1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
#include <QtGui>
#include <QModelIndex>
#include "treemodelcompleter.h"
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QTextEdit(parent) {
completer = new TreeModelCompleter(this);
completer->setWidget(this);
completer->setModel(modelFromFile(":/resources/treemodel.txt"));
completer->setSeparator(QLatin1String("."));
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
completer->setCompletionMode(QCompleter::PopupCompletion);
completer->setWrapAround(true);
QObject::connect(completer, SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString)));
setWindowTitle(tr("Tree Model Completer"));
}
void MainWindow::insertCompletion(const QString& completion) {
if (completer->widget() != this)
return;
QTextCursor tc = textCursor();
int extra = completion.length() - completer->completionPrefix().length();
tc.movePosition(QTextCursor::Left);
tc.movePosition(QTextCursor::EndOfWord);
tc.insertText(completion.right(extra));
setTextCursor(tc);
}
QString MainWindow::textUnderCursor() const {
QTextCursor tc = textCursor();
tc.select(QTextCursor::WordUnderCursor);
QString t = tc.selectedText();
return tc.selectedText();
}
void MainWindow::focusInEvent(QFocusEvent *e) {
if (completer)
completer->setWidget(this);
QTextEdit::focusInEvent(e);
}
void MainWindow::keyPressEvent(QKeyEvent *e) {
if (completer && completer->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 (!completer || !isShortcut) // do not process the shortcut when we have a completer
QTextEdit::keyPressEvent(e);
const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);
if (!completer || (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() || eow.contains(e->text().right(1)))) {
completer->popup()->hide();
return;
}
if (completionPrefix != completer->completionPrefix()) {
completer->setCompletionPrefix(completionPrefix);
completer->popup()->setCurrentIndex(completer->completionModel()->index(0, 0));
}
QRect cr = cursorRect();
cr.setWidth(completer->popup()->sizeHintForColumn(0) + completer->popup()->verticalScrollBar()->sizeHint().width());
completer->complete(cr); // popup it up!
}
QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName) {
QFile file(fileName);
if (!file.open(QFile::ReadOnly))
return new QStringListModel(completer);
#ifndef QT_NO_CURSOR
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
#endif
QStringList words;
QStandardItemModel *model = new QStandardItemModel(completer);
QVector<QStandardItem *> parents(10);
parents[0] = model->invisibleRootItem();
while (!file.atEnd()) {
QString line = file.readLine();
QString trimmedLine = line.trimmed();
if (line.isEmpty() || trimmedLine.isEmpty())
continue;
QRegExp re("^\\s+");
int nonws = re.indexIn(line);
int level = 0;
if (nonws == -1) {
level = 0;
} else {
if (line.startsWith("\t")) {
level = re.cap(0).length();
} else {
level = re.cap(0).length()/4;
}
}
if (level+1 >= parents.size())
parents.resize(parents.size()*2);
QStandardItem *item = new QStandardItem;
item->setText(trimmedLine);
parents[level]->appendRow(item);
parents[level+1] = item;
}
#ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor();
#endif
return model;
} |
Partager