Search on Spotify on the left/Internet tab directly, instead of Spotify magic playlist (like for Grooveshark)

- Next step: fix the "did you mean" widget which is visible to user when displayed
This commit is contained in:
Arnaud Bienner 2012-06-28 23:57:51 +02:00
parent abe8d10b9c
commit 70429217c6
5 changed files with 62 additions and 23 deletions

View File

@ -19,6 +19,7 @@
#include "searchboxwidget.h"
#include "ui_searchboxwidget.h"
#include "ui/iconloader.h"
#include "widgets/didyoumean.h"
#include <QKeyEvent>
#include <QMenu>
@ -43,6 +44,13 @@ SearchBoxWidget::SearchBoxWidget(InternetService* service)
ui_->filter->setPlaceholderText(QString("Search on %1").arg(service_->name()));
connect(ui_->filter, SIGNAL(textChanged(QString)), SIGNAL(TextChanged(QString)));
// FIXME: the "Did you mean" suggestion is displayed above the search box,
// but below the internet services tree, which makes it fairly unusuable for
// now :(
did_you_mean_ = new DidYouMean(ui_->filter, this);
connect(did_you_mean_, SIGNAL(Accepted(QString)),
ui_->filter, SLOT(setText(QString)));
}
SearchBoxWidget::~SearchBoxWidget() {

View File

@ -21,6 +21,7 @@
#include <QWidget>
class InternetService;
class DidYouMean;
class Ui_SearchBoxWidget;
class QActionGroup;
@ -33,6 +34,8 @@ public:
SearchBoxWidget(InternetService* service);
~SearchBoxWidget();
DidYouMean* did_you_mean() { return did_you_mean_; }
signals:
void TextChanged(const QString& text);
@ -46,6 +49,7 @@ private:
InternetService* service_;
Ui_SearchBoxWidget* ui_;
QMenu* menu_;
DidYouMean* did_you_mean_;
};
#endif // SEARCHBOXWIDGET_H

View File

@ -45,5 +45,7 @@ void SpotifySearchPlaylistType::Search(const QString& text, Playlist* playlist)
}
void SpotifySearchPlaylistType::DidYouMeanClicked(const QString& text, Playlist* playlist) {
service_->Search(text, playlist, true);
// TODO Dead-code now: we will probably remove the entire class later, if the
// new search looks pretty enough for everyone
//service_->Search(text, playlist, true);
}

View File

