• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

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 }

Kate

Skip menu "Kate"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal