Add the ability to have custom actions for PlaylistItems, and InternetPlaylistItems (through services). Add 'add to playlists' actions for Grooveshark

This commit is contained in:
Arnaud Bienner 2011-11-06 16:12:44 +01:00
parent 7f7c1a398e
commit 89680a02f0
11 changed files with 679 additions and 642 deletions

View File

@ -265,7 +265,7 @@ void GroovesharkService::SearchSongsFinished() {
QVariantMap result = ExtractResult(reply);
SongList songs = ExtractSongs(result);
pending_search_playlist_->Clear();
pending_search_playlist_->InsertSongs(songs);
pending_search_playlist_->InsertInternetItems(this, songs);
}
void GroovesharkService::InitCountry() {
@ -710,6 +710,54 @@ void GroovesharkService::DropMimeData(const QMimeData* data, const QModelIndex&
}
}
QList<QAction*> GroovesharkService::playlistitem_actions(const Song& song) {
// Clear previous actions
while (!playlistitem_actions_.isEmpty()) {
QAction* action = playlistitem_actions_.takeFirst();
QMenu* menu = action->menu();
if (menu)
delete menu;
delete action;
}
// Create a 'add to favorites' action
QAction* add_to_favorites = new QAction(QIcon(":/last.fm/love.png"),
tr("Add to Grooveshark favorites"), this);
connect(add_to_favorites, SIGNAL(triggered()), SLOT(AddCurrentSongToUserFavorites()));
playlistitem_actions_.append(add_to_favorites);
// Create a menu with 'add to playlist' actions for each Grooveshark playlist
QAction* add_to_playlists = new QAction(IconLoader::Load("list-add"),
tr("Add to Grooveshark playlists"), this);
QMenu* playlists_menu = new QMenu();
foreach (PlaylistInfo playlist_info, playlists_.values()) {
QAction* add_to_playlist = new QAction(playlist_info.name_, this);
add_to_playlist->setData(playlist_info.id_);
playlists_menu->addAction(add_to_playlist);
}
connect(playlists_menu, SIGNAL(triggered(QAction*)), SLOT(AddCurrentSongToPlaylist(QAction*)));
add_to_playlists->setMenu(playlists_menu);
playlistitem_actions_.append(add_to_playlists);
// Keep in mind the current song id
current_song_id_ = ExtractSongId(song.url());
return playlistitem_actions_;
}
void GroovesharkService::AddCurrentSongToPlaylist(QAction* action) {
int playlist_id = action->data().toInt();
if (!playlists_.contains(playlist_id)) {
return;
}
// Get the current playlist's songs
PlaylistInfo playlist = playlists_[playlist_id];
QList<int> songs_ids = playlist.songs_ids_;
songs_ids << current_song_id_;
SetPlaylistSongs(playlist_id, songs_ids);
}
void GroovesharkService::SetPlaylistSongs(int playlist_id, const QList<int>& songs_ids) {
QList<Param> parameters;
@ -904,8 +952,8 @@ void GroovesharkService::SongRemovedFromFavorites(QNetworkReply* reply) {
}
QNetworkReply* GroovesharkService::CreateRequest(const QString& method_name, QList<Param> params,
bool need_authentication,
bool use_https) {
bool need_authentication,
bool use_https) {
QVariantMap request_params;
request_params.insert("method", method_name);

View File

@ -58,6 +58,7 @@ class GroovesharkService : public InternetService {
void ItemDoubleClicked(QStandardItem* item);
void DropMimeData(const QMimeData* data, const QModelIndex& index);
QList<QAction*> playlistitem_actions(const Song& song);
void ShowContextMenu(const QModelIndex& index, const QPoint& global_pos);
void Search(const QString& text, Playlist* playlist, bool now = false);
@ -134,6 +135,8 @@ class GroovesharkService : public InternetService {
void NewPlaylistCreated(QNetworkReply* reply, const QString& name);
void DeleteCurrentPlaylist();
void PlaylistDeleted(QNetworkReply* reply, int playlist_id);
void AddCurrentSongToUserFavorites() { AddUserFavoriteSong(current_song_id_); }
void AddCurrentSongToPlaylist(QAction* action);
void UserFavoriteSongAdded(QNetworkReply* reply);
void RemoveCurrentFromPlaylist();
void RemoveCurrentFromFavorites();
@ -192,11 +195,13 @@ class GroovesharkService : public InternetService {
QMenu* context_menu_;
QModelIndex context_item_;
int current_song_id_;
QAction* create_playlist_;
QAction* delete_playlist_;
QAction* remove_from_playlist_;
QAction* remove_from_favorites_;
QList<QAction*> playlistitem_actions_;
QTimer* search_delay_;
QNetworkReply* last_search_reply_;

View File

@ -103,3 +103,10 @@ PlaylistItem::Options InternetPlaylistItem::options() const {
return Default;
return s->playlistitem_options();
}
QList<QAction*> InternetPlaylistItem::actions() {
InternetService* s = service();
if (!s)
return QList<QAction*>();
return s->playlistitem_actions(metadata_);
}

View File

@ -32,6 +32,8 @@ class InternetPlaylistItem : public PlaylistItem {
Options options() const;
QList<QAction*> actions();
bool InitFromQuery(const SqlRow& query);
Song Metadata() const;

View File

@ -51,6 +51,8 @@ public:
virtual void DropMimeData(const QMimeData* data, const QModelIndex& index) {}
virtual PlaylistItem::Options playlistitem_options() const { return PlaylistItem::Default; }
// Redefine this function to add service' specific actions to the playlist item
virtual QList<QAction*> playlistitem_actions(const Song& song) { return QList<QAction*>(); }
virtual QWidget* HeaderWidget() const { return NULL; }

View File

@ -963,6 +963,17 @@ void Playlist::InsertInternetItems(const InternetModel* model,
InsertItems(playlist_items, pos, play_now, enqueue);
}
void Playlist::InsertInternetItems(InternetService* service,
const SongList& songs,
int pos, bool play_now, bool enqueue) {
PlaylistItemList playlist_items;
foreach (const Song& song, songs) {
playlist_items << shared_ptr<PlaylistItem>(new InternetPlaylistItem(service, song));
}
InsertItems(playlist_items, pos, play_now, enqueue);
}
void Playlist::UpdateItems(const SongList& songs) {
qLog(Debug) << "Updating playlist with new tracks' info";
foreach (const Song& song, songs) {

View File

@ -33,6 +33,7 @@ class PlaylistBackend;
class PlaylistFilter;
class Queue;
class InternetModel;
class InternetService;
class TaskManager;
class QSortFilterProxyModel;
@ -214,6 +215,8 @@ class Playlist : public QAbstractListModel {
void InsertSongsOrLibraryItems(const SongList& items, int pos = -1, bool play_now = false, bool enqueue = false);
void InsertSmartPlaylist (smart_playlists::GeneratorPtr gen, int pos = -1, bool play_now = false, bool enqueue = false);
void InsertUrls (const QList<QUrl>& urls, int pos = -1, bool play_now = false, bool enqueue = false);
void InsertInternetItems (InternetService* service,
const SongList& songs, int pos = -1, bool play_now = false, bool enqueue = false);
// Removes items with given indices from the playlist. This operation is not undoable.
void RemoveItemsWithoutUndo (const QList<int>& indices);
void UpdateItems (const SongList& songs);

View File

@ -27,6 +27,7 @@
#include "core/song.h"
class QAction;
class SqlRow;
class PlaylistItem : public boost::enable_shared_from_this<PlaylistItem> {
@ -53,6 +54,8 @@ class PlaylistItem : public boost::enable_shared_from_this<PlaylistItem> {
virtual Options options() const { return Default; }
virtual QList<QAction*> actions() { return QList<QAction*>(); }
virtual bool InitFromQuery(const SqlRow& query) = 0;
void BindToQuery(QSqlQuery* query) const;
virtual void Reload() {}

File diff suppressed because it is too large Load Diff

View File

@ -1379,6 +1379,15 @@ void MainWindow::PlaylistRightClick(const QPoint& global_pos, const QModelIndex&
playlist_delete_->setVisible(editable);
playlist_copy_to_device_->setVisible(editable);
// Remove old item actions, if any.
foreach(QAction* action, playlistitem_actions_) {
playlist_menu_->removeAction(action);
}
// Get the new item actions, and add them
playlistitem_actions_ = item->actions();
playlist_menu_->insertActions(ui_->action_clear_playlist, playlistitem_actions_);
}
//if it isn't the first time we right click, we need to remove the menu previously created

View File

@ -331,6 +331,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
QAction* playlist_open_in_browser_;
QAction* playlist_queue_;
QAction* playlist_add_to_another_;
QList<QAction*> playlistitem_actions_;
QModelIndex playlist_menu_index_;
QSortFilterProxyModel* library_sort_model_;