// This module implements the TQextScintillaCommandSet class.
//
// Copyright (c) 2006
// 	Riverbank Computing Limited <info@riverbankcomputing.co.uk>
// 
// This file is part of TQScintilla.
// 
// This copy of TQScintilla is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option) any
// later version.
// 
// TQScintilla is supplied in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
// details.
// 
// You should have received a copy of the GNU General Public License along with
// TQScintilla; see the file LICENSE.  If not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <tqsettings.h>

#include "tqextscintillacommandset.h"
#include "tqextscintillacommand.h"
#include "tqextscintilla.h"


// The ctor.
TQextScintillaCommandSet::TQextScintillaCommandSet(TQextScintilla *qs) : tqsci(qs)
{
	struct sci_cmd {
		int msg;
		int key;
		int altkey;
		const char *desc;
	};

	// This is based on the default table in src/KeyMap.cxx.
	static struct sci_cmd cmd_table[] = {
		{
			TQextScintillaBase::SCI_LINEDOWN,
			TQt::Key_Down,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move down one line")
		},
		{
			TQextScintillaBase::SCI_LINEDOWNEXTEND,
			TQt::Key_Down | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection down one line")
		},
		{
			TQextScintillaBase::SCI_LINESCROLLDOWN,
			TQt::Key_Down | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Scroll view down one line")
		},
		{
			TQextScintillaBase::SCI_LINEDOWNRECTEXTEND,
			TQt::Key_Down | TQt::ALT | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend rectangular selection down one line")
		},
		{
			TQextScintillaBase::SCI_LINEUP,
			TQt::Key_Up,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move up one line")
		},
		{
			TQextScintillaBase::SCI_LINEUPEXTEND,
			TQt::Key_Up | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection up one line")
		},
		{
			TQextScintillaBase::SCI_LINESCROLLUP,
			TQt::Key_Up | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Scroll view up one line")
		},
		{
			TQextScintillaBase::SCI_LINEUPRECTEXTEND,
			TQt::Key_Up | TQt::ALT | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend rectangular selection up one line")
		},
		{
			TQextScintillaBase::SCI_PARAUP,
			TQt::Key_BracketLeft | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move up one paragraph")
		},
		{
			TQextScintillaBase::SCI_PARAUPEXTEND,
			TQt::Key_BracketLeft | TQt::CTRL | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection up one paragraph")
		},
		{
			TQextScintillaBase::SCI_PARADOWN,
			TQt::Key_BracketRight | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move down one paragraph")
		},
		{
			TQextScintillaBase::SCI_PARADOWNEXTEND,
			TQt::Key_BracketRight | TQt::CTRL | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection down one paragraph")
		},
		{
			TQextScintillaBase::SCI_CHARLEFT,
			TQt::Key_Left,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move left one character")
		},
		{
			TQextScintillaBase::SCI_CHARLEFTEXTEND,
			TQt::Key_Left | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection left one character")
		},
		{
			TQextScintillaBase::SCI_WORDLEFT,
			TQt::Key_Left | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move left one word")
		},
		{
			TQextScintillaBase::SCI_WORDLEFTEXTEND,
			TQt::Key_Left | TQt::SHIFT | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection left one word")
		},
		{
			TQextScintillaBase::SCI_CHARLEFTRECTEXTEND,
			TQt::Key_Left | TQt::ALT | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend rectangular selection left one character")
		},
		{
			TQextScintillaBase::SCI_CHARRIGHT,
			TQt::Key_Right,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move right one character")
		},
		{
			TQextScintillaBase::SCI_CHARRIGHTEXTEND,
			TQt::Key_Right | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection right one character")
		},
		{
			TQextScintillaBase::SCI_WORDRIGHT,
			TQt::Key_Right | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move right one word")
		},
		{
			TQextScintillaBase::SCI_WORDRIGHTEXTEND,
			TQt::Key_Right | TQt::CTRL | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection right one word")
		},
		{
			TQextScintillaBase::SCI_CHARRIGHTRECTEXTEND,
			TQt::Key_Right | TQt::ALT | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend rectangular selection right one character")
		},
		{
			TQextScintillaBase::SCI_WORDPARTLEFT,
			TQt::Key_Slash | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move left one word part")
		},
		{
			TQextScintillaBase::SCI_WORDPARTLEFTEXTEND,
			TQt::Key_Slash | TQt::CTRL | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection left one word part")
		},
		{
			TQextScintillaBase::SCI_WORDPARTRIGHT,
			TQt::Key_Backslash | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move right one word part")
		},
		{
			TQextScintillaBase::SCI_WORDPARTRIGHTEXTEND,
			TQt::Key_Backslash | TQt::CTRL | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection right one word part")
		},
		{
			TQextScintillaBase::SCI_VCHOME,
			TQt::Key_Home,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move to first visible character in line")
		},
		{
			TQextScintillaBase::SCI_VCHOMEEXTEND,
			TQt::Key_Home | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection to first visible character in line")
		},
		{
			TQextScintillaBase::SCI_DOCUMENTSTART,
			TQt::Key_Home | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move to start of text")
		},
		{
			TQextScintillaBase::SCI_DOCUMENTSTARTEXTEND,
			TQt::Key_Home | TQt::CTRL | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection to start of text")
		},
		{
			TQextScintillaBase::SCI_HOMEDISPLAY,
			TQt::Key_Home | TQt::ALT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move to start of displayed line")
		},
		{
			TQextScintillaBase::SCI_HOMEDISPLAYEXTEND,
			0,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection to start of line")
		},
		{
			TQextScintillaBase::SCI_VCHOMERECTEXTEND,
			TQt::Key_Home | TQt::ALT | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend rectangular selection to first visible character in line")
		},
		{
			TQextScintillaBase::SCI_LINEEND,
			TQt::Key_End,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move to end of line")
		},
		{
			TQextScintillaBase::SCI_LINEENDEXTEND,
			TQt::Key_End | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection to end of line")
		},
		{
			TQextScintillaBase::SCI_DOCUMENTEND,
			TQt::Key_End | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move to end of text")
		},
		{
			TQextScintillaBase::SCI_DOCUMENTENDEXTEND,
			TQt::Key_End | TQt::CTRL | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection to end of text")
		},
		{
			TQextScintillaBase::SCI_LINEENDDISPLAY,
			TQt::Key_End | TQt::ALT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move to end of displayed line")
		},
		{
			TQextScintillaBase::SCI_LINEENDDISPLAYEXTEND,
			0,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection to end of displayed line")
		},
		{
			TQextScintillaBase::SCI_LINEENDRECTEXTEND,
			TQt::Key_End | TQt::ALT | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend rectangular selection to end of line")
		},
		{
			TQextScintillaBase::SCI_PAGEUP,
			TQt::Key_Prior,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move up one page")
		},
		{
			TQextScintillaBase::SCI_PAGEUPEXTEND,
			TQt::Key_Prior | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection up one page")
		},
		{
			TQextScintillaBase::SCI_PAGEUPRECTEXTEND,
			TQt::Key_Prior | TQt::ALT | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend rectangular selection up one page")
		},
		{
			TQextScintillaBase::SCI_PAGEDOWN,
			TQt::Key_Next,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move down one page")
		},
		{
			TQextScintillaBase::SCI_PAGEDOWNEXTEND,
			TQt::Key_Next | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend selection down one page")
		},
		{
			TQextScintillaBase::SCI_PAGEDOWNRECTEXTEND,
			TQt::Key_Next | TQt::ALT | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Extend rectangular selection down one page")
		},
		{
			TQextScintillaBase::SCI_CLEAR,
			TQt::Key_Delete,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Delete current character")
		},
		{
			TQextScintillaBase::SCI_CUT,
			TQt::Key_X | TQt::CTRL,
			TQt::Key_Delete | TQt::SHIFT,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Cut selection")
		},
		{
			TQextScintillaBase::SCI_DELWORDRIGHT,
			TQt::Key_Delete | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Delete word to right")
		},
		{
			TQextScintillaBase::SCI_DELLINERIGHT,
			TQt::Key_Delete | TQt::CTRL | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Delete line to right")
		},
		{
			TQextScintillaBase::SCI_EDITTOGGLEOVERTYPE,
			TQt::Key_Insert,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Toggle insert/overtype")
		},
		{
			TQextScintillaBase::SCI_PASTE,
			TQt::Key_V | TQt::CTRL,
			TQt::Key_Insert | TQt::SHIFT,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Paste")
		},
		{
			TQextScintillaBase::SCI_COPY,
			TQt::Key_C | TQt::CTRL,
			TQt::Key_Insert | TQt::CTRL,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Copy selection")
		},
		{
			TQextScintillaBase::SCI_CANCEL,
			TQt::Key_Escape,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Cancel")
		},
		{
			TQextScintillaBase::SCI_DELETEBACK,
			TQt::Key_Backspace,
			TQt::Key_Backspace | TQt::SHIFT,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Delete previous character")
		},
		{
			TQextScintillaBase::SCI_DELWORDLEFT,
			TQt::Key_Backspace | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Delete word to left")
		},
		{
			TQextScintillaBase::SCI_UNDO,
			TQt::Key_Z | TQt::CTRL,
			TQt::Key_Backspace | TQt::ALT,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Undo the last command")
		},
		{
			TQextScintillaBase::SCI_DELLINELEFT,
			TQt::Key_Backspace | TQt::CTRL | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Delete line to left")
		},
		{
			TQextScintillaBase::SCI_REDO,
			TQt::Key_Y | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Redo last command")
		},
		{
			TQextScintillaBase::SCI_SELECTALL,
			TQt::Key_A | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Select all text")
		},
		{
			TQextScintillaBase::SCI_TAB,
			TQt::Key_Tab,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Indent one level")
		},
		{
			TQextScintillaBase::SCI_BACKTAB,
			TQt::Key_Tab | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Move back one indentation level")
		},
		{
			TQextScintillaBase::SCI_NEWLINE,
			TQt::Key_Return,
			TQt::Key_Return | TQt::SHIFT,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Insert new line")
		},
		{
			TQextScintillaBase::SCI_ZOOMIN,
			TQt::Key_Plus | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Zoom in")
		},
		{
			TQextScintillaBase::SCI_ZOOMOUT,
			TQt::Key_Minus | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Zoom out")
		},
		{
			TQextScintillaBase::SCI_SETZOOM,
			0,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Set zoom")
		},
		{
			TQextScintillaBase::SCI_FORMFEED,
			0,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Formfeed")
		},
		{
			TQextScintillaBase::SCI_LINECUT,
			TQt::Key_L | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Cut current line")
		},
		{
			TQextScintillaBase::SCI_LINEDELETE,
			TQt::Key_L | TQt::CTRL | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Delete current line")
		},
		{
			TQextScintillaBase::SCI_LINECOPY,
			TQt::Key_T | TQt::CTRL | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Copy current line")
		},
		{
			TQextScintillaBase::SCI_LINETRANSPOSE,
			TQt::Key_T | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Swap current and previous lines")
		},
		{
			TQextScintillaBase::SCI_SELECTIONDUPLICATE,
			TQt::Key_D | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Duplicate selection")
		},
		{
			TQextScintillaBase::SCI_LOWERCASE,
			TQt::Key_U | TQt::CTRL,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Convert selection to lower case")
		},
		{
			TQextScintillaBase::SCI_UPPERCASE,
			TQt::Key_U | TQt::CTRL | TQt::SHIFT,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Convert selection to upper case")
		},
		{
			TQextScintillaBase::SCI_DELETEBACKNOTLINE,
			0,
			0,
			TQT_TRANSLATE_NOOP("TQextScintillaCommand",
				"Delete previous character if not at line start")
		},
	};

	cmds.setAutoDelete(true);

	// Clear the default map.
	tqsci -> SendScintilla(TQextScintillaBase::SCI_CLEARALLCMDKEYS);

	for (int i = 0; i < sizeof (cmd_table) / sizeof (cmd_table[0]); ++i)
		cmds.append(new TQextScintillaCommand(tqsci,cmd_table[i].msg,cmd_table[i].key,cmd_table[i].altkey,cmd_table[i].desc));
}


