Kate
kateviinputmodemanager.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kateviinputmodemanager.h"
00021
00022 #include <QKeyEvent>
00023 #include <QString>
00024 #include <QCoreApplication>
00025
00026 #include "katevinormalmode.h"
00027 #include "kateviinsertmode.h"
00028 #include "katevivisualmode.h"
00029 #include "katevikeysequenceparser.h"
00030
00031 KateViInputModeManager::KateViInputModeManager(KateView* view, KateViewInternal* viewInternal)
00032 {
00033 m_viNormalMode = new KateViNormalMode(this, view, viewInternal);
00034 m_viInsertMode = new KateViInsertMode(this, view, viewInternal);
00035 m_viVisualMode = new KateViVisualMode(this, view, viewInternal);
00036
00037 m_currentViMode = NormalMode;
00038
00039 m_view = view;
00040 m_viewInternal = viewInternal;
00041 m_keyParser = new KateViKeySequenceParser();
00042
00043 m_runningMacro = false;
00044 }
00045
00046 KateViInputModeManager::~KateViInputModeManager()
00047 {
00048 delete m_viNormalMode;
00049 delete m_viInsertMode;
00050 delete m_viVisualMode;
00051 }
00052
00053 bool KateViInputModeManager::handleKeypress(const QKeyEvent *e)
00054 {
00055 bool res;
00056
00057
00058 if (!isRunningMacro()) {
00059 QKeyEvent copy( e->type(), e->key(), e->modifiers(), e->text() );
00060 appendKeyEventToLog( copy );
00061 }
00062
00063 switch(m_currentViMode) {
00064 case NormalMode:
00065 res = m_viNormalMode->handleKeypress(e);
00066 break;
00067 case InsertMode:
00068 res = m_viInsertMode->handleKeypress(e);
00069 break;
00070 case VisualMode:
00071 case VisualLineMode:
00072 res = m_viVisualMode->handleKeypress(e);
00073 break;
00074 default:
00075 res = false;
00076 }
00077
00078 return res;
00079 }
00080
00081 void KateViInputModeManager::feedKeyPresses(const QString &keyPresses) const
00082 {
00083 QChar c;
00084 int key;
00085 Qt::KeyboardModifiers mods;
00086 QString text;
00087
00088 kDebug( 13070 ) << "Repeating change";
00089 foreach(c, keyPresses) {
00090 QString decoded = m_keyParser->decodeKeySequence(QString(c));
00091 key = -1;
00092 mods = Qt::NoModifier;
00093 text = QString();
00094
00095 kDebug( 13070 ) << "\t" << decoded;
00096
00097 if (decoded.length() > 1 ) {
00098
00099
00100 decoded.remove(0, 1);
00101 decoded.remove(decoded.indexOf(">"), 1);
00102 kDebug( 13070 ) << "\t Special key:" << decoded;
00103
00104
00105 if (decoded.indexOf("s-") != -1 || decoded.indexOf("c-") != -1
00106 || decoded.indexOf("m-") != -1 || decoded.indexOf("m-") != -1) {
00107
00108 int s = decoded.indexOf("s-");
00109 if (s != -1) {
00110 mods |= Qt::ShiftModifier;
00111 decoded.remove(s, 2);
00112 }
00113
00114 int c = decoded.indexOf("c-");
00115 if (c != -1) {
00116 mods |= Qt::ControlModifier;
00117 decoded.remove(c, 2);
00118 }
00119
00120 int a = decoded.indexOf("a-");
00121 if (a != -1) {
00122 mods |= Qt::AltModifier;
00123 decoded.remove(a, 2);
00124 }
00125
00126 int m = decoded.indexOf("m-");
00127 if (m != -1) {
00128 mods |= Qt::MetaModifier;
00129 decoded.remove(m, 2);
00130 }
00131
00132 if (decoded.length() > 1 ) {
00133 key = m_keyParser->vi2qt(decoded);
00134 } else {
00135 key = int(decoded.at(0).toUpper().toAscii());
00136 text = decoded.at(0);
00137 kDebug( 13070 ) << "###########" << key;
00138 kDebug( 13070 ) << "###########" << Qt::Key_W;
00139 }
00140 } else {
00141 key = m_keyParser->vi2qt(decoded);
00142 }
00143 } else {
00144 key = decoded.at(0).unicode();
00145 text = decoded.at(0);
00146 }
00147
00148 QKeyEvent k(QEvent::KeyPress, key, mods, text);
00149
00150 QCoreApplication::sendEvent(m_viewInternal, &k);
00151 }
00152 }
00153
00154 void KateViInputModeManager::appendKeyEventToLog(const QKeyEvent &e)
00155 {
00156 if ( e.key() != Qt::Key_Shift && e.key() != Qt::Key_Control
00157 && e.key() != Qt::Key_Meta && e.key() != Qt::Key_Alt ) {
00158 m_keyEventsLog.append(e);
00159 }
00160 }
00161
00162 void KateViInputModeManager::storeChangeCommand()
00163 {
00164 m_lastChange.clear();
00165
00166 for (int i = 0; i < m_keyEventsLog.size(); i++) {
00167 int keyCode = m_keyEventsLog.at(i).key();
00168 QString text = m_keyEventsLog.at(i).text();
00169 int mods = m_keyEventsLog.at(i).modifiers();
00170 QChar key;
00171
00172 if ( text.length() > 0 ) {
00173 key = text.at(0);
00174 }
00175
00176 if ( text.isEmpty() || ( text.length() ==1 && text.at(0) < 0x20 )
00177 || ( mods != Qt::NoModifier && mods != Qt::ShiftModifier ) ) {
00178 QString keyPress;
00179
00180 keyPress.append( '<' );
00181 keyPress.append( ( mods & Qt::ShiftModifier ) ? "s-" : "" );
00182 keyPress.append( ( mods & Qt::ControlModifier ) ? "c-" : "" );
00183 keyPress.append( ( mods & Qt::AltModifier ) ? "a-" : "" );
00184 keyPress.append( ( mods & Qt::MetaModifier ) ? "m-" : "" );
00185 keyPress.append( keyCode <= 0xFF ? QChar( keyCode ) : m_keyParser->qt2vi( keyCode ) );
00186 keyPress.append( '>' );
00187
00188 key = m_keyParser->encodeKeySequence( keyPress ).at( 0 );
00189 }
00190
00191 m_lastChange.append(key);
00192 }
00193 }
00194
00195 void KateViInputModeManager::repeatLastChange()
00196 {
00197 m_runningMacro = true;
00198 feedKeyPresses(m_lastChange);
00199 m_runningMacro = false;
00200 }
00201
00202 void KateViInputModeManager::changeViMode(ViMode newMode)
00203 {
00204 m_currentViMode = newMode;
00205 }
00206
00207 ViMode KateViInputModeManager::getCurrentViMode() const
00208 {
00209 return m_currentViMode;
00210 }
00211
00212 void KateViInputModeManager::viEnterNormalMode()
00213 {
00214 bool moveCursorLeft = m_currentViMode == InsertMode && m_viewInternal->getCursor().column() > 0;
00215
00216 changeViMode(NormalMode);
00217
00218 if ( moveCursorLeft ) {
00219 m_viewInternal->cursorLeft();
00220 }
00221 m_viewInternal->repaint ();
00222 }
00223
00224 void KateViInputModeManager::viEnterInsertMode()
00225 {
00226 changeViMode(InsertMode);
00227 m_viewInternal->repaint ();
00228 }
00229
00230 void KateViInputModeManager::viEnterVisualMode( bool visualLine )
00231 {
00232 if ( !visualLine ) {
00233 changeViMode(VisualMode);
00234 } else {
00235 changeViMode(VisualLineMode);
00236 }
00237
00238 m_viewInternal->repaint ();
00239 getViVisualMode()->setVisualLine( visualLine );
00240 getViVisualMode()->init();
00241 }
00242
00243 KateViNormalMode* KateViInputModeManager::getViNormalMode()
00244 {
00245 return m_viNormalMode;
00246 }
00247
00248 KateViInsertMode* KateViInputModeManager::getViInsertMode()
00249 {
00250 return m_viInsertMode;
00251 }
00252
00253 KateViVisualMode* KateViInputModeManager::getViVisualMode()
00254 {
00255 return m_viVisualMode;
00256 }
00257
00258 const QString KateViInputModeManager::getVerbatimKeys() const
00259 {
00260 QString cmd;
00261
00262 switch (getCurrentViMode()) {
00263 case NormalMode:
00264 cmd = m_viNormalMode->getVerbatimKeys();
00265 break;
00266 case InsertMode:
00267
00268 break;
00269 case VisualMode:
00270 case VisualLineMode:
00271 cmd = m_viVisualMode->getVerbatimKeys();
00272 break;
00273 }
00274
00275 return cmd;
00276 }