@ -8,6 +8,7 @@
#include "core/application.h"
#include "core/database.h"
#include "core/logging.h"
#include "core/mergedproxymodel.h"
#include "core/player.h"
#include "core/taskmanager.h"
#include "core/timeconstants.h"
@ -17,8 +18,10 @@
#include "playlist/playlist.h"
#include "playlist/playlistcontainer.h"
#include "playlist/playlistmanager.h"
#include "searchboxwidget.h"
#include "widgets/didyoumean.h"
#include "ui/iconloader.h"
#include "widgets/didyoumean.h"
#include <QCoreApplication>
#include <QFile>
@ -47,8 +50,8 @@ SpotifyService::SpotifyService(Application* app, InternetModel* parent)
inbox_(NULL),
toplist_(NULL),
login_task_id_(0),
pending_search_playlist_(NULL),
context_menu_(NULL),
search_box_(new SearchBoxWidget(this)),
search_delay_(new QTimer(this)),
login_state_(LoginState_OtherError),
bitrate_(pb::spotify::Bitrate320k),
@ -80,6 +83,7 @@ SpotifyService::SpotifyService(Application* app, InternetModel* parent)
search_delay_->setInterval(kSearchDelayMsec);
search_delay_->setSingleShot(true);
connect(search_delay_, SIGNAL(timeout()), SLOT(DoSearch()));
connect(search_box_, SIGNAL(TextChanged(QString)), SLOT(Search(QString)));
}
SpotifyService::~SpotifyService() {
@ -340,7 +344,9 @@ void SpotifyService::PlaylistsUpdated(const pb::spotify::Playlists& response) {
// Create starred and inbox playlists if they're not here already
if (!search_) {
search_ = new QStandardItem(IconLoader::Load("edit-find"),
tr("Search Spotify (opens a new tab)"));
tr("Search results"));
search_->setToolTip(tr("Start typing something on the search box above to "
"fill this search results list"));
search_->setData(Type_SearchResults, InternetModel::Role_Type);
search_->setData(InternetModel::PlayBehaviour_DoubleClickAction,
InternetModel::Role_PlayBehaviour);
@ -494,6 +500,10 @@ PlaylistItem::Options SpotifyService::playlistitem_options() const {
return PlaylistItem::PauseDisabled | PlaylistItem::SeekDisabled;
}
QWidget* SpotifyService::HeaderWidget() const {
return search_box_;
}
void SpotifyService::EnsureMenuCreated() {
if (context_menu_)
return;
@ -502,8 +512,6 @@ void SpotifyService::EnsureMenuCreated() {
context_menu_->addActions(GetPlaylistActions());
context_menu_->addSeparator();
context_menu_->addAction(IconLoader::Load("edit-find"), tr("Search Spotify (opens a new tab)..."), this, SLOT(OpenSearchTab()));
context_menu_->addSeparator();
context_menu_->addAction(IconLoader::Load("configure"), tr("Configure Spotify..."), this, SLOT(ShowConfig()));
playlist_context_menu_ = new QMenu;
@ -514,6 +522,11 @@ void SpotifyService::EnsureMenuCreated() {
SLOT(SyncPlaylist()));
}
void SpotifyService::ClearSearchResults() {
if (search_)
search_->removeRows(0, search_->rowCount());
}
void SpotifyService::SyncPlaylist() {
QStandardItem* item = playlist_sync_action_->data().value<QStandardItem*>();
Q_ASSERT(item);
@ -539,11 +552,18 @@ void SpotifyService::SyncPlaylist() {
}
}
void SpotifyService::Search(const QString& text, Playlist* playlist, bool now) {
void SpotifyService::Search(const QString& text, bool now) {
EnsureServerCreated();
pending_search_ = text;
pending_search_playlist_ = playlist;
// If there is no text (e.g. user cleared search box), we don't need to do a
// real query that will return nothing: we can clear the playlist now
if (text.isEmpty()) {
search_delay_->stop();
ClearSearchResults();
return;
}
if (now) {
search_delay_->stop();
@ -577,13 +597,22 @@ void SpotifyService::SearchResults(const pb::spotify::SearchResponse& response)
qLog(Debug) << "Got" << songs.count() << "results";
pending_search_playlist_->Clear();
pending_search_playlist_->InsertSongs(songs);
ClearSearchResults();
const QString did_you_mean = QStringFromStdString(response.did_you_mean());
if (!did_you_mean.isEmpty()) {
app_->playlist_manager()->playlist_container()->did_you_mean()->Show(did_you_mean);
// Fill results list
foreach(const Song& song, songs) {
QStandardItem* child = CreateSongItem(song);
search_->appendRow(child);
}
const QString did_you_mean_suggestion = QStringFromStdString(response.did_you_mean());
qLog(Debug) << "Did you mean suggestion: " << did_you_mean_suggestion;
if (!did_you_mean_suggestion.isEmpty()) {
search_box_->did_you_mean()->Show(did_you_mean_suggestion);
}
QModelIndex index = model()->merged_model()->mapFromSource(search_->index());
ScrollToIndex(index);
}
SpotifyServer* SpotifyService::server() const {
@ -616,15 +645,7 @@ void SpotifyService::ShowContextMenu(const QPoint& global_pos) {
context_menu_->popup(global_pos);
}
void SpotifyService::OpenSearchTab() {
app_->playlist_manager()->New(tr("Search Spotify"), SongList(),
SpotifySearchPlaylistType::kName);
}
void SpotifyService::ItemDoubleClicked(QStandardItem* item) {
if (item == search_) {
OpenSearchTab();
}
}
void SpotifyService::DropMimeData(const QMimeData* data, const QModelIndex& index) {

View File

@ -10,7 +10,9 @@
#include <boost/shared_ptr.hpp>
class DidYouMean;
class Playlist;
class SearchBoxWidget;
class SpotifyServer;
class QMenu;
@ -57,10 +59,10 @@ public:
void ItemDoubleClicked(QStandardItem* item);
void DropMimeData(const QMimeData* data, const QModelIndex& index);
PlaylistItem::Options playlistitem_options() const;
QWidget* HeaderWidget() const;
void Logout();
void Login(const QString& username, const QString& password);
void Search(const QString& text, Playlist* playlist, bool now = false);
Q_INVOKABLE void LoadImage(const QString& id);
SpotifyServer* server() const;
@ -80,6 +82,7 @@ signals:
void ImageLoaded(const QString& id, const QImage& image);
public slots:
void Search(const QString& text, bool now = false);
void ShowConfig();
private:
@ -89,6 +92,7 @@ private:
const google::protobuf::RepeatedPtrField<pb::spotify::Track>& tracks);
void FillPlaylist(QStandardItem* item, const pb::spotify::LoadPlaylistResponse& response);
void EnsureMenuCreated();
void ClearSearchResults();
QStandardItem* PlaylistBySpotifyIndex(int index) const;
bool DoPlaylistsDiffer(const pb::spotify::Playlists& response) const;
@ -107,7 +111,6 @@ private slots:
void SyncPlaylistProgress(const pb::spotify::SyncPlaylistProgress& progress);
void ToplistLoaded(const pb::spotify::BrowseToplistResponse& response);
void OpenSearchTab();
void DoSearch();
void SyncPlaylist();
@ -130,12 +133,13 @@ private:
int login_task_id_;
QString pending_search_;
Playlist* pending_search_playlist_;
QMenu* context_menu_;
QMenu* playlist_context_menu_;
QAction* playlist_sync_action_;
SearchBoxWidget* search_box_;
QTimer* search_delay_;
int inbox_sync_id_;