// Read the command set from settings.
bool TQextScintillaCommandSet::readSettings(TQSettings &qs,const char *prefix)
{
	bool rc = true;
	TQString skey;

	for (TQextScintillaCommand *cmd = cmds.first(); cmd; cmd = cmds.next())
	{
		skey.sprintf("%s/keymap/c%d/",prefix,cmd -> msgId());

		int key;
		bool ok;

		// Read the key.
		key = qs.readNumEntry(skey + "key",0,&ok);

		if (ok)
			cmd -> setKey(key);
		else
			rc = false;

		// Read the alternate key.
		key = qs.readNumEntry(skey + "alt",0,&ok);

		if (ok)
			cmd -> setAlternateKey(key);
		else
			rc = false;
	}

	return rc;
}


// Write the command set to settings.
bool TQextScintillaCommandSet::writeSettings(TQSettings &qs,const char *prefix)
{
	bool rc = true;
	TQString skey;

	for (const TQextScintillaCommand *cmd = cmds.first(); cmd; cmd = cmds.next())
	{
		skey.sprintf("%s/keymap/c%d/",prefix,cmd -> msgId());

		// Write the key.
		if (!qs.writeEntry(skey + "key",cmd -> key()))
			rc = false;

		// Write the alternate key.
		if (!qs.writeEntry(skey + "alt",cmd -> alternateKey()))
			rc = false;
	}

	return rc;
}


// Clear the key bindings.
void TQextScintillaCommandSet::clearKeys()
{
	TQPtrList<TQextScintillaCommand> &set = commands();

	for (TQextScintillaCommand *cmd = set.first(); cmd; cmd = set.next())
		cmd -> setKey(0);
}


// Clear the alternate key bindings.
void TQextScintillaCommandSet::clearAlternateKeys()
{
	TQPtrList<TQextScintillaCommand> &set = commands();

	for (TQextScintillaCommand *cmd = set.first(); cmd; cmd = set.next())
		cmd -> setAlternateKey(0);
}