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