From 3c0ca1405ca6d5c7c4d0bc14eadad32f56f29150 Mon Sep 17 00:00:00 2001 From: Flavio Date: Wed, 25 Jul 2012 16:25:12 +0200 Subject: [PATCH] Search spell suggestions --- src/ListModel.cpp | 4 ++++ src/ListModel.h | 1 + src/MainWindow.h | 2 +- src/MediaView.cpp | 5 +++++ src/sidebarwidget.cpp | 43 +++++++++++++++++++++++++++++++++++++ src/sidebarwidget.h | 6 ++++++ src/youtubesearch.cpp | 5 +++++ src/youtubesearch.h | 2 ++ src/youtubestreamreader.cpp | 9 ++++++++ src/youtubestreamreader.h | 2 ++ 10 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/ListModel.cpp b/src/ListModel.cpp index 468435f..851c152 100644 --- a/src/ListModel.cpp +++ b/src/ListModel.cpp @@ -197,6 +197,10 @@ void ListModel::searchFinished(int total) { // update the message item emit dataChanged( createIndex( MAX_ITEMS, 0 ), createIndex( MAX_ITEMS, columnCount() - 1 ) ); + + if (!youtubeSearch->getSuggestions().isEmpty()) { + emit haveSuggestions(youtubeSearch->getSuggestions()); + } } void ListModel::searchError(QString message) { diff --git a/src/ListModel.h b/src/ListModel.h index 2752aab..f9d424b 100644 --- a/src/ListModel.h +++ b/src/ListModel.h @@ -84,6 +84,7 @@ public slots: signals: void activeRowChanged(int); void needSelectionFor(QList); + void haveSuggestions(const QStringList &suggestions); private: void searchMore(int max); diff --git a/src/MainWindow.h b/src/MainWindow.h index 6710e2c..713422d 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -32,6 +32,7 @@ public slots: void restore(); void messageReceived(const QString &message); void quit(); + void startToolbarSearch(QString query); protected: void changeEvent(QEvent *); @@ -78,7 +79,6 @@ private slots: void downloadsFinished(); void toggleDownloads(bool show); - void startToolbarSearch(QString query); void floatOnTop(bool); void showActionInStatusBar(QAction*, bool show); void showStopAfterThisInStatusBar(bool show); diff --git a/src/MediaView.cpp b/src/MediaView.cpp index f4ef727..8ad65ba 100644 --- a/src/MediaView.cpp +++ b/src/MediaView.cpp @@ -71,6 +71,10 @@ MediaView::MediaView(QWidget *parent) : QWidget(parent) { sidebar->setPlaylist(listView); connect(sidebar->getRefineSearchWidget(), SIGNAL(searchRefined()), SLOT(searchAgain())); + connect(listModel, SIGNAL(haveSuggestions(const QStringList &)), + sidebar, SLOT(showSuggestions(const QStringList &))); + connect(sidebar, SIGNAL(suggestionAccepted(QString)), + MainWindow::instance(), SLOT(startToolbarSearch(QString))); splitter->addWidget(sidebar); videoAreaWidget = new VideoAreaWidget(this); @@ -172,6 +176,7 @@ void MediaView::search(SearchParams *searchParams) { } sidebar->getRefineSearchWidget()->setSearchParams(searchParams); + sidebar->hideSuggestions(); } void MediaView::searchAgain() { diff --git a/src/sidebarwidget.cpp b/src/sidebarwidget.cpp index 6717e30..ceae150 100644 --- a/src/sidebarwidget.cpp +++ b/src/sidebarwidget.cpp @@ -14,8 +14,25 @@ SidebarWidget::SidebarWidget(QWidget *parent) : playlist = 0; QBoxLayout *layout = new QVBoxLayout(this); + layout->setSpacing(1); layout->setMargin(0); + // hidden message widget + messageLabel = new QLabel(this); + messageLabel->setMargin(10); + messageLabel->setBackgroundRole(QPalette::ToolTipBase); + messageLabel->setForegroundRole(QPalette::ToolTipText); + messageLabel->setAutoFillBackground(true); + messageLabel->setWordWrap(true); + messageLabel->setTextFormat(Qt::RichText); + messageLabel->setTextInteractionFlags( + Qt::LinksAccessibleByKeyboard | + Qt::LinksAccessibleByMouse); + connect(messageLabel, SIGNAL(linkActivated(QString)), + SIGNAL(suggestionAccepted(QString))); + messageLabel->hide(); + layout->addWidget(messageLabel); + stackedWidget = new QStackedWidget(this); layout->addWidget(stackedWidget); @@ -119,3 +136,29 @@ void SidebarWidget::showRefineSearchButton() { height() - refineSearchButton->minimumHeight()); refineSearchButton->show(); } + +void SidebarWidget::showSuggestions(const QStringList &suggestions) { + QString message = tr("Did you mean: %1"); + + QString suggestionLinks; + foreach (QString suggestion, suggestions) { + suggestionLinks += "" + suggestion + " "; + } + message = message.arg(suggestionLinks); + + QString html = + "" + "" + "%1" + ""; + html = html.arg(message); + messageLabel->setText(html); + messageLabel->show(); +} + +void SidebarWidget::hideSuggestions() { + messageLabel->hide(); + messageLabel->clear(); +} diff --git a/src/sidebarwidget.h b/src/sidebarwidget.h index e861299..5edb56f 100644 --- a/src/sidebarwidget.h +++ b/src/sidebarwidget.h @@ -15,11 +15,16 @@ public: void setPlaylist(QListView *playlist); void showPlaylist(); RefineSearchWidget* getRefineSearchWidget() { return refineSearchWidget; } + void hideSuggestions(); public slots: void showRefineSearchWidget(); void hideRefineSearchWidget(); void toggleRefineSearch(bool show = false); + void showSuggestions(const QStringList &suggestions); + +signals: + void suggestionAccepted(QString); protected: void resizeEvent(QResizeEvent *); @@ -38,6 +43,7 @@ private: QListView *playlist; RefineSearchWidget *refineSearchWidget; QTimer *mouseTimer; + QLabel *messageLabel; }; diff --git a/src/youtubesearch.cpp b/src/youtubesearch.cpp index 67eee08..3263525 100644 --- a/src/youtubesearch.cpp +++ b/src/youtubesearch.cpp @@ -87,6 +87,7 @@ void YouTubeSearch::parseResults(QByteArray data) { qDebug() << "Error parsing XML"; } videos = reader.getVideos(); + suggestions = reader.getSuggestions(); foreach (Video *video, videos) { // send it to the model @@ -106,6 +107,10 @@ QList YouTubeSearch::getResults() { return videos; } +const QStringList & YouTubeSearch::getSuggestions() const { + return suggestions; +} + void YouTubeSearch::abort() { this->abortFlag = true; } diff --git a/src/youtubesearch.h b/src/youtubesearch.h index 4a094e0..254ea02 100644 --- a/src/youtubesearch.h +++ b/src/youtubesearch.h @@ -13,6 +13,7 @@ public: void search(SearchParams *searchParams, int max, int skip); void abort(); QList getResults(); + const QStringList & getSuggestions() const; static QString videoIdFromUrl(QString url); signals: @@ -27,6 +28,7 @@ private slots: private: QList videos; + QStringList suggestions; bool abortFlag; diff --git a/src/youtubestreamreader.cpp b/src/youtubestreamreader.cpp index c7e54ef..9869da7 100644 --- a/src/youtubestreamreader.cpp +++ b/src/youtubestreamreader.cpp @@ -17,6 +17,10 @@ bool YouTubeStreamReader::read(QByteArray data) { readNext(); if (isStartElement() && name() == "entry") { readEntry(); + } else if (name() == "link" + && attributes().value("rel").toString() + == "http://schemas.google.com/g/2006#spellcorrection") { + suggestions << attributes().value("title").toString(); } } } @@ -55,6 +59,7 @@ void YouTubeStreamReader::readEntry() { webpage.remove("&feature=youtube_gdata"); // qDebug() << "Webpage: " << webpage; video->setWebpage(QUrl(webpage)); + } else if (name() == "author") { readNext(); if (name() == "name") { @@ -110,3 +115,7 @@ void YouTubeStreamReader::readEntry() { QList YouTubeStreamReader::getVideos() { return videos; } + +const QStringList & YouTubeStreamReader::getSuggestions() const { + return suggestions; +} diff --git a/src/youtubestreamreader.h b/src/youtubestreamreader.h index 4cd3894..8c8c617 100644 --- a/src/youtubestreamreader.h +++ b/src/youtubestreamreader.h @@ -11,11 +11,13 @@ public: YouTubeStreamReader(); bool read(QByteArray data); QList getVideos(); + const QStringList & getSuggestions() const; private: void readMediaGroup(); void readEntry(); QList videos; + QStringList suggestions; }; #endif // YOUTUBESTREAMREADER_H -- 2.39.5