/* This file is part of Clementine. Copyright 2014, Vlad Maltsev Copyright 2014, Krzysztof Sobiecki Copyright 2014, Ivan Leontiev Clementine is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Clementine is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Clementine. If not, see . */ #ifndef INTERNET_VK_VKSERVICE_H_ #define INTERNET_VK_VKSERVICE_H_ #include #include "internet/core/internetservice.h" #include "internet/core/internetmodel.h" #include "core/song.h" #include "vreen/audio.h" #include "vreen/contact.h" #include "vkconnection.h" #include "vkurlhandler.h" namespace Vreen { class Client; class Buddy; } class SearchBoxWidget; class VkMusicCache; class VkSearchDialog; /*** * Store information about user or group * using in bookmarks. */ class MusicOwner { public: MusicOwner() : songs_count_(0), id_(0) {} explicit MusicOwner(const QUrl& group_url); Song toOwnerRadio() const; QString name() const { return name_; } int id() const { return id_; } int song_count() const { return songs_count_; } static QList parseMusicOwnerList(const QVariant& request_result); // quick and dirty solution for creating MusicOwner instance for // logged in user void setId(int id) { id_ = id; } private: friend QDataStream& operator<<(QDataStream& stream, const MusicOwner& val); friend QDataStream& operator>>(QDataStream& stream, MusicOwner& val); friend QDebug operator<<(QDebug d, const MusicOwner& owner); int songs_count_; int id_; // if id > 0 is user otherwise id group QString name_; // name used in url http://vk.com/ for example: // http://vk.com/shedward QString screen_name_; QUrl photo_; }; typedef QList MusicOwnerList; Q_DECLARE_METATYPE(MusicOwner) QDataStream& operator<<(QDataStream& stream, const MusicOwner& val); QDataStream& operator>>(QDataStream& stream, MusicOwner& var); QDebug operator<<(QDebug d, const MusicOwner& owner); /*** * The simple structure allows the handler to determine * how to react to the received request or quickly skip unwanted. */ struct SearchID { enum Type { GlobalSearch, LocalSearch, MoreLocalSearch, UserOrGroup }; explicit SearchID(Type type) : type_(type) { id_ = last_id_++; } int id() const { return id_; } Type type() const { return type_; } private: static uint last_id_; int id_; Type type_; }; /*** * VkService */ class VkService : public InternetService { Q_OBJECT public: explicit VkService(Application* app, InternetModel* parent); ~VkService(); static const char* kServiceName; static const char* kSettingGroup; static const char* kUrlScheme; static const char* kDefCacheFilename; static QString DefaultCacheDir(); static const int kMaxVkSongList; static const int kMaxVkWallPostList; static const int kMaxVkSongCount; static const int kSearchDelayMsec; enum ItemType { Type_Loading = InternetModel::TypeCount, Type_More, Type_Recommendations, Type_Music, Type_Bookmark, Type_Album, Type_Wall, Type_AlbumList, Type_Search }; enum Role { Role_MusicOwnerMetadata = InternetModel::RoleCount, Role_AlbumMetadata, Role_MoreMetadata }; Application* app() const { return app_; } /* InternetService interface */ QStandardItem* CreateRootItem(); void LazyPopulate(QStandardItem* parent); void ShowContextMenu(const QPoint& global_pos); void ItemDoubleClicked(QStandardItem* item); QList playlistitem_actions(const Song& song); /* Interface*/ QWidget* HeaderWidget() const; /* Connection */ void Login(); void Logout(); bool HasAccount() const; int UserID() const; void RequestUserProfile(); bool WaitForReply(Vreen::Reply* reply); /* Music */ void SongStarting(const Song& song); void SongStarting(const QUrl& url); // Used if song taked from cache. void SongSkipped(); UrlHandler::LoadResult GetSongResult(const QUrl& url); Vreen::AudioItem GetAudioItemFromUrl(const QUrl& url); // Return random song result from group playlist. UrlHandler::LoadResult GetGroupNextSongUrl(const QUrl& url); void SongSearch(SearchID id, const QString& query, int count = kMaxVkSongCount, int offset = 0); void GroupSearch(SearchID id, const QString& query); /* Settings */ void ReloadSettings(); int maxGlobalSearch() const { return maxGlobalSearch_; } bool isCachingEnabled() const { return cachingEnabled_; } bool isGroupsInGlobalSearch() const { return groups_in_global_search_; } bool isBroadcasting() const { return enable_broadcast_; } QString cacheDir() const { return cacheDir_; } QString cacheFilename() const { return cacheFilename_; } bool isLoveAddToMyMusic() const { return love_is_add_to_mymusic_; } signals: void NameUpdated(const QString& name); void ConnectionStateChanged(Vreen::Client::State state); void LoginSuccess(bool success); void SongSearchResult(const SearchID& id, const SongList& songs); void GroupSearchResult(const SearchID& id, const MusicOwnerList& groups); void UserOrGroupSearchResult(const SearchID& id, const MusicOwnerList& owners); void StopWaiting(); public slots: void UpdateRoot(); void ShowConfig(); void FindUserOrGroup(const QString& q); void DoLocalSearch(); private slots: /* Interface */ void UpdateItem(); /* Connection */ void ChangeConnectionState(Vreen::Client::State state); void UserProfileRecived(const QVariant& result); void Error(Vreen::Client::Error error); /* Music */ void SongStopped(); void UpdateMusic(QStandardItem* item); void UpdateAlbumList(QStandardItem* item); void UpdateAlbumSongs(QStandardItem* item); void UpdateWallSongs(QStandardItem* item); void MoreWallSongs(QStandardItem* item); void FindSongs(const QString& query); void FindMore(); void UpdateRecommendations(); void MoreRecommendations(); void FindThisArtist(); void AddToMyMusic(); void AddToMyMusicCurrent(); void RemoveFromMyMusic(); void AddSelectedToCache(); void CopyShareUrl(); void ShowSearchDialog(); void AddSelectedToBookmarks(); void RemoveFromBookmark(); void SongSearchReceived(const SearchID& id, Vreen::AudioItemListReply* reply); void GroupSearchReceived(const SearchID& id, Vreen::Reply* reply); void UserOrGroupReceived(const SearchID& id, Vreen::Reply* reply); void AlbumListReceived(QStandardItem* parent, Vreen::AudioAlbumItemListReply* reply); void BroadcastChangeReceived(Vreen::IntReply* reply); void AppendLoadedSongs(QStandardItem* item, Vreen::AudioItemListReply* reply); void RecommendationsLoaded(Vreen::AudioItemListReply* reply); void SearchResultLoaded(const SearchID& id, const SongList& songs); void WallPostsLoaded(QStandardItem* item, Vreen::Reply* reply, int offset); private: bool isItemBusy(const QStandardItem* item); int TypeOfItem(const QStandardItem* item); Vreen::AudioItemList handleWallPosts(const QVariant& response); /* Interface */ QStandardItem* CreateAndAppendRow(QStandardItem* parent, VkService::ItemType type); void ClearStandardItem(QStandardItem* item); QStandardItem* GetBookmarkItemById(int id); void EnsureMenuCreated(); /* Music */ void LoadAndAppendSongList(QStandardItem* item, int uid, int album_id = -1); void LoadAndAppendWallSongList(QStandardItem* item, const MusicOwner& owner, int offset = 0); Song FromAudioItem(const Vreen::AudioItem& item); SongList FromAudioList(const Vreen::AudioItemList& list); void AppendSongs(QStandardItem* parent, const SongList& songs); QStandardItem* AppendBookmark(const MusicOwner& owner); void SaveBookmarks(); void LoadBookmarks(); void LoadAlbums(QStandardItem* parent, const MusicOwner& owner); QStandardItem* AppendAlbum(QStandardItem* parent, const Vreen::AudioAlbumItem& album); QStandardItem* AppendAlbumList(QStandardItem* parent, bool myself = false); QStandardItem* AppendWall(QStandardItem* parent); QStandardItem* AppendMusic(QStandardItem* parent, bool myself = false); /* Interface */ QStandardItem* root_item_; QStandardItem* recommendations_item_; QStandardItem* my_music_item_; QStandardItem* my_albums_item_; QStandardItem* search_result_item_; QMenu* context_menu_; QAction* update_item_; QAction* find_this_artist_; QAction* add_to_my_music_; QAction* remove_from_my_music_; QAction* add_song_to_cache_; QAction* copy_share_url_; QAction* add_to_bookmarks_; QAction* remove_from_bookmarks_; QAction* find_owner_; SearchBoxWidget* search_box_; VkSearchDialog* vk_search_dialog_; /* Connection */ std::unique_ptr client_; std::unique_ptr connection_; VkUrlHandler* url_handler_; /* Music */ std::unique_ptr audio_provider_; VkMusicCache* cache_; // Keeping when more recent results recived. // Using for prevent loading tardy result instead. uint last_search_id_; QTimer* search_delay_; QString last_query_; Song selected_song_; // Store for context menu actions. Song current_song_; // Store for actions with now playing song. // Store current group url for actions with it. QUrl current_group_url_; /* Settings */ int maxGlobalSearch_; bool cachingEnabled_; bool love_is_add_to_mymusic_; bool groups_in_global_search_; bool enable_broadcast_; QString cacheDir_; QString cacheFilename_; }; #endif // INTERNET_VK_VKSERVICE_H_