]> git.sur5r.net Git - minitube/blobdiff - src/autocomplete.cpp
Updated UA
[minitube] / src / autocomplete.cpp
index e6e0d429af0fd4e9d08966c35a465d8371439154..8ef4d317d7e910766abbd7b07edfc6ce12864896 100644 (file)
@@ -19,51 +19,76 @@ along with Minitube.  If not, see <http://www.gnu.org/licenses/>.
 $END_LICENSE */
 #include "autocomplete.h"
 #include "suggester.h"
-#ifdef APP_MAC
+#ifdef APP_MAC_SEARCHFIELD
 #include "searchlineedit_mac.h"
 #else
 #include "searchlineedit.h"
 #endif
 
-AutoComplete::AutoComplete(SearchLineEdit *buddy, QLineEdit *lineEdit):
-    QObject(buddy), buddy(buddy), lineEdit(lineEdit), suggester(0) {
+#ifdef APP_MAC
+#include "macutils.h"
+#endif
 
-    enabled = true;
+#include <QListWidget>
+
+#ifndef QT_NO_DEBUG_OUTPUT
+/// Gives human-readable event type information.
+QDebug operator<<(QDebug str, const QEvent * ev) {
+    static int eventEnumIndex = QEvent::staticMetaObject.indexOfEnumerator("Type");
+    str << "QEvent";
+    if (ev) {
+        QString name = QEvent::staticMetaObject.enumerator(eventEnumIndex).valueToKey(ev->type());
+        if (!name.isEmpty()) str << name; else str << ev->type();
+    } else {
+        str << (void*)ev;
+    }
+    return str.maybeSpace();
+}
+#endif
+
+AutoComplete::AutoComplete(SearchWidget *buddy, QLineEdit *lineEdit):
+    QObject(lineEdit), buddy(buddy), lineEdit(lineEdit), enabled(true), suggester(0), itemHovering(false) {
 
     popup = new QListWidget();
-    popup->setMouseTracking(true);
     popup->setWindowFlags(Qt::Popup);
-    popup->setAttribute(Qt::WA_ShowWithoutActivating);
-    popup->setFocusPolicy(Qt::NoFocus);
-    popup->setFocusProxy(buddy);
+    popup->setFocusProxy(buddy->toWidget());
     popup->installEventFilter(this);
+    buddy->toWidget()->window()->installEventFilter(this);
+    popup->setMouseTracking(true);
 
+    // style
     popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
     popup->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
     popup->setWindowOpacity(.9);
     popup->setProperty("suggest", true);
-    popup->setFrameShape(QFrame::NoFrame);
-    popup->setAttribute(Qt::WA_TranslucentBackground);
-    popup->viewport()->setStyleSheet("border:0; border-radius:5px; background:palette(base)");
 
     connect(popup, SIGNAL(itemClicked(QListWidgetItem*)), SLOT(acceptSuggestion()));
     connect(popup, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
-        SLOT(currentItemChanged(QListWidgetItem*)));
+            SLOT(currentItemChanged(QListWidgetItem*)));
     connect(popup, SIGNAL(itemEntered(QListWidgetItem*)), SLOT(itemEntered(QListWidgetItem *)));
 
     timer = new QTimer(this);
     timer->setSingleShot(true);
     timer->setInterval(500);
     connect(timer, SIGNAL(timeout()), SLOT(suggest()));
-    connect(buddy, SIGNAL(textEdited(QString)), timer, SLOT(start()));
-}
-
-AutoComplete::~AutoComplete() {
-    delete popup;
+    connect(buddy->toWidget(), SIGNAL(textEdited(QString)), timer, SLOT(start()));
 }
 
 bool AutoComplete::eventFilter(QObject *obj, QEvent *ev) {
-    if (obj != popup) return false;
+
+    if (obj != popup) {
+        switch (ev->type()) {
+        case QEvent::Move:
+        case QEvent::Resize:
+            adjustPosition();
+            break;
+        default:
+            break;
+        }
+        return false;
+    }
+
+    // qDebug() << ev;
 
     if (ev->type() == QEvent::Leave) {
         popup->setCurrentItem(0);
@@ -72,10 +97,8 @@ bool AutoComplete::eventFilter(QObject *obj, QEvent *ev) {
         return true;
     }
 
-    if (ev->type() == QEvent::FocusOut) {
-        popup->hide();
-        buddy->setText(originalText);
-        buddy->setFocus();
+    if (ev->type() == QEvent::FocusOut || ev->type() == QEvent::MouseButtonPress) {
+        hideSuggestions();
         return true;
     }
 
@@ -90,17 +113,13 @@ bool AutoComplete::eventFilter(QObject *obj, QEvent *ev) {
                 acceptSuggestion();
                 consumed = true;
             } else {
-                buddy->setFocus();
                 lineEdit->event(ev);
-                popup->hide();
+                hideSuggestions();
             }
             break;
 
         case Qt::Key_Escape:
-            popup->hide();
-            popup->clear();
-            buddy->setText(originalText);
-            buddy->setFocus();
+            hideSuggestions();
             consumed = true;
             break;
 
@@ -109,7 +128,7 @@ bool AutoComplete::eventFilter(QObject *obj, QEvent *ev) {
                 popup->setCurrentItem(0);
                 popup->clearSelection();
                 buddy->setText(originalText);
-                buddy->setFocus();
+                buddy->toWidget()->setFocus();
                 consumed = true;
             }
             break;
@@ -135,46 +154,45 @@ bool AutoComplete::eventFilter(QObject *obj, QEvent *ev) {
     return false;
 }
 
-void AutoComplete::showCompletion(const QList<Suggestion *> &suggestions) {
+void AutoComplete::showSuggestions(const QList<Suggestion *> &suggestions) {
     if (suggestions.isEmpty()) {
-        popup->clear();
-        popup->hide();
+        hideSuggestions();
         return;
     }
     popup->setUpdatesEnabled(false);
     popup->clear();
     for (int i = 0; i < suggestions.count(); ++i) {
-        QListWidgetItem * item;
-        item = new QListWidgetItem(popup);
+        QListWidgetItem *item = new QListWidgetItem(popup);
         Suggestion *s = suggestions[i];
         item->setText(s->value);
         if (!s->type.isEmpty())
             item->setIcon(QIcon(":/images/" + s->type + ".png"));
     }
     popup->setCurrentItem(0);
-    int h = 0;
+    int h = popup->frameWidth() * 2;
     for (int i = 0; i < suggestions.count(); ++i)
         h += popup->sizeHintForRow(i);
-    popup->resize(buddy->width(), h);
-    popup->move(buddy->mapToGlobal(QPoint(0, buddy->height())));
-    popup->setFocus();
 
-    if (popup->isHidden()) popup->show();
+    popup->resize(buddy->toWidget()->width(), h);
+    adjustPosition();
     popup->setUpdatesEnabled(true);
+
+    if (popup->isHidden()) {
+        itemHovering = false;
+        popup->showNormal();
+        QTimer::singleShot(100, this, SLOT(enableItemHovering()));
+    }
 }
 
 void AutoComplete::acceptSuggestion() {
-    timer->stop();
-    originalText.clear();
-    popup->hide();
-    buddy->setFocus();
     int index = popup->currentIndex().row();
     if (index >= 0 && index < suggestions.size()) {
         Suggestion* suggestion = suggestions.at(index);
         buddy->setText(suggestion->value);
         emit suggestionAccepted(suggestion);
         emit suggestionAccepted(suggestion->value);
-        popup->clear();
+        originalText.clear();
+        hideSuggestions();
     } else qWarning() << "No suggestion for index" << index;
 }
 
@@ -182,7 +200,6 @@ void AutoComplete::preventSuggest() {
     timer->stop();
     enabled = false;
     popup->hide();
-    popup->setFrameShape(QFrame::NoFrame);
 }
 
 void AutoComplete::enableSuggest() {
@@ -197,15 +214,13 @@ void AutoComplete::setSuggester(Suggester* suggester) {
 
 void AutoComplete::suggest() {
     if (!enabled) return;
-    if (!buddy->hasFocus()) return;
 
     popup->setCurrentItem(0);
     popup->clearSelection();
 
     originalText = buddy->text();
     if (originalText.isEmpty()) {
-        popup->hide();
-        buddy->setFocus();
+        hideSuggestions();
         return;
     }
 
@@ -216,11 +231,36 @@ void AutoComplete::suggestionsReady(const QList<Suggestion *> &suggestions) {
     qDeleteAll(this->suggestions);
     this->suggestions = suggestions;
     if (!enabled) return;
-    if (!buddy->hasFocus()) return;
-    showCompletion(suggestions);
+    if (!buddy->toWidget()->hasFocus() && buddy->toWidget()->isVisible()) return;
+    showSuggestions(suggestions);
+}
+
+void AutoComplete::adjustPosition() {
+    popup->move(buddy->toWidget()->mapToGlobal(QPoint(0, buddy->toWidget()->height())));
+}
+
+void AutoComplete::enableItemHovering() {
+    itemHovering = true;
+}
+
+void AutoComplete::hideSuggestions() {
+    itemHovering = false;
+#ifdef APP_MAC_NO
+    mac::fadeOutWindow(popup);
+#else
+    popup->hide();
+    popup->clear();
+#endif
+    if (!originalText.isEmpty()) {
+        buddy->setText(originalText);
+        originalText.clear();
+    }
+    buddy->toWidget()->setFocus();
+    timer->stop();
 }
 
 void AutoComplete::itemEntered(QListWidgetItem *item) {
+    if (!itemHovering) return;
     if (!item) return;
     item->setSelected(true);
     popup->setCurrentItem(item);
@@ -229,5 +269,5 @@ void AutoComplete::itemEntered(QListWidgetItem *item) {
 void AutoComplete::currentItemChanged(QListWidgetItem *item) {
     if (!item) return;
     buddy->setText(item->text());
-    // lineEdit->setSelection(originalText.length(), editor->text().length());
+    // lineEdit->setSelection(originalText.length(), lineEdit->text().length());
 }