#ifndef SPOTIFYSERVICE_H #define SPOTIFYSERVICE_H #include "internetmodel.h" #include "internetservice.h" #include "spotifymessages.pb.h" #include #include class Playlist; class SearchBoxWidget; class SpotifyServer; class QMenu; class SpotifyService : public InternetService { Q_OBJECT public: SpotifyService(Application* app, InternetModel* parent); ~SpotifyService(); enum Type { Type_SearchResults = InternetModel::TypeCount, Type_StarredPlaylist, Type_InboxPlaylist, Type_Toplist, }; enum Role { Role_UserPlaylistIndex = InternetModel::RoleCount, Role_UserPlaylistIsMine, // Is this playlist owned by the user currently logged-in? }; // Values are persisted - don't change. enum LoginState { LoginState_LoggedIn = 1, LoginState_Banned = 2, LoginState_BadCredentials = 3, LoginState_NoPremium = 4, LoginState_OtherError = 5, LoginState_ReloginFailed = 6 }; static const char* kServiceName; static const char* kSettingsGroup; static const char* kBlobDownloadUrl; static const int kSearchDelayMsec; void ReloadSettings(); QStandardItem* CreateRootItem(); void LazyPopulate(QStandardItem* parent); void ShowContextMenu(const QPoint& global_pos); void ItemDoubleClicked(QStandardItem* item); void DropMimeData(const QMimeData* data, const QModelIndex& index); QList playlistitem_actions(const Song& song) override; QWidget* HeaderWidget() const; void Logout(); void Login(const QString& username, const QString& password); Q_INVOKABLE void LoadImage(const QString& id); Q_INVOKABLE void SetPaused(bool paused); Q_INVOKABLE void Seek(qint64 offset_nsec); SpotifyServer* server() const; bool IsBlobInstalled() const; void InstallBlob(); // Persisted in the settings and updated on each Login(). LoginState login_state() const { return login_state_; } bool IsLoggedIn() const { return login_state_ == LoginState_LoggedIn; } static void SongFromProtobuf(const pb::spotify::Track& track, Song* song); signals: void BlobStateChanged(); void LoginFinished(bool success); void ImageLoaded(const QString& id, const QImage& image); public slots: void Search(const QString& text, bool now = false); void ShowConfig(); void RemoveCurrentFromPlaylist(); private: void StartBlobProcess(); void FillPlaylist( QStandardItem* item, const google::protobuf::RepeatedPtrField& tracks); void FillPlaylist(QStandardItem* item, const pb::spotify::LoadPlaylistResponse& response); void AddSongsToPlaylist(int playlist_index, const QList& songs_urls); void EnsureMenuCreated(); // Create a new "show config" action. The caller is responsible for deleting // the pointer (or adding it to menu or anything else that will take ownership // of it) QAction* GetNewShowConfigAction(); void ClearSearchResults(); QStandardItem* PlaylistBySpotifyIndex(int index) const; bool DoPlaylistsDiffer(const pb::spotify::Playlists& response) const; private slots: void EnsureServerCreated(const QString& username = QString(), const QString& password = QString()); void BlobProcessError(QProcess::ProcessError error); void LoginCompleted(bool success, const QString& error, pb::spotify::LoginResponse_Error error_code); void AddCurrentSongToPlaylist(QAction* action); void RemoveSongsFromPlaylist(int playlist_index, const QList& songs_indices_to_remove); void PlaylistsUpdated(const pb::spotify::Playlists& response); void InboxLoaded(const pb::spotify::LoadPlaylistResponse& response); void StarredLoaded(const pb::spotify::LoadPlaylistResponse& response); void UserPlaylistLoaded(const pb::spotify::LoadPlaylistResponse& response); void SearchResults(const pb::spotify::SearchResponse& response); void SyncPlaylistProgress(const pb::spotify::SyncPlaylistProgress& progress); void ToplistLoaded(const pb::spotify::BrowseToplistResponse& response); void DoSearch(); void SyncPlaylist(); void BlobDownloadFinished(); private: SpotifyServer* server_; QString system_blob_path_; QString local_blob_version_; QString local_blob_path_; QProcess* blob_process_; QStandardItem* root_; QStandardItem* search_; QStandardItem* starred_; QStandardItem* inbox_; QStandardItem* toplist_; QList playlists_; int login_task_id_; QString pending_search_; QMenu* context_menu_; QMenu* playlist_context_menu_; QMenu* song_context_menu_; QAction* playlist_sync_action_; QList playlistitem_actions_; QAction* remove_from_playlist_; QUrl current_song_url_; SearchBoxWidget* search_box_; QTimer* search_delay_; int inbox_sync_id_; int starred_sync_id_; QMap playlist_sync_ids_; LoginState login_state_; pb::spotify::Bitrate bitrate_; bool volume_normalisation_; }; #endif