276 lines
7.2 KiB
C++
276 lines
7.2 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
|
|
**
|
|
** This file is part of the Edyuk project <http://edyuk.org>
|
|
**
|
|
** This file may be used under the terms of the GNU General Public License
|
|
** version 3 as published by the Free Software Foundation and appearing in the
|
|
** file GPL.txt included in the packaging of this file.
|
|
**
|
|
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
**
|
|
****************************************************************************/
|
|
|
|
#include "qeditorinputbinding.h"
|
|
|
|
#include "qdocument.h"
|
|
#include "qdocumentcursor.h"
|
|
#include "qeditor.h"
|
|
|
|
#include <QKeyEvent>
|
|
|
|
/*!
|
|
\class QEditorInputBindingInterface
|
|
\brief A class designed to allow extending user input in a transparent
|
|
way
|
|
|
|
An input binding interface, when set to an editor, can intercept all the
|
|
events the editor receive and radically change the behavior.
|
|
|
|
The main purpose of this class is twofold :
|
|
<ul>
|
|
<li>Allow vi-like (or emacs-like, ...) editing to be implemented with
|
|
little extra work. And allow the user to easily switch between input
|
|
modes</li> <li>Allow applications using QCE to easily add extra features (e.g
|
|
extended code navigation within projects, jump to documentation, ...) with
|
|
little extra work</li>
|
|
</ul>
|
|
*/
|
|
|
|
/*!
|
|
\class QEditorInputBinding
|
|
\brief A "managed" input binding interface
|
|
|
|
This subclass of QEditorInputBindingInterface is meant to make the
|
|
creatio of input bindings easier and more intuitive by abstracting away most
|
|
of the low-level event handling logic.
|
|
*/
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
QEditorInputBinding::MotionCommand::MotionCommand(
|
|
QDocumentCursor::MoveOperation op, QDocumentCursor::MoveMode m, int n)
|
|
: count(n), mode(m), operation(op) {}
|
|
|
|
void QEditorInputBinding::MotionCommand::exec(QEditor *e) {
|
|
QDocumentCursor c = e->cursor();
|
|
c.movePosition(count, operation, mode);
|
|
e->setCursor(c);
|
|
}
|
|
|
|
QEditorInputBinding::EditCommand::EditCommand(Operation op) : operation(op) {}
|
|
|
|
void QEditorInputBinding::EditCommand::exec(QEditor *e) {
|
|
QDocumentCursor c = e->cursor();
|
|
|
|
switch (operation) {
|
|
case ClearSelection:
|
|
c.clearSelection();
|
|
break;
|
|
|
|
case SelectWord:
|
|
c.select(QDocumentCursor::WordUnderCursor);
|
|
break;
|
|
|
|
case SelectLine:
|
|
c.select(QDocumentCursor::LineUnderCursor);
|
|
break;
|
|
|
|
case SelectDocument:
|
|
c.movePosition(1, QDocumentCursor::Start, QDocumentCursor::MoveAnchor);
|
|
c.movePosition(1, QDocumentCursor::End, QDocumentCursor::KeepAnchor);
|
|
break;
|
|
|
|
case DeleteChar:
|
|
c.deleteChar();
|
|
break;
|
|
|
|
case DeletePreviousChar:
|
|
c.deletePreviousChar();
|
|
break;
|
|
|
|
case DeleteLine:
|
|
c.eraseLine();
|
|
break;
|
|
|
|
case DeleteSelection:
|
|
c.removeSelectedText();
|
|
break;
|
|
|
|
case InsertLine:
|
|
c.insertLine();
|
|
break;
|
|
|
|
case InsertClipBoard:
|
|
e->paste();
|
|
return;
|
|
|
|
default:
|
|
|
|
break;
|
|
}
|
|
|
|
e->setCursor(c);
|
|
}
|
|
|
|
QEditorInputBinding::WriteCommand::WriteCommand(const QString &t) : text(t) {}
|
|
|
|
void QEditorInputBinding::WriteCommand::exec(QEditor *e) { e->write(text); }
|
|
|
|
void QEditorInputBinding::GroupCommand::addCommand(Command *c) {
|
|
commands << c;
|
|
}
|
|
|
|
void QEditorInputBinding::GroupCommand::exec(QEditor *e) {
|
|
foreach (Command *c, commands)
|
|
c->exec(e);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
QEditorInputBinding::QEditorInputBinding() {}
|
|
|
|
QEditorInputBinding::~QEditorInputBinding() { qDeleteAll(m_actions); }
|
|
|
|
void QEditorInputBinding::setMapping(const QKeySequence &ks, Command *cmd) {
|
|
for (int i = 0; i < m_keys.count(); ++i) {
|
|
if (m_keys.at(i) == ks) {
|
|
delete m_actions[i];
|
|
m_actions[i] = cmd;
|
|
return;
|
|
}
|
|
}
|
|
|
|
m_index << 0;
|
|
m_keys << ks;
|
|
m_actions << cmd;
|
|
}
|
|
|
|
bool QEditorInputBinding::isExclusive() const { return false; }
|
|
|
|
bool QEditorInputBinding::keyPressEvent(QKeyEvent *event, QEditor *editor) {
|
|
bool filter = false;
|
|
|
|
for (int i = 0; i < m_keys.count(); ++i) {
|
|
int idx = m_index.at(i);
|
|
const QKeySequence &ks = m_keys.at(i);
|
|
|
|
if (idx < ks.count()) {
|
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
if (ks[idx].key() == event->key()) {
|
|
#else
|
|
if (ks[idx] == event->key()) {
|
|
#endif
|
|
++idx;
|
|
|
|
if (idx == ks.count()) {
|
|
// qDebug("match");
|
|
|
|
// key sequence matched
|
|
m_actions.at(i)->exec(editor);
|
|
|
|
// cancel other in progress matches ?
|
|
m_index.fill(0);
|
|
|
|
// return true;
|
|
} else {
|
|
// qDebug("step");
|
|
m_index[i] = idx;
|
|
}
|
|
|
|
// filter out the event
|
|
filter = true;
|
|
} else {
|
|
m_index[i] = 0;
|
|
}
|
|
} else {
|
|
m_index[i] = 0;
|
|
}
|
|
}
|
|
|
|
return filter;
|
|
}
|
|
|
|
void QEditorInputBinding::postKeyPressEvent(QKeyEvent *event, QEditor *editor) {
|
|
Q_UNUSED(event)
|
|
Q_UNUSED(editor)
|
|
}
|
|
|
|
bool QEditorInputBinding::inputMethodEvent(QInputMethodEvent *event,
|
|
QEditor *editor) {
|
|
Q_UNUSED(event)
|
|
Q_UNUSED(editor)
|
|
|
|
return false;
|
|
}
|
|
|
|
void QEditorInputBinding::postInputMethodEvent(QInputMethodEvent *event,
|
|
QEditor *editor) {
|
|
Q_UNUSED(event)
|
|
Q_UNUSED(editor)
|
|
}
|
|
|
|
bool QEditorInputBinding::mouseMoveEvent(QMouseEvent *event, QEditor *editor) {
|
|
Q_UNUSED(event)
|
|
Q_UNUSED(editor)
|
|
|
|
return false;
|
|
}
|
|
|
|
void QEditorInputBinding::postMouseMoveEvent(QMouseEvent *event,
|
|
QEditor *editor) {
|
|
Q_UNUSED(event)
|
|
Q_UNUSED(editor)
|
|
}
|
|
|
|
bool QEditorInputBinding::mousePressEvent(QMouseEvent *event, QEditor *editor) {
|
|
Q_UNUSED(event)
|
|
Q_UNUSED(editor)
|
|
|
|
return false;
|
|
}
|
|
|
|
void QEditorInputBinding::postMousePressEvent(QMouseEvent *event,
|
|
QEditor *editor) {
|
|
Q_UNUSED(event)
|
|
Q_UNUSED(editor)
|
|
}
|
|
|
|
bool QEditorInputBinding::mouseReleaseEvent(QMouseEvent *event,
|
|
QEditor *editor) {
|
|
Q_UNUSED(event)
|
|
Q_UNUSED(editor)
|
|
|
|
return false;
|
|
}
|
|
|
|
void QEditorInputBinding::postMouseReleaseEvent(QMouseEvent *event,
|
|
QEditor *editor) {
|
|
Q_UNUSED(event)
|
|
Q_UNUSED(editor)
|
|
}
|
|
|
|
bool QEditorInputBinding::mouseDoubleClickEvent(QMouseEvent *event,
|
|
QEditor *editor) {
|
|
Q_UNUSED(event)
|
|
Q_UNUSED(editor)
|
|
|
|
return false;
|
|
}
|
|
|
|
void QEditorInputBinding::postMouseDoubleClickEvent(QMouseEvent *event,
|
|
QEditor *editor) {
|
|
Q_UNUSED(event)
|
|
Q_UNUSED(editor)
|
|
}
|
|
|
|
bool QEditorInputBinding::contextMenuEvent(QContextMenuEvent *event,
|
|
QEditor *editor) {
|
|
Q_UNUSED(event)
|
|
Q_UNUSED(editor)
|
|
|
|
return false;
|
|
}
|