1 #include "lineeditcompleter.h"
2
3 #include <QAbstractItemView>
4 #include <QCompleter>
5 #include <QFocusEvent>
6 #include <QKeyEvent>
7 #include <QScrollBar>
8 #include <QStringListModel>
9 #include <QTextCursor>
10 #include <QWidget>
11
LineEditCompleter(QWidget * parent)12 LineEditCompleter::LineEditCompleter(QWidget *parent) : LineEditUnfocusable(parent), c(nullptr)
13 {
14 }
15
focusOutEvent(QFocusEvent * e)16 void LineEditCompleter::focusOutEvent(QFocusEvent *e)
17 {
18 LineEditUnfocusable::focusOutEvent(e);
19 if (c->popup()->isVisible()) {
20 // Remove Popup
21 c->popup()->hide();
22 // Truncate the line to last space or whole string
23 QString textValue = text();
24 int lastIndex = textValue.length();
25 int lastWordStartIndex = textValue.lastIndexOf(" ") + 1;
26 int leftShift = qMin(lastIndex, lastWordStartIndex);
27 setText(textValue.left(leftShift));
28 // Insert highlighted line from popup
29 insert(c->completionModel()->index(c->popup()->currentIndex().row(), 0).data().toString() + " ");
30 // Set focus back to the textbox since tab was pressed
31 setFocus();
32 }
33 }
34
keyPressEvent(QKeyEvent * event)35 void LineEditCompleter::keyPressEvent(QKeyEvent *event)
36 {
37 switch (event->key()) {
38 case Qt::Key_Return:
39 case Qt::Key_Enter:
40 case Qt::Key_Escape:
41 if (c->popup()->isVisible()) {
42 event->ignore();
43 // Remove Popup
44 c->popup()->hide();
45 // Truncate the line to last space or whole string
46 QString textValue = text();
47 int lastIndexof = qMax(0, textValue.lastIndexOf(" "));
48 QString finalString = textValue.left(lastIndexof);
49 // Add a space if there's a word
50 if (finalString != "")
51 finalString += " ";
52 setText(finalString);
53 return;
54 }
55 break;
56 case Qt::Key_Space:
57 if (c->popup()->isVisible()) {
58 event->ignore();
59 // Remove Popup
60 c->popup()->hide();
61 // Truncate the line to last space or whole string
62 QString textValue = text();
63 int lastIndex = textValue.length();
64 int lastWordStartIndex = textValue.lastIndexOf(" ") + 1;
65 int leftShift = qMin(lastIndex, lastWordStartIndex);
66 setText(textValue.left(leftShift));
67 // Insert highlighted line from popup
68 insert(c->completionModel()->index(c->popup()->currentIndex().row(), 0).data().toString() + " ");
69 return;
70 }
71 break;
72 default:
73 break;
74 }
75
76 LineEditUnfocusable::keyPressEvent(event);
77 // return if the completer is null or if the most recently typed char was '@'.
78 // Only want the popup AFTER typing the first char of the mention.
79 if (!c || text().right(1).contains("@")) {
80 c->popup()->hide();
81 return;
82 }
83
84 // Set new completion prefix
85 c->setCompletionPrefix(cursorWord(text()));
86 if (c->completionPrefix().length() < 1) {
87 c->popup()->hide();
88 return;
89 }
90
91 // Draw completion box
92 QRect cr = cursorRect();
93 cr.setWidth(c->popup()->sizeHintForColumn(0) + c->popup()->verticalScrollBar()->sizeHint().width());
94 c->complete(cr);
95
96 // Select first item in the completion popup
97 QItemSelectionModel *sm = new QItemSelectionModel(c->completionModel());
98 c->popup()->setSelectionModel(sm);
99 sm->select(c->completionModel()->index(0, 0), QItemSelectionModel::ClearAndSelect);
100 sm->setCurrentIndex(c->completionModel()->index(0, 0), QItemSelectionModel::NoUpdate);
101 }
102
cursorWord(const QString & line) const103 QString LineEditCompleter::cursorWord(const QString &line) const
104 {
105 return line.mid(line.left(cursorPosition()).lastIndexOf(" ") + 1,
106 cursorPosition() - line.left(cursorPosition()).lastIndexOf(" ") - 1);
107 }
108
insertCompletion(QString arg)109 void LineEditCompleter::insertCompletion(QString arg)
110 {
111 QString s_arg = arg + " ";
112 setText(text().replace(text().left(cursorPosition()).lastIndexOf(" ") + 1,
113 cursorPosition() - text().left(cursorPosition()).lastIndexOf(" ") - 1, s_arg));
114 }
115
setCompleter(QCompleter * completer)116 void LineEditCompleter::setCompleter(QCompleter *completer)
117 {
118 c = completer;
119 c->setWidget(this);
120 connect(c, SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString)));
121 }
122
setCompletionList(QStringList completionList)123 void LineEditCompleter::setCompletionList(QStringList completionList)
124 {
125 if (!c || c->popup()->isVisible())
126 return;
127
128 QStringListModel *model;
129 model = (QStringListModel *)(c->model());
130 if (model == NULL)
131 model = new QStringListModel();
132 model->setStringList(completionList);
133 }
134