source: trunk/examples/tools/customcompleter/textedit.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 5.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "textedit.h"
42#include <QCompleter>
43#include <QKeyEvent>
44#include <QAbstractItemView>
45#include <QtDebug>
46#include <QApplication>
47#include <QModelIndex>
48#include <QAbstractItemModel>
49#include <QScrollBar>
50
51//! [0]
52TextEdit::TextEdit(QWidget *parent)
53: QTextEdit(parent), c(0)
54{
55 setPlainText(tr("This TextEdit provides autocompletions for words that have more than"
56 " 3 characters. You can trigger autocompletion using ") +
57 QKeySequence("Ctrl+E").toString(QKeySequence::NativeText));
58}
59//! [0]
60
61//! [1]
62TextEdit::~TextEdit()
63{
64}
65//! [1]
66
67//! [2]
68void TextEdit::setCompleter(QCompleter *completer)
69{
70 if (c)
71 QObject::disconnect(c, 0, this, 0);
72
73 c = completer;
74
75 if (!c)
76 return;
77
78 c->setWidget(this);
79 c->setCompletionMode(QCompleter::PopupCompletion);
80 c->setCaseSensitivity(Qt::CaseInsensitive);
81 QObject::connect(c, SIGNAL(activated(QString)),
82 this, SLOT(insertCompletion(QString)));
83}
84//! [2]
85
86//! [3]
87QCompleter *TextEdit::completer() const
88{
89 return c;
90}
91//! [3]
92
93//! [4]
94void TextEdit::insertCompletion(const QString& completion)
95{
96 if (c->widget() != this)
97 return;
98 QTextCursor tc = textCursor();
99 int extra = completion.length() - c->completionPrefix().length();
100 tc.movePosition(QTextCursor::Left);
101 tc.movePosition(QTextCursor::EndOfWord);
102 tc.insertText(completion.right(extra));
103 setTextCursor(tc);
104}
105//! [4]
106
107//! [5]
108QString TextEdit::textUnderCursor() const
109{
110 QTextCursor tc = textCursor();
111 tc.select(QTextCursor::WordUnderCursor);
112 return tc.selectedText();
113}
114//! [5]
115
116//! [6]
117void TextEdit::focusInEvent(QFocusEvent *e)
118{
119 if (c)
120 c->setWidget(this);
121 QTextEdit::focusInEvent(e);
122}
123//! [6]
124
125//! [7]
126void TextEdit::keyPressEvent(QKeyEvent *e)
127{
128 if (c && c->popup()->isVisible()) {
129 // The following keys are forwarded by the completer to the widget
130 switch (e->key()) {
131 case Qt::Key_Enter:
132 case Qt::Key_Return:
133 case Qt::Key_Escape:
134 case Qt::Key_Tab:
135 case Qt::Key_Backtab:
136 e->ignore();
137 return; // let the completer do default behavior
138 default:
139 break;
140 }
141 }
142
143 bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E
144 if (!c || !isShortcut) // do not process the shortcut when we have a completer
145 QTextEdit::keyPressEvent(e);
146//! [7]
147
148//! [8]
149 const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);
150 if (!c || (ctrlOrShift && e->text().isEmpty()))
151 return;
152
153 static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
154 bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
155 QString completionPrefix = textUnderCursor();
156
157 if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3
158 || eow.contains(e->text().right(1)))) {
159 c->popup()->hide();
160 return;
161 }
162
163 if (completionPrefix != c->completionPrefix()) {
164 c->setCompletionPrefix(completionPrefix);
165 c->popup()->setCurrentIndex(c->completionModel()->index(0, 0));
166 }
167 QRect cr = cursorRect();
168 cr.setWidth(c->popup()->sizeHintForColumn(0)
169 + c->popup()->verticalScrollBar()->sizeHint().width());
170 c->complete(cr); // popup it up!
171}
172//! [8]
173
Note: See TracBrowser for help on using the repository browser.