]> git.sur5r.net Git - minitube/blob - src/autocomplete.cpp
Imported Upstream version 1.4.1
[minitube] / src / autocomplete.cpp
1 #include "autocomplete.h"
2 #include "suggester.h"
3
4 AutoComplete::AutoComplete(QWidget *parent, QLineEdit *editor):
5         QObject(parent), buddy(parent), editor(editor), suggester(0) {
6
7     enabled = true;
8
9     popup = new QListWidget;
10     popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
11     popup->installEventFilter(this);
12     popup->setMouseTracking(true);
13     popup->setWindowOpacity(.9);
14
15     connect(popup, SIGNAL(itemClicked(QListWidgetItem*)),
16             SLOT(doneCompletion()));
17
18     // connect(popup, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)),
19     //    SLOT(currentItemChanged(QListWidgetItem *)));
20
21     // mouse hover
22     // connect(popup, SIGNAL(itemEntered(QListWidgetItem*)),
23     //    SLOT(currentItemChanged(QListWidgetItem *)));
24
25     popup->setWindowFlags(Qt::Popup);
26     popup->setFocusPolicy(Qt::NoFocus);
27     popup->setFocusProxy(parent);
28
29     timer = new QTimer(this);
30     timer->setSingleShot(true);
31     timer->setInterval(300);
32     connect(timer, SIGNAL(timeout()), SLOT(autoSuggest()));
33     connect(editor, SIGNAL(textEdited(QString)), timer, SLOT(start()));
34
35 }
36
37 AutoComplete::~AutoComplete() {
38     delete popup;
39 }
40
41 bool AutoComplete::eventFilter(QObject *obj, QEvent *ev) {
42     if (obj != popup)
43         return false;
44
45     if (ev->type() == QEvent::MouseButtonPress) {
46         popup->hide();
47         editor->setFocus();
48         editor->setText(originalText);
49         return true;
50     }
51
52     if (ev->type() == QEvent::KeyPress) {
53
54         bool consumed = false;
55
56         QKeyEvent *keyEvent = static_cast<QKeyEvent*>(ev);
57         int key = keyEvent->key();
58         // qDebug() << keyEvent->text();
59         switch (key) {
60         case Qt::Key_Enter:
61         case Qt::Key_Return:
62             if (popup->currentItem()) {
63                 doneCompletion();
64                 consumed = true;
65             } else {
66                 editor->setFocus();
67                 editor->event(ev);
68                 popup->hide();
69             }
70             break;
71
72         case Qt::Key_Escape:
73             editor->setFocus();
74             editor->setText(originalText);
75             popup->hide();
76             consumed = true;
77             break;
78
79         case Qt::Key_Up:
80         case Qt::Key_Down:
81         case Qt::Key_Home:
82         case Qt::Key_End:
83         case Qt::Key_PageUp:
84         case Qt::Key_PageDown:
85             break;
86
87         default:
88             // qDebug() << keyEvent->text();
89             editor->setFocus();
90             editor->event(ev);
91             popup->hide();
92             break;
93         }
94
95         return consumed;
96     }
97
98     return false;
99 }
100
101 void AutoComplete::showCompletion(const QStringList &choices) {
102
103     if (choices.isEmpty())
104         return;
105
106     popup->setUpdatesEnabled(false);
107     popup->clear();
108     for (int i = 0; i < choices.count(); ++i) {
109         QListWidgetItem * item;
110         item = new QListWidgetItem(popup);
111         item->setText(choices[i]);
112     }
113     popup->setCurrentItem(0);
114     popup->adjustSize();
115     popup->setUpdatesEnabled(true);
116
117     int h = popup->sizeHintForRow(0) * choices.count() + 4;
118     popup->resize(buddy->width(), h);
119
120     popup->move(buddy->mapToGlobal(QPoint(0, buddy->height())));
121
122     popup->setFocus();
123     popup->show();
124 }
125
126 void AutoComplete::doneCompletion() {
127     timer->stop();
128     popup->hide();
129     editor->setFocus();
130     QListWidgetItem *item = popup->currentItem();
131     if (item) {
132         editor->setText(item->text());
133         QKeyEvent *e;
134         e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
135         QApplication::postEvent(editor, e);
136         e = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier);
137         QApplication::postEvent(editor, e);
138     }
139 }
140
141 void AutoComplete::preventSuggest() {
142     // qDebug() << "preventSuggest";
143     timer->stop();
144     enabled = false;
145     popup->hide();
146 }
147
148 void AutoComplete::enableSuggest() {
149     // qDebug() << "enableSuggest";
150     enabled = true;
151 }
152
153 void AutoComplete::setSuggester(Suggester* suggester) {
154     if (this->suggester) this->suggester->disconnect();
155     this->suggester = suggester;
156     connect(suggester, SIGNAL(ready(QStringList)), SLOT(suggestionsReady(QStringList)));
157 }
158
159 void AutoComplete::autoSuggest() {
160     if (!enabled) return;
161
162     QString query = editor->text();
163     originalText = query;
164     // qDebug() << "originalText" << originalText;
165     if (query.isEmpty()) return;
166
167     if (suggester)
168         suggester->suggest(query);
169 }
170
171 void AutoComplete::suggestionsReady(QStringList suggestions) {
172     if (!enabled) return;
173     showCompletion(suggestions);
174 }
175
176 void AutoComplete::currentItemChanged(QListWidgetItem *current) {
177     if (current) {
178         // qDebug() << "current" << current->text();
179         current->setSelected(true);
180         editor->setText(current->text());
181         editor->setSelection(originalText.length(), editor->text().length());
182     }
183 }