Kate
kateviinputmodemanager.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries and the Kate part. 00002 * 00003 * Copyright (C) 2008 - 2009 Erlend Hamberg <ehamberg@gmail.com> 00004 * Copyright (C) 2009 Paul Gideon Dann <pdgiddie@gmail.com> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Library General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Library General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Library General Public License 00017 * along with this library; see the file COPYING.LIB. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include "kateviinputmodemanager.h" 00023 00024 #include <QKeyEvent> 00025 #include <QString> 00026 #include <QCoreApplication> 00027 00028 #include <kconfig.h> 00029 #include <kconfiggroup.h> 00030 00031 #include "kateconfig.h" 00032 #include "kateglobal.h" 00033 #include "kateviglobal.h" 00034 #include "katevinormalmode.h" 00035 #include "kateviinsertmode.h" 00036 #include "katevivisualmode.h" 00037 #include "katevireplacemode.h" 00038 #include "katevikeyparser.h" 00039 00040 KateViInputModeManager::KateViInputModeManager(KateView* view, KateViewInternal* viewInternal) 00041 { 00042 m_viNormalMode = new KateViNormalMode(this, view, viewInternal); 00043 m_viInsertMode = new KateViInsertMode(this, view, viewInternal); 00044 m_viVisualMode = new KateViVisualMode(this, view, viewInternal); 00045 m_viReplaceMode = new KateViReplaceMode(this, view, viewInternal); 00046 00047 m_currentViMode = NormalMode; 00048 00049 m_view = view; 00050 m_viewInternal = viewInternal; 00051 00052 m_runningMacro = false; 00053 00054 m_lastSearchBackwards = false; 00055 } 00056 00057 KateViInputModeManager::~KateViInputModeManager() 00058 { 00059 delete m_viNormalMode; 00060 delete m_viInsertMode; 00061 delete m_viVisualMode; 00062 delete m_viReplaceMode; 00063 } 00064 00065 bool KateViInputModeManager::handleKeypress(const QKeyEvent *e) 00066 { 00067 bool res; 00068 00069 // record key press so that it can be repeated 00070 if (!isRunningMacro()) { 00071 QKeyEvent copy( e->type(), e->key(), e->modifiers(), e->text() ); 00072 appendKeyEventToLog( copy ); 00073 } 00074 00075 // FIXME: I think we're making things difficult for ourselves here. Maybe some 00076 // more thought needs to go into the inheritance hierarchy. 00077 switch(m_currentViMode) { 00078 case NormalMode: 00079 res = m_viNormalMode->handleKeypress(e); 00080 break; 00081 case InsertMode: 00082 res = m_viInsertMode->handleKeypress(e); 00083 break; 00084 case VisualMode: 00085 case VisualLineMode: 00086 case VisualBlockMode: 00087 res = m_viVisualMode->handleKeypress(e); 00088 break; 00089 case ReplaceMode: 00090 res = m_viReplaceMode->handleKeypress(e); 00091 break; 00092 default: 00093 kDebug( 13070 ) << "WARNING: Unhandled keypress"; 00094 res = false; 00095 } 00096 00097 return res; 00098 } 00099 00100 void KateViInputModeManager::feedKeyPresses(const QString &keyPresses) const 00101 { 00102 int key; 00103 Qt::KeyboardModifiers mods; 00104 QString text; 00105 00106 kDebug( 13070 ) << "Repeating change"; 00107 foreach(const QChar &c, keyPresses) { 00108 QString decoded = KateViKeyParser::getInstance()->decodeKeySequence(QString(c)); 00109 key = -1; 00110 mods = Qt::NoModifier; 00111 text.clear(); 00112 00113 kDebug( 13070 ) << "\t" << decoded; 00114 00115 if (decoded.length() > 1 ) { // special key 00116 00117 // remove the angle brackets 00118 decoded.remove(0, 1); 00119 decoded.remove(decoded.indexOf(">"), 1); 00120 kDebug( 13070 ) << "\t Special key:" << decoded; 00121 00122 // check if one or more modifier keys where used 00123 if (decoded.indexOf("s-") != -1 || decoded.indexOf("c-") != -1 00124 || decoded.indexOf("m-") != -1 || decoded.indexOf("m-") != -1) { 00125 00126 int s = decoded.indexOf("s-"); 00127 if (s != -1) { 00128 mods |= Qt::ShiftModifier; 00129 decoded.remove(s, 2); 00130 } 00131 00132 int c = decoded.indexOf("c-"); 00133 if (c != -1) { 00134 mods |= Qt::ControlModifier; 00135 decoded.remove(c, 2); 00136 } 00137 00138 int a = decoded.indexOf("a-"); 00139 if (a != -1) { 00140 mods |= Qt::AltModifier; 00141 decoded.remove(a, 2); 00142 } 00143 00144 int m = decoded.indexOf("m-"); 00145 if (m != -1) { 00146 mods |= Qt::MetaModifier; 00147 decoded.remove(m, 2); 00148 } 00149 00150 if (decoded.length() > 1 ) { 00151 key = KateViKeyParser::getInstance()->vi2qt(decoded); 00152 } else if (decoded.length() == 1) { 00153 key = int(decoded.at(0).toUpper().toAscii()); 00154 text = decoded.at(0); 00155 kDebug( 13070 ) << "###########" << key; 00156 } else { 00157 kWarning( 13070 ) << "decoded is empty. skipping key press."; 00158 } 00159 } else { // no modifiers 00160 key = KateViKeyParser::getInstance()->vi2qt(decoded); 00161 } 00162 } else { 00163 key = decoded.at(0).unicode(); 00164 text = decoded.at(0); 00165 } 00166 00167 QKeyEvent k(QEvent::KeyPress, key, mods, text); 00168 00169 QCoreApplication::sendEvent(m_viewInternal, &k); 00170 } 00171 } 00172 00173 void KateViInputModeManager::appendKeyEventToLog(const QKeyEvent &e) 00174 { 00175 if ( e.key() != Qt::Key_Shift && e.key() != Qt::Key_Control 00176 && e.key() != Qt::Key_Meta && e.key() != Qt::Key_Alt ) { 00177 m_keyEventsLog.append(e); 00178 } 00179 } 00180 00181 void KateViInputModeManager::storeChangeCommand() 00182 { 00183 m_lastChange.clear(); 00184 00185 for (int i = 0; i < m_keyEventsLog.size(); i++) { 00186 int keyCode = m_keyEventsLog.at(i).key(); 00187 QString text = m_keyEventsLog.at(i).text(); 00188 int mods = m_keyEventsLog.at(i).modifiers(); 00189 QChar key; 00190 00191 if ( text.length() > 0 ) { 00192 key = text.at(0); 00193 } 00194 00195 if ( text.isEmpty() || ( text.length() ==1 && text.at(0) < 0x20 ) 00196 || ( mods != Qt::NoModifier && mods != Qt::ShiftModifier ) ) { 00197 QString keyPress; 00198 00199 keyPress.append( '<' ); 00200 keyPress.append( ( mods & Qt::ShiftModifier ) ? "s-" : "" ); 00201 keyPress.append( ( mods & Qt::ControlModifier ) ? "c-" : "" ); 00202 keyPress.append( ( mods & Qt::AltModifier ) ? "a-" : "" ); 00203 keyPress.append( ( mods & Qt::MetaModifier ) ? "m-" : "" ); 00204 keyPress.append( keyCode <= 0xFF ? QChar( keyCode ) : KateViKeyParser::getInstance()->qt2vi( keyCode ) ); 00205 keyPress.append( '>' ); 00206 00207 key = KateViKeyParser::getInstance()->encodeKeySequence( keyPress ).at( 0 ); 00208 } 00209 00210 m_lastChange.append(key); 00211 } 00212 } 00213 00214 void KateViInputModeManager::repeatLastChange() 00215 { 00216 m_runningMacro = true; 00217 feedKeyPresses(m_lastChange); 00218 m_runningMacro = false; 00219 } 00220 00221 void KateViInputModeManager::changeViMode(ViMode newMode) 00222 { 00223 m_currentViMode = newMode; 00224 } 00225 00226 ViMode KateViInputModeManager::getCurrentViMode() const 00227 { 00228 return m_currentViMode; 00229 } 00230 00231 void KateViInputModeManager::viEnterNormalMode() 00232 { 00233 bool moveCursorLeft = (m_currentViMode == InsertMode || m_currentViMode == ReplaceMode) 00234 && m_viewInternal->getCursor().column() > 0; 00235 00236 changeViMode(NormalMode); 00237 00238 if ( moveCursorLeft ) { 00239 m_viewInternal->cursorLeft(); 00240 } 00241 m_viewInternal->repaint (); 00242 } 00243 00244 void KateViInputModeManager::viEnterInsertMode() 00245 { 00246 changeViMode(InsertMode); 00247 m_viewInternal->repaint (); 00248 } 00249 00250 void KateViInputModeManager::viEnterVisualMode( ViMode mode ) 00251 { 00252 changeViMode( mode ); 00253 00254 m_viewInternal->repaint (); 00255 getViVisualMode()->setVisualModeType( mode ); 00256 getViVisualMode()->init(); 00257 } 00258 00259 void KateViInputModeManager::viEnterReplaceMode() 00260 { 00261 changeViMode(ReplaceMode); 00262 m_viewInternal->repaint (); 00263 } 00264 00265 00266 KateViNormalMode* KateViInputModeManager::getViNormalMode() 00267 { 00268 return m_viNormalMode; 00269 } 00270 00271 KateViInsertMode* KateViInputModeManager::getViInsertMode() 00272 { 00273 return m_viInsertMode; 00274 } 00275 00276 KateViVisualMode* KateViInputModeManager::getViVisualMode() 00277 { 00278 return m_viVisualMode; 00279 } 00280 00281 KateViReplaceMode* KateViInputModeManager::getViReplaceMode() 00282 { 00283 return m_viReplaceMode; 00284 } 00285 00286 const QString KateViInputModeManager::getVerbatimKeys() const 00287 { 00288 QString cmd; 00289 00290 switch (getCurrentViMode()) { 00291 case NormalMode: 00292 cmd = m_viNormalMode->getVerbatimKeys(); 00293 break; 00294 case InsertMode: 00295 case ReplaceMode: 00296 // ... 00297 break; 00298 case VisualMode: 00299 case VisualLineMode: 00300 case VisualBlockMode: 00301 cmd = m_viVisualMode->getVerbatimKeys(); 00302 break; 00303 } 00304 00305 return cmd; 00306 } 00307 00308 void KateViInputModeManager::readSessionConfig( const KConfigGroup& config ) 00309 { 00310 QStringList names = config.readEntry( "ViRegisterNames", QStringList() ); 00311 QStringList contents = config.readEntry( "ViRegisterContents", QStringList() ); 00312 00313 // sanity check 00314 if ( names.size() == contents.size() ) { 00315 for ( int i = 0; i < names.size(); i++ ) { 00316 KateGlobal::self()->viInputModeGlobal()->fillRegister( names.at( i ).at( 0 ), contents.at( i ) ); 00317 } 00318 } 00319 } 00320 00321 void KateViInputModeManager::writeSessionConfig( KConfigGroup& config ) 00322 { 00323 const QMap<QChar, QString>* regs = KateGlobal::self()->viInputModeGlobal()->getRegisters(); 00324 QStringList names, contents; 00325 QMap<QChar, QString>::const_iterator i; 00326 for (i = regs->constBegin(); i != regs->constEnd(); ++i) { 00327 if ( i.value().length() <= 1000 ) { 00328 names << i.key(); 00329 contents << i.value(); 00330 } else { 00331 kDebug( 13070 ) << "Did not save contents of register " << i.key() << ": contents too long (" 00332 << i.value().length() << " characters)"; 00333 } 00334 } 00335 00336 config.writeEntry( "ViRegisterNames", names ); 00337 config.writeEntry( "ViRegisterContents", contents ); 00338 }
KDE 4.6 API Reference