commit 8429fa4b49ea6ce1a232dbb81f46d05ac5b3b4fd
Author: phantomjinx <[email protected]>
Date: Mon Oct 3 20:57:57 2011 +0100
Allow the multiple selection of playlists in the playlist view
* Only the first selection is passed to libgtkpod and notified to
other plugins.
* On selection of extra playlists, a reduced context menu can be
displayed, allowing for actions to be performed on the set of
playlists, notably deletion.
Fixes:3413192 - Not obvious how to delete a playlist without selecting from
libgtkpod/context_menus.c | 24 ---
libgtkpod/context_menus.h | 1 -
plugins/playlist_display/display_playlists.c | 211 ++++++++++----------
plugins/playlist_display/display_playlists.h | 12 +-
.../playlist_display/playlist_display_actions.c | 68 ++++---
.../playlist_display/playlist_display_actions.h | 14 +-
.../playlist_display_context_menu.c | 134 ++++++++++---
plugins/playlist_display/plugin.c | 12 +-
8 files changed, 276 insertions(+), 200 deletions(-)
---
diff --git a/libgtkpod/context_menus.c b/libgtkpod/context_menus.c
index c781d44..1a56c90 100644
--- a/libgtkpod/context_menus.c
+++ b/libgtkpod/context_menus.c
@@ -110,11 +110,6 @@ GtkWidget *add_separator(GtkWidget *menu) {
return sep;
}
-void context_menu_delete_track_head(GtkMenuItem *mi, gpointer data) {
- DeleteAction deleteaction = GPOINTER_TO_INT (data);
- delete_track_head(deleteaction);
-}
-
GtkWidget *add_exec_commands(GtkWidget *menu) {
GList *trkcmds = gtkpod_get_registered_track_commands();
GList *cmds = trkcmds;
@@ -156,25 +151,6 @@ GtkWidget *add_update_tracks_from_file(GtkWidget *menu) {
return hookup_menu_item(menu, _("Update Tracks from File"),
GTK_STOCK_REFRESH, G_CALLBACK (update_tracks_from_file), NULL);
}
-/*
- * sync_dirs_ entries - sync the directories of the selected playlist
- *
- * @mi - the menu item selected
- * @data - Ignored, should be NULL
- */
-static void sync_dirs(GtkMenuItem *mi, gpointer data) {
- if (gtkpod_get_current_playlist()) {
- sync_playlist(gtkpod_get_current_playlist(), NULL,
KEY_SYNC_CONFIRM_DIRS, 0, KEY_SYNC_DELETE_TRACKS, 0, KEY_SYNC_CONFIRM_DELETE,
0, KEY_SYNC_SHOW_SUMMARY, 0);
- }
- else {
- g_return_if_reached ();
- }
-}
-
-GtkWidget *add_sync_playlist_with_dirs(GtkWidget *menu) {
- return hookup_menu_item(menu, _("Sync Playlist with Dir(s)"),
GTK_STOCK_REFRESH, G_CALLBACK (sync_dirs), NULL);
-}
-
static void copy_selected_tracks_to_target_itdb(GtkMenuItem *mi, gpointer
*userdata) {
iTunesDB *t_itdb = *userdata;
g_return_if_fail (t_itdb);
diff --git a/libgtkpod/context_menus.h b/libgtkpod/context_menus.h
index 8024010..05a2de6 100644
--- a/libgtkpod/context_menus.h
+++ b/libgtkpod/context_menus.h
@@ -54,7 +54,6 @@ void context_menu_delete_track_head(GtkMenuItem *mi, gpointer
data);
GtkWidget *add_copy_track_to_filesystem (GtkWidget *menu);
GtkWidget *add_create_playlist_file (GtkWidget *menu);
GtkWidget *add_update_tracks_from_file (GtkWidget *menu);
-GtkWidget *add_sync_playlist_with_dirs (GtkWidget *menu);
GtkWidget *add_create_new_playlist (GtkWidget *menu);
GtkWidget *add_edit_track_details (GtkWidget *menu);
diff --git a/plugins/playlist_display/display_playlists.c
b/plugins/playlist_display/display_playlists.c
index 951b9da..208ad91 100644
--- a/plugins/playlist_display/display_playlists.c
+++ b/plugins/playlist_display/display_playlists.c
@@ -231,7 +231,7 @@ static gboolean pm_drag_motion(GtkWidget *widget,
GdkDragContext *dc, gint x, gi
return TRUE;
case DND_GTKPOD_TRACKLIST:
/* do not allow drop into currently selected playlist */
- if (pl_d == pm_get_selected_playlist()) {
+ if (pl_d == pm_get_first_selected_playlist()) {
if ((pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) || (pos ==
GTK_TREE_VIEW_DROP_INTO_OR_AFTER)) {
gtk_tree_path_free(path);
gdk_drag_status(dc, 0, time);
@@ -1015,55 +1015,20 @@ void pm_add_child(Itdb_iTunesDB *itdb, PM_column_type
type, gpointer item, gint
gtk_tree_store_set(GTK_TREE_STORE (model), &iter, PM_COLUMN_ITDB, itdb,
PM_COLUMN_TYPE, type, type, item, -1);
}
-/* Remove "playlist" from the display model.
- "select": TRUE: a new playlist is selected
- FALSE: no selection is taking place
- (useful when quitting program) */
-void pm_remove_playlist(Playlist *playlist, gboolean select) {
+/* Remove "playlist" from the display model */
+void pm_remove_playlist(Playlist *playlist) {
GtkTreeModel *model;
- gboolean have_iter = FALSE;
- GtkTreeIter select_iter, delete_iter;
- GtkTreeSelection *ts = NULL;
+ GtkTreeIter iter;
g_return_if_fail (playlist);
model = gtk_tree_view_get_model(playlist_treeview);
g_return_if_fail (model);
- ts = gtk_tree_view_get_selection(playlist_treeview);
-
- if (itdb_playlist_is_mpl(playlist) && (playlist->itdb ==
gtkpod_get_current_itdb())) {
- /* We are about to remove the entire itdb (playlist is MPL) and
- * a playlist of this itdb is selected --> clear display
- * (pm_unselect_playlist probably works as well, but the
- * unselect won't be done until later (callback)) */
- gtkpod_set_current_playlist(NULL);
- }
-
- if (select && (gtkpod_get_current_playlist() == playlist)) {
- /* We are about to delete the currently selected
- * playlist. Try to select the next. */
- if (gtk_tree_selection_get_selected(ts, NULL, &select_iter)) {
- GtkTreePath *path = gtk_tree_model_get_path(model, &select_iter);
- if (gtk_tree_model_iter_next(model, &select_iter)) {
- have_iter = TRUE;
- }
- else { /* no next iter -- try previous iter */
- if (gtk_tree_path_prev(path)) { /* OK -- make iter from it */
- gtk_tree_model_get_iter(model, &select_iter, path);
- have_iter = TRUE;
- }
- }
- gtk_tree_path_free(path);
- }
- }
+ gtkpod_set_current_playlist(NULL);
- if (pm_get_iter_for_playlist(playlist, &delete_iter)) {
- gtk_tree_store_remove(GTK_TREE_STORE (model), &delete_iter);
+ if (pm_get_iter_for_playlist(playlist, &iter)) {
+ gtk_tree_store_remove(GTK_TREE_STORE (model), &iter);
}
-
- /* select our new iter !!! */
- if (have_iter && select)
- gtk_tree_selection_select_iter(ts, &select_iter);
}
/* Remove all playlists from the display model */
@@ -1091,6 +1056,35 @@ void pm_remove_all_playlists(gboolean clear_sort) {
}
/* Select specified playlist */
+void pm_select_playlists(GList *playlists) {
+ GtkTreeIter iter;
+ GtkTreeSelection *ts;
+
+ g_return_if_fail (playlist_treeview);
+
+ if (!playlists) {
+ ts = gtk_tree_view_get_selection(playlist_treeview);
+ gtk_tree_selection_unselect_all(ts);
+ return;
+ }
+
+ ts = gtk_tree_view_get_selection(playlist_treeview);
+
+ for (gint i = 0; i < g_list_length(playlists); ++i) {
+ Playlist *pl = g_list_nth_data(playlists, i);
+
+ if (pm_get_iter_for_playlist(pl, &iter)) {
+ gtk_tree_selection_select_iter(ts, &iter);
+ }
+
+ /* Only properly select the first in the list */
+ if (i == 0 && gtkpod_get_current_playlist() != pl) {
+ gtkpod_set_current_playlist(pl);
+ }
+ }
+}
+
+/* Select specified playlist */
void pm_select_playlist(Playlist *playlist) {
GtkTreeIter iter;
GtkTreeSelection *ts;
@@ -1128,10 +1122,13 @@ void pm_unselect_playlist(Playlist *playlist) {
}
static gboolean pm_selection_changed_cb(gpointer data) {
- GtkTreeModel *model;
GtkTreeIter iter;
GtkTreeView *tree_view = GTK_TREE_VIEW (data);
- GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view);
+
+ g_return_val_if_fail(tree_view, FALSE);
+
+ GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
+ g_return_val_if_fail(model, FALSE);
#if DEBUG_TIMING
GTimeVal time;
@@ -1140,16 +1137,20 @@ static gboolean pm_selection_changed_cb(gpointer data) {
time.tv_sec % 3600, time.tv_usec);
#endif
- if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE) {
/* no selection -> reset sort tabs */
- // gphoto_change_to_photo_window (FALSE);
+ if (! pm_is_playlist_selected()) {
+ /* no selection */
gtkpod_set_current_playlist(NULL);
}
else {
- Playlist *new_playlist = NULL;
+ Playlist *new_playlist = pm_get_first_selected_playlist();
+ g_return_val_if_fail(new_playlist, FALSE);
+
Itdb_iTunesDB *itdb = NULL;
Itdb_PhotoDB *photodb = NULL;
PM_column_type type = 0;
+
/* handle new selection */
+ pm_get_iter_for_playlist(new_playlist, &iter);
gtk_tree_model_get(model, &iter, PM_COLUMN_TYPE, &type,
PM_COLUMN_ITDB, &itdb, PM_COLUMN_PLAYLIST, &new_playlist, PM_COLUMN_PHOTOS,
&photodb, -1);
gtkpod_set_current_playlist(new_playlist);
@@ -1159,8 +1160,6 @@ static gboolean pm_selection_changed_cb(gpointer data) {
g_return_val_if_fail (new_playlist, FALSE);
g_return_val_if_fail (itdb, FALSE);
- // gphoto_change_to_photo_window (FALSE);
-
if (new_playlist->is_spl && new_playlist->splpref.liveupdate)
itdb_spl_update(new_playlist);
@@ -1169,7 +1168,6 @@ static gboolean pm_selection_changed_cb(gpointer data) {
case PM_COLUMN_PHOTOS:
g_return_val_if_fail (photodb, FALSE);
g_return_val_if_fail (itdb, FALSE);
- // gphoto_display_photo_window (itdb);
break;
case PM_COLUMN_ITDB:
case PM_COLUMN_TYPE:
@@ -1361,16 +1359,16 @@ static gint pm_get_position_for_playlist(Playlist
*playlist) {
/* "unsort" the playlist view without causing the sort tabs to be
touched. */
static void pm_unsort() {
- Playlist *cur_pl;
+ GList *cur_pls;
pm_selection_blocked = TRUE;
/* remember */
- cur_pl = pm_get_selected_playlist();
+ cur_pls = pm_get_selected_playlists();
pm_remove_all_playlists(TRUE);
- pm_set_selected_playlist(cur_pl);
+ pm_select_playlists(cur_pls);
pm_selection_blocked = FALSE;
/* reset sort counter */
@@ -1904,11 +1902,12 @@ static void pm_create_treeview(void) {
model = gtk_tree_store_new(PM_NUM_COLUMNS, G_TYPE_POINTER, G_TYPE_INT,
G_TYPE_POINTER, G_TYPE_POINTER);
/* set tree model */
gtk_tree_view_set_model(playlist_treeview, GTK_TREE_MODEL (model));
- /* gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (playlist_treeview), TRUE);
*/
-
gtk_tree_selection_set_mode(gtk_tree_view_get_selection(playlist_treeview),
GTK_SELECTION_SINGLE);
+
+ /* set selection mode */
selection = gtk_tree_view_get_selection(playlist_treeview);
- g_signal_connect (G_OBJECT (selection), "changed",
- G_CALLBACK (pm_selection_changed), NULL);
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
+ g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK
(pm_selection_changed), NULL);
+
pm_add_columns();
pm_add_all_itdbs();
@@ -2005,51 +2004,63 @@ GtkWidget *pm_create_playlist_view(GtkActionGroup
*action_group) {
return GTK_WIDGET(vbox);
}
-Playlist* pm_get_selected_playlist(void) {
- GtkTreeSelection *ts;
- GtkTreeIter iter;
- GtkTreeModel *model;
- Playlist *result = NULL;
+void pm_selected_playlists_foreach(PlaylistSelectionForeachFunc func, gpointer
data) {
+ GList *playlists = pm_get_selected_playlists();
+ while(playlists) {
+ Playlist *pl = playlists->data;
+ (* func) (pl ,data);
+ playlists = playlists->next;
+ }
+}
- g_return_val_if_fail (playlist_treeview, NULL);
- ts = gtk_tree_view_get_selection(playlist_treeview);
- g_return_val_if_fail (ts, NULL);
+GList *pm_get_selected_playlists() {
+ g_return_val_if_fail(playlist_treeview, NULL);
- if (gtk_tree_selection_get_selected(ts, &model, &iter)) {
- gtk_tree_model_get(model, &iter, PM_COLUMN_PLAYLIST, &result, -1);
+ GtkTreeSelection *selection =
gtk_tree_view_get_selection(playlist_treeview);
+ g_return_val_if_fail(selection, NULL);
+
+ GtkTreeModel *model = gtk_tree_view_get_model(playlist_treeview);
+ GList *paths = gtk_tree_selection_get_selected_rows(selection, &model);
+ GList *playlists = NULL;
+
+ while (paths) {
+ GtkTreePath *path = paths->data;
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_get_iter(model, &iter, path)) {
+ Playlist *pl;
+ gtk_tree_model_get(model, &iter, PM_COLUMN_PLAYLIST, &pl, -1);
+ if (pl) {
+ playlists = g_list_append(playlists, pl);
+ }
+ }
+
+ paths = paths->next;
}
- /* playlist was just changed -- wait until current_playlist is
- updated. */
- if (result != gtkpod_get_current_playlist())
- result = NULL;
- return result;
+ g_list_free(paths);
+
+ return playlists;
}
-Itdb_iTunesDB* pm_get_selected_itdb(void) {
- GtkTreeSelection *ts;
- GtkTreeIter iter;
- GtkTreeModel *model;
- Itdb_iTunesDB *result = NULL;
+Playlist *pm_get_first_selected_playlist(void) {
- g_return_val_if_fail (playlist_treeview, NULL);
- ts = gtk_tree_view_get_selection(playlist_treeview);
- g_return_val_if_fail (ts, NULL);
+ GList *playlists = pm_get_selected_playlists();
- if (gtk_tree_selection_get_selected(ts, &model, &iter)) {
- gtk_tree_model_get(model, &iter, PM_COLUMN_ITDB, &result, -1);
+ if (!playlists) {
+ return NULL;
}
- /* playlist was just changed -- wait until current_playlist is
- updated. */
- if (result != gtkpod_get_current_itdb())
- result = NULL;
- return result;
+ return playlists->data;
+}
+
+gint pm_get_selected_playlist_count() {
+ GtkTreeSelection *selection =
gtk_tree_view_get_selection(playlist_treeview);
+ return gtk_tree_selection_count_selected_rows(selection);
}
-/* use with care!! */
-void pm_set_selected_playlist(Playlist *pl) {
- gtkpod_set_current_playlist(pl);
+gboolean pm_is_playlist_selected() {
+ return pm_get_selected_playlist_count() > 0;
}
void pm_show_all_playlists() {
@@ -2082,7 +2093,7 @@ void playlist_display_update_itdb_cb(GtkPodApp *app,
gpointer olditdb, gpointer
/* remove @old_itdb (all playlists are removed if the MPL is
removed and add @new_itdb at its place */
- pm_remove_playlist(itdb_playlist_mpl(old_itdb), FALSE);
+ pm_remove_playlist(itdb_playlist_mpl(old_itdb));
/* display replacement */
pm_add_itdb(new_itdb, pos);
@@ -2103,21 +2114,7 @@ void playlist_display_itdb_removed_cb(GtkPodApp *app,
gpointer itdb, gpointer da
return;
}
- pm_remove_playlist(itdb_playlist_mpl(old_itdb), FALSE);
-}
-
-void playlist_display_select_playlist_cb(GtkPodApp *app, gpointer pl, gpointer
data) {
- Playlist *new_playlist = pl;
- Playlist *old_playlist = pm_get_selected_playlist();
-
- if (old_playlist == new_playlist) {
- return;
- }
-
- if (old_playlist)
- pm_unselect_playlist(old_playlist);
-
- pm_select_playlist(new_playlist);
+ pm_remove_playlist(itdb_playlist_mpl(old_itdb));
}
void playlist_display_playlist_added_cb(GtkPodApp *app, gpointer pl, gint32
pos, gpointer data) {
@@ -2129,7 +2126,7 @@ void playlist_display_playlist_added_cb(GtkPodApp *app,
gpointer pl, gint32 pos,
void playlist_display_playlist_removed_cb(GtkPodApp *app, gpointer pl,
gpointer data) {
Playlist *old_playlist = pl;
- pm_remove_playlist(old_playlist, TRUE);
+ pm_remove_playlist(old_playlist);
}
void playlist_display_preference_changed_cb(GtkPodApp *app, gpointer pfname,
gpointer value, gpointer data) {
diff --git a/plugins/playlist_display/display_playlists.h
b/plugins/playlist_display/display_playlists.h
index e78f68f..8957a4b 100644
--- a/plugins/playlist_display/display_playlists.h
+++ b/plugins/playlist_display/display_playlists.h
@@ -49,16 +49,22 @@ typedef enum {
GtkWidget *pm_create_playlist_view(GtkActionGroup *action_group);
void pm_destroy_playlist_view(void);
void pm_select_playlist(Playlist *playlist);
-void pm_set_selected_playlist(Playlist *pl);
+
+GList *pm_get_selected_playlists(void);
+Playlist *pm_get_first_selected_playlist(void);
+gint pm_get_selected_playlist_count(void);
+gboolean pm_is_playlist_selected(void);
+
+typedef gboolean (* PlaylistSelectionForeachFunc) (Playlist *playlist,
gpointer data);
+void pm_selected_playlists_foreach(PlaylistSelectionForeachFunc func, gpointer
data);
+
void pm_remove_all_playlists (gboolean clear_sort);
void pm_add_all_itdbs (void);
-Playlist* pm_get_selected_playlist(void);
void pm_stop_editing(gboolean cancel);
void playlist_display_itdb_added_cb(GtkPodApp *app, gpointer itdb, gint32 pos,
gpointer data);
void playlist_display_itdb_removed_cb(GtkPodApp *app, gpointer itdb, gpointer
data);
void playlist_display_update_itdb_cb (GtkPodApp *app, gpointer olditdb,
gpointer newitdb, gpointer data);
-void playlist_display_select_playlist_cb (GtkPodApp *app, gpointer pl,
gpointer data);
void playlist_display_playlist_added_cb(GtkPodApp *app, gpointer pl, gint32
pos, gpointer data);
void playlist_display_playlist_removed_cb(GtkPodApp *app, gpointer pl,
gpointer data);
void playlist_display_track_removed_cb(GtkPodApp *app, gpointer tk, gpointer
data);
diff --git a/plugins/playlist_display/playlist_display_actions.c
b/plugins/playlist_display/playlist_display_actions.c
index cd612d7..f8954b9 100644
--- a/plugins/playlist_display/playlist_display_actions.c
+++ b/plugins/playlist_display/playlist_display_actions.c
@@ -624,59 +624,77 @@ void on_pl_for_each_rating_activate(GtkAction *action,
PlaylistDisplayPlugin* pl
}
}
-static void delete_selected_playlist(DeleteAction deleteaction) {
- Playlist *pl = pm_get_selected_playlist();
+static void delete_selected_playlists(DeleteAction deleteaction) {
+ GList *playlists = pm_get_selected_playlists();
+
+ while (playlists) {
+ Playlist *pl = playlists->data;
+ if (pl) {
+ gtkpod_set_current_playlist(pl);
+ delete_playlist_head(deleteaction);
+ }
+ else {
+ message_sb_no_playlist_selected();
+ }
- if (pl) {
- delete_playlist_head(deleteaction);
- }
- else {
- message_sb_no_playlist_selected();
+ playlists = playlists->next;
}
}
-void on_delete_selected_playlist (GtkAction *action, PlaylistDisplayPlugin*
plugin)
+void on_delete_selected_playlists (GtkAction *action, PlaylistDisplayPlugin*
plugin)
{
- delete_selected_playlist (DELETE_ACTION_PLAYLIST);
+ delete_selected_playlists (DELETE_ACTION_PLAYLIST);
}
-void on_delete_selected_playlist_including_tracks_from_harddisk (GtkAction
*action, PlaylistDisplayPlugin* plugin)
+void on_delete_selected_playlists_including_tracks_from_harddisk (GtkAction
*action, PlaylistDisplayPlugin* plugin)
{
- delete_selected_playlist (DELETE_ACTION_LOCAL);
+ delete_selected_playlists (DELETE_ACTION_LOCAL);
}
-void on_delete_selected_playlist_including_tracks_from_ipod (GtkAction
*action, PlaylistDisplayPlugin* plugin)
+void on_delete_selected_playlists_including_tracks_from_ipod (GtkAction
*action, PlaylistDisplayPlugin* plugin)
{
- delete_selected_playlist (DELETE_ACTION_IPOD);
+ delete_selected_playlists (DELETE_ACTION_IPOD);
}
-void on_delete_selected_playlist_including_tracks_from_database (GtkAction
*action, PlaylistDisplayPlugin* plugin)
+void on_delete_selected_playlists_including_tracks_from_database (GtkAction
*action, PlaylistDisplayPlugin* plugin)
{
- delete_selected_playlist (DELETE_ACTION_DATABASE);
+ delete_selected_playlists (DELETE_ACTION_DATABASE);
}
-void on_delete_selected_playlist_including_tracks_from_device(GtkAction
*action, PlaylistDisplayPlugin* plugin)
+void on_delete_selected_playlists_including_tracks_from_device(GtkAction
*action, PlaylistDisplayPlugin* plugin)
{
iTunesDB *itdb = gtkpod_get_current_itdb();
if (!itdb)
return;
if (itdb->usertype & GP_ITDB_TYPE_IPOD) {
- on_delete_selected_playlist_including_tracks_from_ipod(action, plugin);
+ on_delete_selected_playlists_including_tracks_from_ipod(action,
plugin);
} else if (itdb->usertype & GP_ITDB_TYPE_LOCAL) {
- on_delete_selected_playlist_including_tracks_from_harddisk(action,
plugin);
+ on_delete_selected_playlists_including_tracks_from_harddisk(action,
plugin);
}
}
-void on_update_selected_playlist (GtkAction *action, PlaylistDisplayPlugin*
plugin) {
- Playlist *pl = pm_get_selected_playlist();
- if (pl) {
- update_tracks(pm_get_selected_playlist()->members);
+void on_update_selected_playlists (GtkAction *action, PlaylistDisplayPlugin*
plugin) {
+
+ GList *playlists = pm_get_selected_playlists();
+
+ while (playlists) {
+ Playlist *pl = playlists->data;
+ if (pl) {
+ update_tracks(pl->members);
+ }
+ playlists = playlists->next;
}
}
-void on_sync_playlist_with_dirs(GtkAction *action, PlaylistDisplayPlugin*
plugin) {
- if (gtkpod_get_current_playlist()) {
- sync_playlist(gtkpod_get_current_playlist(), NULL,
KEY_SYNC_CONFIRM_DIRS, 0, KEY_SYNC_DELETE_TRACKS, 0, KEY_SYNC_CONFIRM_DELETE,
0, KEY_SYNC_SHOW_SUMMARY, 0);
+void on_sync_playlists_with_dirs(GtkAction *action, PlaylistDisplayPlugin*
plugin) {
+ GList *playlists = pm_get_selected_playlists();
+
+ while (playlists) {
+ Playlist *pl = playlists->data;
+ if (pl) {
+ sync_playlist(pl, NULL, KEY_SYNC_CONFIRM_DIRS, 0,
KEY_SYNC_DELETE_TRACKS, 0, KEY_SYNC_CONFIRM_DELETE, 0, KEY_SYNC_SHOW_SUMMARY,
0);
+ }
+ playlists = playlists->next;
}
}
diff --git a/plugins/playlist_display/playlist_display_actions.h
b/plugins/playlist_display/playlist_display_actions.h
index 20ced8c..5d7b6d2 100644
--- a/plugins/playlist_display/playlist_display_actions.h
+++ b/plugins/playlist_display/playlist_display_actions.h
@@ -61,13 +61,13 @@ void on_pl_for_each_composer_activate(GtkAction *action,
PlaylistDisplayPlugin*
void on_pl_for_each_year_activate(GtkAction *action, PlaylistDisplayPlugin*
plugin);
void on_pl_for_each_rating_activate(GtkAction *action, PlaylistDisplayPlugin*
plugin);
-void on_delete_selected_playlist (GtkAction *action, PlaylistDisplayPlugin*
plugin);
-void on_delete_selected_playlist_including_tracks_from_harddisk (GtkAction
*action, PlaylistDisplayPlugin* plugin);
-void on_delete_selected_playlist_including_tracks_from_ipod (GtkAction
*action, PlaylistDisplayPlugin* plugin);
-void on_delete_selected_playlist_including_tracks_from_database (GtkAction
*action, PlaylistDisplayPlugin* plugin);
-void on_delete_selected_playlist_including_tracks_from_device(GtkAction
*action, PlaylistDisplayPlugin* plugin);
+void on_delete_selected_playlists (GtkAction *action, PlaylistDisplayPlugin*
plugin);
+void on_delete_selected_playlists_including_tracks_from_harddisk (GtkAction
*action, PlaylistDisplayPlugin* plugin);
+void on_delete_selected_playlists_including_tracks_from_ipod (GtkAction
*action, PlaylistDisplayPlugin* plugin);
+void on_delete_selected_playlists_including_tracks_from_database (GtkAction
*action, PlaylistDisplayPlugin* plugin);
+void on_delete_selected_playlists_including_tracks_from_device(GtkAction
*action, PlaylistDisplayPlugin* plugin);
-void on_update_selected_playlist (GtkAction *action, PlaylistDisplayPlugin*
plugin);
-void on_sync_playlist_with_dirs(GtkAction *action, PlaylistDisplayPlugin*
plugin);
+void on_update_selected_playlists (GtkAction *action, PlaylistDisplayPlugin*
plugin);
+void on_sync_playlists_with_dirs(GtkAction *action, PlaylistDisplayPlugin*
plugin);
#endif
diff --git a/plugins/playlist_display/playlist_display_context_menu.c
b/plugins/playlist_display/playlist_display_context_menu.c
index b3246c6..2e8adda 100644
--- a/plugins/playlist_display/playlist_display_context_menu.c
+++ b/plugins/playlist_display/playlist_display_context_menu.c
@@ -40,13 +40,21 @@
#include "libgtkpod/gp_itdb.h"
#include "libgtkpod/context_menus.h"
#include "libgtkpod/misc_playlist.h"
+#include "libgtkpod/misc_track.h"
#include "libgtkpod/misc.h"
+#include "libgtkpod/prefs.h"
+#include "libgtkpod/syncdir.h"
static void context_menu_delete_playlist_head(GtkMenuItem *mi, gpointer data) {
DeleteAction deleteaction = GPOINTER_TO_INT (data);
delete_playlist_head(deleteaction);
}
+void context_menu_delete_track_head(GtkMenuItem *mi, gpointer data) {
+ DeleteAction deleteaction = GPOINTER_TO_INT (data);
+ delete_track_head(deleteaction);
+}
+
static GtkWidget *add_delete_all_tracks_from_ipod(GtkWidget *menu) {
GtkWidget *mi;
GtkWidget *sub;
@@ -99,21 +107,33 @@ static GtkWidget
*add_delete_playlist_but_keep_tracks(GtkWidget *menu) {
return hookup_menu_item(menu, _("Delete But Keep Tracks"),
GTK_STOCK_DELETE, G_CALLBACK (context_menu_delete_playlist_head),
GINT_TO_POINTER (DELETE_ACTION_PLAYLIST));
}
-static void copy_selected_playlist_to_target_itdb(GtkMenuItem *mi, gpointer
*userdata) {
+static void copy_selected_playlists_to_target_itdb(GtkMenuItem *mi, gpointer
*userdata) {
iTunesDB *t_itdb = *userdata;
g_return_if_fail (t_itdb);
- if (gtkpod_get_current_playlist())
- copy_playlist_to_target_itdb(gtkpod_get_current_playlist(), t_itdb);
+
+ GList *playlists = pm_get_selected_playlists();
+ while(playlists) {
+ Playlist *pl = playlists->data;
+ copy_playlist_to_target_itdb(pl, t_itdb);
+ playlists = playlists->next;
+ }
}
-static void copy_selected_playlist_to_target_playlist(GtkMenuItem *mi,
gpointer *userdata) {
+
+
+static void copy_selected_playlists_to_target_playlist(GtkMenuItem *mi,
gpointer *userdata) {
Playlist *t_pl = *userdata;
g_return_if_fail (t_pl);
- if (gtkpod_get_current_playlist())
- copy_playlist_to_target_playlist(gtkpod_get_current_playlist(), t_pl);
+
+ GList *playlists = pm_get_selected_playlists();
+ while(playlists) {
+ Playlist *pl = playlists->data;
+ copy_playlist_to_target_playlist(pl, t_pl);
+ playlists = playlists->next;
+ }
}
-static GtkWidget *add_copy_selected_playlist_to_target_itdb(GtkWidget *menu,
const gchar *title) {
+static GtkWidget *add_copy_selected_playlists_to_target_itdb(GtkWidget *menu,
const gchar *title) {
GtkWidget *mi;
GtkWidget *sub;
GtkWidget *pl_mi;
@@ -150,7 +170,7 @@ static GtkWidget
*add_copy_selected_playlist_to_target_itdb(GtkWidget *menu, con
pl_sub = gtk_menu_new();
gtk_widget_show(pl_sub);
gtk_menu_item_set_submenu(GTK_MENU_ITEM (pl_mi), pl_sub);
- hookup_menu_item(pl_sub, _(itdb_playlist_mpl(itdb)->name), stock_id,
G_CALLBACK(copy_selected_playlist_to_target_itdb), &itdbs->data);
+ hookup_menu_item(pl_sub, _(itdb_playlist_mpl(itdb)->name), stock_id,
G_CALLBACK(copy_selected_playlists_to_target_itdb), &itdbs->data);
add_separator(pl_sub);
for (db = itdb->playlists; db; db = db->next) {
pl = db->data;
@@ -159,7 +179,7 @@ static GtkWidget
*add_copy_selected_playlist_to_target_itdb(GtkWidget *menu, con
stock_id = GTK_STOCK_PROPERTIES;
else
stock_id = GTK_STOCK_JUSTIFY_LEFT;
- hookup_menu_item(pl_sub, _(pl->name), stock_id,
G_CALLBACK(copy_selected_playlist_to_target_playlist), &db->data);
+ hookup_menu_item(pl_sub, _(pl->name), stock_id,
G_CALLBACK(copy_selected_playlists_to_target_playlist), &db->data);
}
}
}
@@ -195,7 +215,13 @@ static void open_photo_editor(GtkMenuItem *mi, gpointer
data) {
/* Save Changes */
static void save_changes(GtkMenuItem *mi, gpointer data) {
g_return_if_fail (gtkpod_get_current_playlist());
- gp_save_itdb(gtkpod_get_current_playlist()->itdb);
+
+ GList *playlists = pm_get_selected_playlists();
+ while (playlists) {
+ Playlist *pl = playlists->data;
+ gp_save_itdb(pl->itdb);
+ playlists = playlists->next;
+ }
}
/* Load an itdb */
@@ -268,21 +294,42 @@ static GtkWidget *add_eject_ipod(GtkWidget *menu) {
return hookup_menu_item(menu, _("Eject iPod"), GTK_STOCK_DISCONNECT,
G_CALLBACK (eject_ipod), NULL);
}
-void pm_context_menu_init(void) {
- GtkWidget *menu = NULL;
- Playlist *pl;
+/*
+ * sync_dirs_ entries - sync the directories of the selected playlist
+ *
+ * @mi - the menu item selected
+ * @data - Ignored, should be NULL
+ */
+static void sync_dirs(GtkMenuItem *mi, gpointer data) {
+ GList *playlists = pm_get_selected_playlists();
+ while (playlists) {
+ Playlist *pl = playlists->data;
+ sync_playlist(pl, NULL, KEY_SYNC_CONFIRM_DIRS, 0,
KEY_SYNC_DELETE_TRACKS, 0, KEY_SYNC_CONFIRM_DELETE, 0, KEY_SYNC_SHOW_SUMMARY,
0);
+ playlists = playlists->next;
+ }
+}
- if (widgets_blocked)
- return;
+static GtkWidget *add_sync_playlist_with_dirs(GtkWidget *menu) {
+ return hookup_menu_item(menu, _("Sync Playlist with Dir(s)"),
GTK_STOCK_REFRESH, G_CALLBACK (sync_dirs), NULL);
+}
- pm_stop_editing(TRUE);
+static void update_multi_tracks_from_file(GtkMenuItem *mi, gpointer data) {
+ GList *playlists = pm_get_selected_playlists();
+ while (playlists) {
+ Playlist *pl = playlists->data;
+ update_tracks(pl->members);
+ playlists = playlists->next;
+ }
+}
- if (!pm_get_selected_playlist())
- return;
+GtkWidget *add_multi_update_tracks_from_file(GtkWidget *menu) {
+ return hookup_menu_item(menu, _("Update Tracks from File"),
GTK_STOCK_REFRESH, G_CALLBACK (update_multi_tracks_from_file), NULL);
+}
- pl = pm_get_selected_playlist();
- if (!pl)
- return;
+static void _populate_single_playlist_menu(GtkWidget *menu) {
+
+ Playlist *pl = pm_get_first_selected_playlist();
+ g_return_if_fail(pl);
// Ensure that all the tracks in the playlist are the current selected
tracks
gtkpod_set_selected_tracks(pl->members);
@@ -293,8 +340,6 @@ void pm_context_menu_init(void) {
eitdb = itdb->userdata;
g_return_if_fail (eitdb);
- menu = gtk_menu_new();
-
if (itdb->usertype & GP_ITDB_TYPE_IPOD) {
if (eitdb->itdb_imported) {
add_exec_commands(menu);
@@ -312,7 +357,7 @@ void pm_context_menu_init(void) {
add_delete_playlist_but_keep_tracks(delete_menu);
}
add_separator(menu);
- add_copy_selected_playlist_to_target_itdb(menu, _("Copy selected
playlist to..."));
+ add_copy_selected_playlists_to_target_itdb(menu, _("Copy selected
playlist to..."));
add_separator(menu);
add_update_tracks_from_file(menu);
@@ -340,7 +385,7 @@ void pm_context_menu_init(void) {
add_load_ipod(menu);
}
}
- if (itdb->usertype & GP_ITDB_TYPE_LOCAL) {
+ else if (itdb->usertype & GP_ITDB_TYPE_LOCAL) {
add_exec_commands(menu);
add_separator(menu);
@@ -353,7 +398,7 @@ void pm_context_menu_init(void) {
add_delete_playlist_including_tracks_harddisk(delete_menu);
add_delete_playlist_but_keep_tracks(delete_menu);
}
- add_copy_selected_playlist_to_target_itdb(menu, _("Copy selected
playlist to..."));
+ add_copy_selected_playlists_to_target_itdb(menu, _("Copy selected
playlist to..."));
add_separator(menu);
add_update_tracks_from_file(menu);
if (!pl->is_spl) {
@@ -376,6 +421,43 @@ void pm_context_menu_init(void) {
if (eitdb->data_changed) {
add_save_changes(menu);
}
+}
+
+static void _populate_multi_playlist_menu(GtkWidget *menu) {
+
+ GtkWidget *delete_menu = add_sub_menu(menu, "Delete", GTK_STOCK_DELETE);
+ add_delete_playlist_including_tracks_ipod(delete_menu);
+ add_delete_playlist_but_keep_tracks(delete_menu);
+
+ add_separator(menu);
+ add_copy_selected_playlists_to_target_itdb(menu, _("Copy selected playlist
to..."));
+
+ add_separator(menu);
+ add_multi_update_tracks_from_file(menu);
+
+ add_sync_playlist_with_dirs(menu);
+
+ add_save_changes(menu);
+}
+
+void pm_context_menu_init(void) {
+ GtkWidget *menu = NULL;
+
+ if (widgets_blocked)
+ return;
+
+ pm_stop_editing(TRUE);
+
+ if (!pm_is_playlist_selected())
+ return;
+
+ menu = gtk_menu_new();
+
+ if (pm_get_selected_playlist_count() == 1) {
+ _populate_single_playlist_menu(menu);
+ } else {
+ _populate_multi_playlist_menu(menu);
+ }
/*
* button should be button 0 as per the docs because we're calling
diff --git a/plugins/playlist_display/plugin.c
b/plugins/playlist_display/plugin.c
index 2368e2c..407c55c 100644
--- a/plugins/playlist_display/plugin.c
+++ b/plugins/playlist_display/plugin.c
@@ -116,7 +116,7 @@ static GtkActionEntry playlist_actions[] =
N_("Sync Playlist with Dir(s)"),
NULL,
NULL,
- G_CALLBACK (on_sync_playlist_with_dirs)
+ G_CALLBACK (on_sync_playlists_with_dirs)
},
{
ACTION_NEW_PLAYLIST_MENU,
@@ -268,7 +268,7 @@ static GtkActionEntry playlist_actions[] =
N_("Selected Playlist"),
NULL,
NULL,
- G_CALLBACK (on_delete_selected_playlist)
+ G_CALLBACK (on_delete_selected_playlists)
},
{
"ActionDeleteSelectedPlaylistIncDb",
@@ -276,7 +276,7 @@ static GtkActionEntry playlist_actions[] =
N_("Selected Playlist including Tracks from Database"),
NULL,
NULL,
- G_CALLBACK
(on_delete_selected_playlist_including_tracks_from_database)
+ G_CALLBACK
(on_delete_selected_playlists_including_tracks_from_database)
},
{
"ActionDeleteSelectedPlaylistIncDev",
@@ -284,7 +284,7 @@ static GtkActionEntry playlist_actions[] =
N_("Selected Playlist including Tracks from Device"),
NULL,
NULL,
- G_CALLBACK
(on_delete_selected_playlist_including_tracks_from_device)
+ G_CALLBACK
(on_delete_selected_playlists_including_tracks_from_device)
},
{
"ActionUpdatePlaylist",
@@ -292,7 +292,7 @@ static GtkActionEntry playlist_actions[] =
N_("Selected Playlist"),
NULL,
NULL,
- G_CALLBACK (on_update_selected_playlist)
+ G_CALLBACK (on_update_selected_playlists)
}
};
@@ -349,7 +349,6 @@ static gboolean activate_plugin(AnjutaPlugin *plugin) {
playlist_display_plugin->playlist_view =
pm_create_playlist_view(action_group);
- g_signal_connect (gtkpod_app, SIGNAL_PLAYLIST_SELECTED, G_CALLBACK
(playlist_display_select_playlist_cb), NULL);
g_signal_connect (gtkpod_app, SIGNAL_PLAYLIST_ADDED, G_CALLBACK
(playlist_display_playlist_added_cb), NULL);
g_signal_connect (gtkpod_app, SIGNAL_PLAYLIST_REMOVED, G_CALLBACK
(playlist_display_playlist_removed_cb), NULL);
g_signal_connect (gtkpod_app, SIGNAL_ITDB_ADDED, G_CALLBACK
(playlist_display_itdb_added_cb), NULL);
@@ -373,7 +372,6 @@ static gboolean deactivate_plugin(AnjutaPlugin *plugin) {
playlist_display_plugin = (PlaylistDisplayPlugin*) plugin;
ui = anjuta_shell_get_ui(plugin->shell, NULL);
- g_signal_handlers_disconnect_by_func (plugin->shell, G_CALLBACK
(playlist_display_select_playlist_cb), plugin);
g_signal_handlers_disconnect_by_func (plugin->shell, G_CALLBACK
(playlist_display_playlist_added_cb), plugin);
g_signal_handlers_disconnect_by_func (plugin->shell, G_CALLBACK
(playlist_display_playlist_removed_cb), plugin);
g_signal_handlers_disconnect_by_func (plugin->shell, G_CALLBACK
(playlist_display_itdb_added_cb), plugin);
------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure contains a
definitive record of customers, application performance, security
threats, fraudulent activity and more. Splunk takes this data and makes
sense of it. Business sense. IT sense. Common sense.
http://p.sf.net/sfu/splunk-d2dcopy1
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2