From: Flavio Date: Tue, 25 Jan 2011 23:34:30 +0000 (+0100) Subject: Nicer selection style on Mac & Win X-Git-Tag: 1.4~41 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=acda6aee34b1aa7cec6f9aa04e73f4b0c3e1e5ee;p=minitube Nicer selection style on Mac & Win --- diff --git a/src/Suggester.h b/src/Suggester.h new file mode 100644 index 0000000..dc30bd8 --- /dev/null +++ b/src/Suggester.h @@ -0,0 +1,18 @@ +#ifndef SUGGESTER_H +#define SUGGESTER_H + +#include + +class Suggester : public QObject { + + Q_OBJECT + +public: + virtual void suggest(QString query) = 0; + +signals: + void ready(QStringList); + +}; + +#endif // SUGGESTER_H diff --git a/src/autocomplete.cpp b/src/autocomplete.cpp new file mode 100644 index 0000000..656c651 --- /dev/null +++ b/src/autocomplete.cpp @@ -0,0 +1,205 @@ +#include "googlesuggest.h" +#include "networkaccess.h" + +#define GSUGGEST_URL "http://suggestqueries.google.com/complete/search?ds=yt&output=toolbar&hl=%1&q=%2" + +namespace The { + NetworkAccess* http(); +} + +GSuggestCompletion::GSuggestCompletion(QWidget *parent, QLineEdit *editor): + QObject(parent), buddy(parent), editor(editor) { + + enabled = true; + + popup = new QListWidget; + popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + popup->installEventFilter(this); + popup->setMouseTracking(true); + popup->setWindowOpacity(.9); + + connect(popup, SIGNAL(itemClicked(QListWidgetItem*)), + SLOT(doneCompletion())); + + // connect(popup, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), + // SLOT(currentItemChanged(QListWidgetItem *))); + + // mouse hover + // connect(popup, SIGNAL(itemEntered(QListWidgetItem*)), + // SLOT(currentItemChanged(QListWidgetItem *))); + + popup->setWindowFlags(Qt::Popup); + popup->setFocusPolicy(Qt::NoFocus); + popup->setFocusProxy(parent); + + timer = new QTimer(this); + timer->setSingleShot(true); + timer->setInterval(300); + connect(timer, SIGNAL(timeout()), SLOT(autoSuggest())); + connect(editor, SIGNAL(textEdited(QString)), timer, SLOT(start())); + +} + +GSuggestCompletion::~GSuggestCompletion() { + delete popup; +} + +bool GSuggestCompletion::eventFilter(QObject *obj, QEvent *ev) { + if (obj != popup) + return false; + + if (ev->type() == QEvent::MouseButtonPress) { + popup->hide(); + editor->setFocus(); + editor->setText(originalText); + return true; + } + + if (ev->type() == QEvent::KeyPress) { + + bool consumed = false; + + QKeyEvent *keyEvent = static_cast(ev); + int key = keyEvent->key(); + // qDebug() << keyEvent->text(); + switch (key) { + case Qt::Key_Enter: + case Qt::Key_Return: + if (popup->currentItem()) { + doneCompletion(); + consumed = true; + } else { + editor->setFocus(); + editor->event(ev); + popup->hide(); + } + break; + + case Qt::Key_Escape: + editor->setFocus(); + editor->setText(originalText); + popup->hide(); + consumed = true; + break; + + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + break; + + default: + // qDebug() << keyEvent->text(); + editor->setFocus(); + editor->event(ev); + popup->hide(); + break; + } + + return consumed; + } + + return false; +} + +void GSuggestCompletion::showCompletion(const QStringList &choices) { + + if (choices.isEmpty()) + return; + + popup->setUpdatesEnabled(false); + popup->clear(); + for (int i = 0; i < choices.count(); ++i) { + QListWidgetItem * item; + item = new QListWidgetItem(popup); + item->setText(choices[i]); + } + popup->setCurrentItem(0); + popup->adjustSize(); + popup->setUpdatesEnabled(true); + + int h = popup->sizeHintForRow(0) * choices.count() + 4; + popup->resize(buddy->width(), h); + + popup->move(buddy->mapToGlobal(QPoint(0, buddy->height()))); + + popup->setFocus(); + popup->show(); +} + +void GSuggestCompletion::doneCompletion() { + timer->stop(); + popup->hide(); + editor->setFocus(); + QListWidgetItem *item = popup->currentItem(); + if (item) { + editor->setText(item->text()); + QKeyEvent *e; + e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier); + QApplication::postEvent(editor, e); + e = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier); + QApplication::postEvent(editor, e); + } +} + +void GSuggestCompletion::preventSuggest() { + // qDebug() << "preventSuggest"; + timer->stop(); + enabled = false; + popup->hide(); +} + +void GSuggestCompletion::enableSuggest() { + // qDebug() << "enableSuggest"; + enabled = true; +} + +void GSuggestCompletion::autoSuggest() { + if (!enabled) return; + + QString query = editor->text(); + originalText = query; + // qDebug() << "originalText" << originalText; + if (query.isEmpty()) return; + + QString locale = QLocale::system().name().replace("_", "-"); + // case for system locales such as "C" + if (locale.length() < 2) { + locale = "en-US"; + } + + QString url = QString(GSUGGEST_URL).arg(locale, query); + + QObject *reply = The::http()->get(url); + connect(reply, SIGNAL(data(QByteArray)), SLOT(handleNetworkData(QByteArray))); +} + +void GSuggestCompletion::handleNetworkData(QByteArray response) { + if (!enabled) return; + + QStringList choices; + + QXmlStreamReader xml(response); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.tokenType() == QXmlStreamReader::StartElement) + if (xml.name() == "suggestion") { + QStringRef str = xml.attributes().value("data"); + choices << str.toString(); + } + } + + showCompletion(choices); + +} + +void GSuggestCompletion::currentItemChanged(QListWidgetItem *current) { + if (current) { + // qDebug() << "current" << current->text(); + current->setSelected(true); + editor->setText(current->text()); + editor->setSelection(originalText.length(), editor->text().length()); + } +} diff --git a/src/autocomplete.h b/src/autocomplete.h new file mode 100644 index 0000000..9773380 --- /dev/null +++ b/src/autocomplete.h @@ -0,0 +1,33 @@ +#ifndef GOOGLESUGGEST_H +#define GOOGLESUGGEST_H + +#include + +class GSuggestCompletion : public QObject { + Q_OBJECT + +public: + GSuggestCompletion(QWidget *parent, QLineEdit *editor); + ~GSuggestCompletion(); + bool eventFilter(QObject *obj, QEvent *ev); + void showCompletion(const QStringList &choices); + +public slots: + void doneCompletion(); + void preventSuggest(); + void enableSuggest(); + void autoSuggest(); + void handleNetworkData(QByteArray response); + void currentItemChanged(QListWidgetItem *current); + +private: + QWidget *buddy; + QLineEdit *editor; + QString originalText; + QListWidget *popup; + QTimer *timer; + bool enabled; + +}; + +#endif // GOOGLESUGGEST_H diff --git a/src/channelsuggest.cpp b/src/channelsuggest.cpp new file mode 100644 index 0000000..c36afb7 --- /dev/null +++ b/src/channelsuggest.cpp @@ -0,0 +1,46 @@ +#include "channelsuggest.h" +#include "networkaccess.h" + +namespace The { + NetworkAccess* http(); +} + +ChannelSuggest::ChannelSuggest(QObject *parent) : Suggester() { + +} + +void ChannelSuggest::suggest(QString query) { + + /* // TODO how to localize results? + QString locale = QLocale::system().name().replace("_", "-"); + // case for system locales such as "C" + if (locale.length() < 2) { + locale = "en-US"; + }*/ + + QUrl url("http://www.youtube.com/results?search_type=search_users"); + url.addQueryItem("search_query", query); + // url.addQueryItem("hl", "it-IT"); + + QObject *reply = The::http()->get(url); + connect(reply, SIGNAL(data(QByteArray)), SLOT(handleNetworkData(QByteArray))); +} + +void ChannelSuggest::handleNetworkData(QByteArray data) { + QStringList choices; + QString html = QString::fromUtf8(data); + QRegExp re("/user/([a-zA-Z0-9]+)"); + + int pos = 0; + while ((pos = re.indexIn(html, pos)) != -1) { + // qDebug() << re.cap(0) << re.cap(1); + QString choice = re.cap(1); + if (!choices.contains(choice)) { + choices << choice; + if (choices.size() == 10) break; + } + pos += re.matchedLength(); + } + + emit ready(choices); +} diff --git a/src/channelsuggest.h b/src/channelsuggest.h new file mode 100644 index 0000000..85cbef9 --- /dev/null +++ b/src/channelsuggest.h @@ -0,0 +1,24 @@ +#ifndef CHANNELSUGGEST_H +#define CHANNELSUGGEST_H + +#include + +#include "suggester.h" + +class ChannelSuggest : public Suggester { + + Q_OBJECT + +public: + ChannelSuggest(QObject *parent = 0); + void suggest(QString query); + +signals: + void ready(QStringList); + +private slots: + void handleNetworkData(QByteArray response); + +}; + +#endif // CHANNELSUGGEST_H diff --git a/src/googlesuggest.cpp b/src/googlesuggest.cpp deleted file mode 100644 index 656c651..0000000 --- a/src/googlesuggest.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include "googlesuggest.h" -#include "networkaccess.h" - -#define GSUGGEST_URL "http://suggestqueries.google.com/complete/search?ds=yt&output=toolbar&hl=%1&q=%2" - -namespace The { - NetworkAccess* http(); -} - -GSuggestCompletion::GSuggestCompletion(QWidget *parent, QLineEdit *editor): - QObject(parent), buddy(parent), editor(editor) { - - enabled = true; - - popup = new QListWidget; - popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - popup->installEventFilter(this); - popup->setMouseTracking(true); - popup->setWindowOpacity(.9); - - connect(popup, SIGNAL(itemClicked(QListWidgetItem*)), - SLOT(doneCompletion())); - - // connect(popup, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), - // SLOT(currentItemChanged(QListWidgetItem *))); - - // mouse hover - // connect(popup, SIGNAL(itemEntered(QListWidgetItem*)), - // SLOT(currentItemChanged(QListWidgetItem *))); - - popup->setWindowFlags(Qt::Popup); - popup->setFocusPolicy(Qt::NoFocus); - popup->setFocusProxy(parent); - - timer = new QTimer(this); - timer->setSingleShot(true); - timer->setInterval(300); - connect(timer, SIGNAL(timeout()), SLOT(autoSuggest())); - connect(editor, SIGNAL(textEdited(QString)), timer, SLOT(start())); - -} - -GSuggestCompletion::~GSuggestCompletion() { - delete popup; -} - -bool GSuggestCompletion::eventFilter(QObject *obj, QEvent *ev) { - if (obj != popup) - return false; - - if (ev->type() == QEvent::MouseButtonPress) { - popup->hide(); - editor->setFocus(); - editor->setText(originalText); - return true; - } - - if (ev->type() == QEvent::KeyPress) { - - bool consumed = false; - - QKeyEvent *keyEvent = static_cast(ev); - int key = keyEvent->key(); - // qDebug() << keyEvent->text(); - switch (key) { - case Qt::Key_Enter: - case Qt::Key_Return: - if (popup->currentItem()) { - doneCompletion(); - consumed = true; - } else { - editor->setFocus(); - editor->event(ev); - popup->hide(); - } - break; - - case Qt::Key_Escape: - editor->setFocus(); - editor->setText(originalText); - popup->hide(); - consumed = true; - break; - - case Qt::Key_Up: - case Qt::Key_Down: - case Qt::Key_Home: - case Qt::Key_End: - case Qt::Key_PageUp: - case Qt::Key_PageDown: - break; - - default: - // qDebug() << keyEvent->text(); - editor->setFocus(); - editor->event(ev); - popup->hide(); - break; - } - - return consumed; - } - - return false; -} - -void GSuggestCompletion::showCompletion(const QStringList &choices) { - - if (choices.isEmpty()) - return; - - popup->setUpdatesEnabled(false); - popup->clear(); - for (int i = 0; i < choices.count(); ++i) { - QListWidgetItem * item; - item = new QListWidgetItem(popup); - item->setText(choices[i]); - } - popup->setCurrentItem(0); - popup->adjustSize(); - popup->setUpdatesEnabled(true); - - int h = popup->sizeHintForRow(0) * choices.count() + 4; - popup->resize(buddy->width(), h); - - popup->move(buddy->mapToGlobal(QPoint(0, buddy->height()))); - - popup->setFocus(); - popup->show(); -} - -void GSuggestCompletion::doneCompletion() { - timer->stop(); - popup->hide(); - editor->setFocus(); - QListWidgetItem *item = popup->currentItem(); - if (item) { - editor->setText(item->text()); - QKeyEvent *e; - e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier); - QApplication::postEvent(editor, e); - e = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier); - QApplication::postEvent(editor, e); - } -} - -void GSuggestCompletion::preventSuggest() { - // qDebug() << "preventSuggest"; - timer->stop(); - enabled = false; - popup->hide(); -} - -void GSuggestCompletion::enableSuggest() { - // qDebug() << "enableSuggest"; - enabled = true; -} - -void GSuggestCompletion::autoSuggest() { - if (!enabled) return; - - QString query = editor->text(); - originalText = query; - // qDebug() << "originalText" << originalText; - if (query.isEmpty()) return; - - QString locale = QLocale::system().name().replace("_", "-"); - // case for system locales such as "C" - if (locale.length() < 2) { - locale = "en-US"; - } - - QString url = QString(GSUGGEST_URL).arg(locale, query); - - QObject *reply = The::http()->get(url); - connect(reply, SIGNAL(data(QByteArray)), SLOT(handleNetworkData(QByteArray))); -} - -void GSuggestCompletion::handleNetworkData(QByteArray response) { - if (!enabled) return; - - QStringList choices; - - QXmlStreamReader xml(response); - while (!xml.atEnd()) { - xml.readNext(); - if (xml.tokenType() == QXmlStreamReader::StartElement) - if (xml.name() == "suggestion") { - QStringRef str = xml.attributes().value("data"); - choices << str.toString(); - } - } - - showCompletion(choices); - -} - -void GSuggestCompletion::currentItemChanged(QListWidgetItem *current) { - if (current) { - // qDebug() << "current" << current->text(); - current->setSelected(true); - editor->setText(current->text()); - editor->setSelection(originalText.length(), editor->text().length()); - } -} diff --git a/src/googlesuggest.h b/src/googlesuggest.h deleted file mode 100644 index 9773380..0000000 --- a/src/googlesuggest.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef GOOGLESUGGEST_H -#define GOOGLESUGGEST_H - -#include - -class GSuggestCompletion : public QObject { - Q_OBJECT - -public: - GSuggestCompletion(QWidget *parent, QLineEdit *editor); - ~GSuggestCompletion(); - bool eventFilter(QObject *obj, QEvent *ev); - void showCompletion(const QStringList &choices); - -public slots: - void doneCompletion(); - void preventSuggest(); - void enableSuggest(); - void autoSuggest(); - void handleNetworkData(QByteArray response); - void currentItemChanged(QListWidgetItem *current); - -private: - QWidget *buddy; - QLineEdit *editor; - QString originalText; - QListWidget *popup; - QTimer *timer; - bool enabled; - -}; - -#endif // GOOGLESUGGEST_H diff --git a/src/playlist/PrettyItemDelegate.cpp b/src/playlist/PrettyItemDelegate.cpp index 4f64c99..3454572 100644 --- a/src/playlist/PrettyItemDelegate.cpp +++ b/src/playlist/PrettyItemDelegate.cpp @@ -85,6 +85,12 @@ void PrettyItemDelegate::paintBody( QPainter* painter, paintActiveOverlay(painter, line.x(), line.y(), line.width(), line.height()); } +#if defined(APP_MAC) | defined(APP_WIN) + if (isSelected) { + paintSelectedOverlay(painter, line.x(), line.y(), line.width(), line.height()); + } +#endif + // get the video metadata const VideoPointer videoPointer = index.data( VideoRole ).value(); const Video *video = videoPointer.data(); @@ -211,6 +217,20 @@ void PrettyItemDelegate::paintActiveOverlay( QPainter *painter, qreal x, qreal y painter->restore(); } +void PrettyItemDelegate::paintSelectedOverlay( QPainter *painter, qreal x, qreal y, qreal w, qreal h ) const { + QColor color1 = QColor::fromRgb(0x69, 0xa6, 0xd9); + QColor color2 = QColor::fromRgb(0x14, 0x6b, 0xd4); + QRect rect((int) x, (int) y, (int) w, (int) h); + painter->save(); + painter->setPen(Qt::NoPen); + QLinearGradient linearGradient(0, 0, 0, rect.height()); + linearGradient.setColorAt(0.0, color1); + linearGradient.setColorAt(1.0, color2); + painter->setBrush(linearGradient); + painter->drawRect(rect); + painter->restore(); +} + void PrettyItemDelegate::paintPlayIcon(QPainter *painter) const { painter->save(); painter->setOpacity(.5); diff --git a/src/playlist/PrettyItemDelegate.h b/src/playlist/PrettyItemDelegate.h index 4260558..708256f 100644 --- a/src/playlist/PrettyItemDelegate.h +++ b/src/playlist/PrettyItemDelegate.h @@ -27,6 +27,7 @@ private: const QModelIndex& index ) const; // active track painting + void paintSelectedOverlay( QPainter *painter, qreal x, qreal y, qreal w, qreal h ) const; void paintActiveOverlay( QPainter *painter, qreal x, qreal y, qreal w, qreal h ) const; void paintPlayIcon(QPainter *painter) const; diff --git a/src/suggester.h b/src/suggester.h new file mode 100644 index 0000000..dc30bd8 --- /dev/null +++ b/src/suggester.h @@ -0,0 +1,18 @@ +#ifndef SUGGESTER_H +#define SUGGESTER_H + +#include + +class Suggester : public QObject { + + Q_OBJECT + +public: + virtual void suggest(QString query) = 0; + +signals: + void ready(QStringList); + +}; + +#endif // SUGGESTER_H diff --git a/src/youtubesuggest.cpp b/src/youtubesuggest.cpp new file mode 100644 index 0000000..c1965ca --- /dev/null +++ b/src/youtubesuggest.cpp @@ -0,0 +1,42 @@ +#include "youtubesuggest.h" +#include +#include "networkaccess.h" + +#define GSUGGEST_URL "http://suggestqueries.google.com/complete/search?ds=yt&output=toolbar&hl=%1&q=%2" + +namespace The { + NetworkAccess* http(); +} + +YouTubeSuggest::YouTubeSuggest(QObject *parent) : Suggester() { + +} + +void YouTubeSuggest::suggest(QString query) { + QString locale = QLocale::system().name().replace("_", "-"); + // case for system locales such as "C" + if (locale.length() < 2) { + locale = "en-US"; + } + + QString url = QString(GSUGGEST_URL).arg(locale, query); + + QObject *reply = The::http()->get(url); + connect(reply, SIGNAL(data(QByteArray)), SLOT(handleNetworkData(QByteArray))); +} + +void YouTubeSuggest::handleNetworkData(QByteArray response) { + QStringList choices; + + QXmlStreamReader xml(response); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.tokenType() == QXmlStreamReader::StartElement) { + if (xml.name() == "suggestion") { + QStringRef str = xml.attributes().value("data"); + choices << str.toString(); + } + } + } + emit ready(choices); +} diff --git a/src/youtubesuggest.h b/src/youtubesuggest.h new file mode 100644 index 0000000..2d2221e --- /dev/null +++ b/src/youtubesuggest.h @@ -0,0 +1,24 @@ +#ifndef YOUTUBESUGGEST_H +#define YOUTUBESUGGEST_H + +#include + +#include "suggester.h" + +class YouTubeSuggest : public Suggester { + + Q_OBJECT + +public: + YouTubeSuggest(QObject *parent = 0); + void suggest(QString query); + +signals: + void ready(QStringList); + +private slots: + void handleNetworkData(QByteArray response); + +}; + +#endif // YOUTUBESUGGEST_H