mirror of
https://github.com/clementine-player/Clementine
synced 2025-02-02 20:36:44 +01:00
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:
parent
abe8d10b9c
commit
70429217c6
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user