diff options
Diffstat (limited to 'examples/widgets/tools/customcompleter/textedit.cpp')
-rw-r--r-- | examples/widgets/tools/customcompleter/textedit.cpp | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/examples/widgets/tools/customcompleter/textedit.cpp b/examples/widgets/tools/customcompleter/textedit.cpp new file mode 100644 index 0000000000..65054e736d --- /dev/null +++ b/examples/widgets/tools/customcompleter/textedit.cpp @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "textedit.h" +#include <QCompleter> +#include <QKeyEvent> +#include <QAbstractItemView> +#include <QtDebug> +#include <QApplication> +#include <QModelIndex> +#include <QAbstractItemModel> +#include <QScrollBar> + +//! [0] +TextEdit::TextEdit(QWidget *parent) +: QTextEdit(parent), c(0) +{ + setPlainText(tr("This TextEdit provides autocompletions for words that have more than" + " 3 characters. You can trigger autocompletion using ") + + QKeySequence("Ctrl+E").toString(QKeySequence::NativeText)); +} +//! [0] + +//! [1] +TextEdit::~TextEdit() +{ +} +//! [1] + +//! [2] +void TextEdit::setCompleter(QCompleter *completer) +{ + if (c) + QObject::disconnect(c, 0, this, 0); + + c = completer; + + if (!c) + return; + + c->setWidget(this); + c->setCompletionMode(QCompleter::PopupCompletion); + c->setCaseSensitivity(Qt::CaseInsensitive); + QObject::connect(c, SIGNAL(activated(QString)), + this, SLOT(insertCompletion(QString))); +} +//! [2] + +//! [3] +QCompleter *TextEdit::completer() const +{ + return c; +} +//! [3] + +//! [4] +void TextEdit::insertCompletion(const QString& completion) +{ + if (c->widget() != this) + return; + QTextCursor tc = textCursor(); + int extra = completion.length() - c->completionPrefix().length(); + tc.movePosition(QTextCursor::Left); + tc.movePosition(QTextCursor::EndOfWord); + tc.insertText(completion.right(extra)); + setTextCursor(tc); +} +//! [4] + +//! [5] +QString TextEdit::textUnderCursor() const +{ + QTextCursor tc = textCursor(); + tc.select(QTextCursor::WordUnderCursor); + return tc.selectedText(); +} +//! [5] + +//! [6] +void TextEdit::focusInEvent(QFocusEvent *e) +{ + if (c) + c->setWidget(this); + QTextEdit::focusInEvent(e); +} +//! [6] + +//! [7] +void TextEdit::keyPressEvent(QKeyEvent *e) +{ + if (c && c->popup()->isVisible()) { + // The following keys are forwarded by the completer to the widget + switch (e->key()) { + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Escape: + case Qt::Key_Tab: + case Qt::Key_Backtab: + e->ignore(); + return; // let the completer do default behavior + default: + break; + } + } + + bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E + if (!c || !isShortcut) // do not process the shortcut when we have a completer + QTextEdit::keyPressEvent(e); +//! [7] + +//! [8] + const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier); + if (!c || (ctrlOrShift && e->text().isEmpty())) + return; + + static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word + bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift; + QString completionPrefix = textUnderCursor(); + + if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3 + || eow.contains(e->text().right(1)))) { + c->popup()->hide(); + return; + } + + if (completionPrefix != c->completionPrefix()) { + c->setCompletionPrefix(completionPrefix); + c->popup()->setCurrentIndex(c->completionModel()->index(0, 0)); + } + QRect cr = cursorRect(); + cr.setWidth(c->popup()->sizeHintForColumn(0) + + c->popup()->verticalScrollBar()->sizeHint().width()); + c->complete(cr); // popup it up! +} +//! [8] + |