From c43eb02efd7e0eb4e9710c3ece742b1aada4de13 Mon Sep 17 00:00:00 2001 From: Andreas Date: Tue, 21 Oct 2014 17:59:02 +0200 Subject: [PATCH] Android Remote: Add global search. --- .../remotecontrolmessages.proto | 17 ++++++- src/networkremote/incomingdataparser.cpp | 8 ++++ src/networkremote/incomingdataparser.h | 3 ++ src/networkremote/networkremote.cpp | 5 +++ src/networkremote/outgoingdatacreator.cpp | 44 +++++++++++++++++++ src/networkremote/outgoingdatacreator.h | 17 +++++++ 6 files changed, 93 insertions(+), 1 deletion(-) diff --git a/ext/libclementine-remote/remotecontrolmessages.proto b/ext/libclementine-remote/remotecontrolmessages.proto index 01dd57942..aad384bee 100644 --- a/ext/libclementine-remote/remotecontrolmessages.proto +++ b/ext/libclementine-remote/remotecontrolmessages.proto @@ -23,6 +23,7 @@ enum MsgType { STOP_AFTER = 17; GET_LIBRARY = 18; RATE_SONG = 19; + GLOBAL_SEARCH = 100; // Messages send by both DISCONNECT = 2; @@ -53,6 +54,7 @@ enum MsgType { DOWNLOAD_QUEUE_EMPTY = 51; LIBRARY_CHUNK = 52; DOWNLOAD_TOTAL_SIZE = 53; + GLOBAL_SEARCH_RESULT = 54; } // Valid Engine states @@ -284,9 +286,20 @@ message ResponseDownloadTotalSize { optional int32 file_count = 2; } +message RequestGlobalSearch { + optional string query = 1; +} + +message ResponseGlobalSearch { + optional int32 id = 1; + optional string query = 2; + optional string search_provider = 3; + repeated SongMetadata song_metadata = 4; +} + // The message itself message Message { - optional int32 version = 1 [default=16]; + optional int32 version = 1 [default=17]; optional MsgType type = 2 [default=UNKNOWN]; // What data is in the message? optional RequestConnect request_connect = 21; @@ -301,6 +314,7 @@ message Message { optional RequestClosePlaylist request_close_playlist = 29; optional RequestDownloadSongs request_download_songs = 31; optional RequestRateSong request_rate_song = 35; + optional RequestGlobalSearch request_global_search = 37; optional Repeat repeat = 13; optional Shuffle shuffle = 14; @@ -318,4 +332,5 @@ message Message { optional ResponseSongOffer response_song_offer = 33; optional ResponseLibraryChunk response_library_chunk = 34; optional ResponseDownloadTotalSize response_download_total_size = 36; + optional ResponseGlobalSearch response_global_search = 38; } diff --git a/src/networkremote/incomingdataparser.cpp b/src/networkremote/incomingdataparser.cpp index 8cc9a0b66..d78832746 100644 --- a/src/networkremote/incomingdataparser.cpp +++ b/src/networkremote/incomingdataparser.cpp @@ -169,6 +169,9 @@ void IncomingDataParser::Parse(const pb::remote::Message& msg) { case pb::remote::RATE_SONG: RateSong(msg); break; + case pb::remote::GLOBAL_SEARCH: + GlobalSearch(client, msg); + break; default: break; } @@ -291,3 +294,8 @@ void IncomingDataParser::RateSong(const pb::remote::Message& msg) { double rating = (double)msg.request_rate_song().rating(); emit RateCurrentSong(rating); } + +void IncomingDataParser::GlobalSearch(RemoteClient *client, const pb::remote::Message &msg) { + emit DoGlobalSearch(QStringFromStdString(msg.request_global_search().query()), + client); +} diff --git a/src/networkremote/incomingdataparser.h b/src/networkremote/incomingdataparser.h index 47cd4e94d..a3e23e070 100644 --- a/src/networkremote/incomingdataparser.h +++ b/src/networkremote/incomingdataparser.h @@ -52,6 +52,8 @@ signals: void SendLibrary(RemoteClient* client); void RateCurrentSong(double); + void DoGlobalSearch(QString, RemoteClient*); + private: Application* app_; bool close_connection_; @@ -67,6 +69,7 @@ signals: void OpenPlaylist(const pb::remote::Message& msg); void ClosePlaylist(const pb::remote::Message& msg); void RateSong(const pb::remote::Message& msg); + void GlobalSearch(RemoteClient* client, const pb::remote::Message& msg); }; #endif // INCOMINGDATAPARSER_H diff --git a/src/networkremote/networkremote.cpp b/src/networkremote/networkremote.cpp index 2f211d719..5dd628e78 100644 --- a/src/networkremote/networkremote.cpp +++ b/src/networkremote/networkremote.cpp @@ -169,6 +169,11 @@ void NetworkRemote::AcceptConnection() { connect(incoming_data_parser_.get(), SIGNAL(SendLibrary(RemoteClient*)), outgoing_data_creator_.get(), SLOT(SendLibrary(RemoteClient*))); + + connect(incoming_data_parser_.get(), + SIGNAL(DoGlobalSearch(QString, RemoteClient*)), + outgoing_data_creator_.get(), + SLOT(DoGlobalSearch(QString, RemoteClient*))); } QTcpServer* server = qobject_cast(sender()); diff --git a/src/networkremote/outgoingdatacreator.cpp b/src/networkremote/outgoingdatacreator.cpp index 3dac89eaf..83fdc99da 100644 --- a/src/networkremote/outgoingdatacreator.cpp +++ b/src/networkremote/outgoingdatacreator.cpp @@ -68,6 +68,16 @@ void OutgoingDataCreator::SetClients(QList* clients) { } CheckEnabledProviders(); + + // Setup global search + connect(app_->global_search(), + SIGNAL(ResultsAvailable(int, SearchProvider::ResultList)), + SLOT(ResultsAvailable(int, SearchProvider::ResultList)), + Qt::QueuedConnection); + + connect(app_->global_search(), + SIGNAL(SearchFinished(int)), + SLOT(SearchFinished(int))); } void OutgoingDataCreator::CheckEnabledProviders() { @@ -860,3 +870,37 @@ void OutgoingDataCreator::SendKitten(const QImage& kitten) { SendSongMetadata(); } } + +void OutgoingDataCreator::DoGlobalSearch(QString &query, RemoteClient *client) { + int id = app_->global_search()->SearchAsync(query); + + GlobalSearchRequest request(id, query, client); + global_search_result_map_.insert(id, request); +} + +void OutgoingDataCreator::ResultsAvailable(int id, SearchProvider::ResultList results) { + if (!global_search_result_map_.contains(id)) return; + + GlobalSearchRequest search_request = global_search_result_map_.value(id); + RemoteClient* client = search_request.client_; + QImage null_img; + + pb::remote::Message msg; + pb::remote::ResponseGlobalSearch* response = msg.mutable_response_global_search(); + + msg.set_type(pb::remote::GLOBAL_SEARCH_RESULT); + response->set_id(search_request.id_); + response->set_query(DataCommaSizeFromQString(search_request.query_)); + response->set_search_provider(DataCommaSizeFromQString(results.first().provider_->name())); + + for (const SearchProvider::Result& result : results) { + pb::remote::SongMetadata* pb_song = response->add_song_metadata(); + CreateSong(result.metadata_, null_img, 0, pb_song); + } + + client->SendData(&msg); +} + +void OutgoingDataCreator::SearchFinished(int id) { + global_search_result_map_.remove(id); +} diff --git a/src/networkremote/outgoingdatacreator.h b/src/networkremote/outgoingdatacreator.h index 05f89b292..c4bf2dc21 100644 --- a/src/networkremote/outgoingdatacreator.h +++ b/src/networkremote/outgoingdatacreator.h @@ -14,6 +14,7 @@ #include "core/application.h" #include "engines/enginebase.h" #include "engines/engine_fwd.h" +#include "globalsearch/globalsearch.h" #include "playlist/playlist.h" #include "playlist/playlistmanager.h" #include "playlist/playlistbackend.h" @@ -37,6 +38,16 @@ struct DownloadItem { : song_(s), song_no_(no), song_count_(count) {} }; +struct GlobalSearchRequest { + int id_; + QString query_; + RemoteClient* client_; + GlobalSearchRequest() + : id_(-1), query_(""), client_(nullptr) {} + GlobalSearchRequest(int i, QString q, RemoteClient* c) + : id_(i), query_(q), client_(c) {} +}; + class OutgoingDataCreator : public QObject { Q_OBJECT public: @@ -78,6 +89,10 @@ class OutgoingDataCreator : public QObject { void EnableKittens(bool aww); void SendKitten(const QImage& kitten); + void DoGlobalSearch(QString& query, RemoteClient* client); + void ResultsAvailable(int id, SearchProvider::ResultList results); + void SearchFinished(int id); + private: Application* app_; QList* clients_; @@ -97,6 +112,8 @@ class OutgoingDataCreator : public QObject { QMap results_; SongInfoFetcher* fetcher_; + QMap global_search_result_map_; + void SendDataToClients(pb::remote::Message* msg); void SetEngineState(pb::remote::ResponseClementineInfo* msg); void CreateSong(const Song& song, const QImage& art, const int index,