File indexing completed on 2024-03-24 16:41:32
0001 /************************************************************************** 0002 * Copyright (C) 2006 by Michel Ludwig (michel.ludwig@kdemail.net) * 0003 ***************************************************************************/ 0004 0005 /************************************************************************** 0006 * * 0007 * This program is free software; you can redistribute it and/or modify * 0008 * it under the terms of the GNU General Public License as published by * 0009 * the Free Software Foundation; either version 2 of the License, or * 0010 * (at your option) any later version. * 0011 * * 0012 ***************************************************************************/ 0013 0014 #include "editorkeysequencemanager.h" 0015 0016 #include "kileinfo.h" 0017 #include "scriptmanager.h" 0018 #include "scripting/script.h" 0019 0020 #include <QEvent> 0021 #include <QKeyEvent> 0022 0023 #include <KTextEditor/Document> 0024 #include <KLocalizedString> 0025 0026 namespace KileEditorKeySequence { 0027 0028 Manager::Manager(KileInfo* kileInfo, QObject *parent, const char *name) : QObject(parent), m_kileInfo(kileInfo) 0029 { 0030 setObjectName(name); 0031 } 0032 0033 Manager::~Manager() 0034 { 0035 } 0036 0037 void Manager::addAction(const QString& seq, Action *action) 0038 { 0039 if(seq.isEmpty()) { 0040 return; 0041 } 0042 if(m_actionMap.find(seq) == m_actionMap.end()) { 0043 m_actionMap[seq] = action; 0044 m_watchedKeySequencesList.push_back(seq); 0045 emit watchedKeySequencesChanged(); 0046 } 0047 } 0048 0049 void Manager::removeKeySequence(const QString& seq) 0050 { 0051 if(seq.isEmpty()) { 0052 return; 0053 } 0054 QMap<QString, Action*>::iterator it = m_actionMap.find(seq); 0055 if(it != m_actionMap.end()) { 0056 delete (it.value()); 0057 m_actionMap.erase(it); 0058 m_watchedKeySequencesList.removeAll(seq); 0059 emit watchedKeySequencesChanged(); 0060 } 0061 } 0062 0063 void Manager::removeKeySequence(const QStringList& l) 0064 { 0065 bool changed = false; 0066 for(QStringList::const_iterator i = l.begin(); i != l.end(); ++i) { 0067 if((*i).isEmpty()) { 0068 continue; 0069 } 0070 QMap<QString, Action*>::iterator it = m_actionMap.find(*i); 0071 if(it != m_actionMap.end()) { 0072 delete (it.value()); 0073 m_actionMap.erase(it); 0074 m_watchedKeySequencesList.removeAll(*i); 0075 changed = true; 0076 } 0077 } 0078 if(changed) { 0079 emit watchedKeySequencesChanged(); 0080 } 0081 } 0082 0083 void Manager::addActionMap(const QMap<QString, Action*>& map) 0084 { 0085 bool changed = false; 0086 for(QMap<QString, Action*>::const_iterator i = map.begin(); i != map.end(); ++i) { 0087 if(i.key().isEmpty()) { 0088 continue; 0089 } 0090 if(m_actionMap[i.key()] != i.value()) { 0091 m_actionMap[i.key()] = i.value(); 0092 changed = true; 0093 } 0094 } 0095 if(changed) { 0096 emit watchedKeySequencesChanged(); 0097 } 0098 } 0099 0100 QString Manager::getKeySequence(const Action* a) 0101 { 0102 for(QMap<QString, Action*>::const_iterator i = m_actionMap.constBegin(); i != m_actionMap.constEnd(); ++i) { 0103 if(i.value() == a) { 0104 return i.key(); 0105 } 0106 } 0107 return QString(); 0108 } 0109 0110 Action* Manager::getAction(const QString& seq) 0111 { 0112 QMap<QString, Action*>::iterator i = m_actionMap.find(seq); 0113 return (i == m_actionMap.end()) ? Q_NULLPTR : (*i); 0114 } 0115 0116 void Manager::setEditorKeySequence(const QString& /* seq */, Action* /* action */) 0117 { 0118 } 0119 0120 void Manager::keySequenceTyped(const QString& seq) 0121 { 0122 m_actionMap[seq]->execute(); 0123 } 0124 0125 void Manager::clear() 0126 { 0127 m_watchedKeySequencesList.clear(); 0128 m_actionMap.clear(); 0129 emit watchedKeySequencesChanged(); 0130 } 0131 0132 0133 const QStringList& Manager::getWatchedKeySequences() 0134 { 0135 return m_watchedKeySequencesList; 0136 } 0137 0138 bool Manager::isSequenceAssigned(const QString& seq) const { 0139 for(QList<QString>::const_iterator i = m_watchedKeySequencesList.begin(); i != m_watchedKeySequencesList.end(); ++i) { 0140 if((*i).startsWith(seq)) { 0141 return true; 0142 } 0143 } 0144 return false; 0145 } 0146 0147 QPair<int, QString> Manager::checkSequence(const QString& seq, const QString& skip) 0148 { 0149 for(QList<QString>::iterator i = m_watchedKeySequencesList.begin(); i != m_watchedKeySequencesList.end(); ++i) { 0150 if((*i) == skip) { 0151 continue; 0152 } 0153 if((*i).startsWith(seq)) { 0154 return (*i == seq) ? qMakePair<int, QString>(1, seq) : qMakePair<int, QString>(2, *i); 0155 } 0156 if(!(*i).isEmpty() && seq.startsWith(*i)) { 0157 return qMakePair<int, QString>(3, *i); 0158 } 0159 } 0160 return qMakePair<int, QString>(0, QString()); 0161 } 0162 0163 Recorder::Recorder(KTextEditor::View *view, Manager *manager) : QObject(view), m_manager(manager), m_view(view) 0164 { 0165 connect(m_manager, SIGNAL(watchedKeySequencesChanged()), this, SLOT(reloadWatchedKeySequences())); 0166 connect(this, SIGNAL(detectedTypedKeySequence(QString)), m_manager, SLOT(keySequenceTyped(QString))); 0167 KTextEditor::Cursor cursor = m_view->cursorPosition(); 0168 m_oldLine = cursor.line(); 0169 m_oldCol = cursor.column(); 0170 0171 reloadWatchedKeySequences(); 0172 } 0173 0174 Recorder::~Recorder() 0175 { 0176 } 0177 0178 bool Recorder::eventFilter(QObject* /* o */, QEvent *e) 0179 { 0180 if (e->type() == QEvent::KeyPress) { 0181 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(e); 0182 int curLine, curCol; 0183 KTextEditor::Cursor cursor = m_view->cursorPosition(); 0184 curLine = cursor.line(); 0185 curCol = cursor.column(); 0186 if(curLine != m_oldLine || m_oldCol+1 != curCol) { 0187 m_typedSequence.clear(); 0188 m_oldLine = curLine; 0189 m_oldCol = curCol; 0190 } 0191 else { 0192 ++m_oldCol; 0193 } 0194 m_typedSequence += keyEvent->text(); 0195 if(m_typedSequence.length() == m_maxSequenceLength + 1) { 0196 m_typedSequence = m_typedSequence.mid(1, m_typedSequence.length() - 1); 0197 } 0198 return seekForKeySequence(m_typedSequence); 0199 } 0200 return false; 0201 } 0202 0203 bool Recorder::seekForKeySequence(const QString& s) 0204 { 0205 for(int i = 0; i < s.length(); ++i) { 0206 QString toCheck = s.right(s.length() - i); 0207 if(m_watchedKeySequencesList.contains(toCheck)) { 0208 m_view->document()->removeText(KTextEditor::Range(m_oldLine, m_oldCol - (s.length() - i - 1), m_oldLine, m_oldCol)); 0209 m_typedSequence.clear(); // clean m_typedSequence to avoid wrong action triggering if one presses keys without printable character 0210 emit detectedTypedKeySequence(toCheck); 0211 return true; 0212 } 0213 } 0214 return false; 0215 } 0216 0217 void Recorder::reloadWatchedKeySequences() 0218 { 0219 m_watchedKeySequencesList = m_manager->getWatchedKeySequences(); 0220 m_maxSequenceLength = 0; 0221 for(QStringList::iterator i = m_watchedKeySequencesList.begin(); i != m_watchedKeySequencesList.end(); ++i) { 0222 m_maxSequenceLength = qMax(m_maxSequenceLength, (*i).length()); 0223 } 0224 if(m_maxSequenceLength < m_typedSequence.length()) { 0225 m_typedSequence = m_typedSequence.right(m_maxSequenceLength); 0226 } 0227 } 0228 0229 Action::Action() { 0230 } 0231 0232 Action::~Action() { 0233 } 0234 0235 QString Action::getDescription() const { 0236 return QString(); 0237 } 0238 0239 ExecuteScriptAction::ExecuteScriptAction(KileScript::Script *script, KileScript::Manager *scriptManager) : m_script(script), m_scriptManager(scriptManager) 0240 { 0241 } 0242 0243 ExecuteScriptAction::~ExecuteScriptAction() 0244 { 0245 } 0246 0247 void ExecuteScriptAction::execute() 0248 { 0249 m_scriptManager->executeScript(m_script); 0250 } 0251 0252 QString ExecuteScriptAction::getDescription() const 0253 { 0254 return i18n("Script execution of %1", m_script->getFileName()); 0255 } 0256 0257 0258 } 0259