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