commit 5360d9eaa66aecc1747c54a10e2a58b81788e761 Author: phantomjinx <p.g.richard...@phantomjinx.co.uk> Date: Tue Jun 1 22:22:58 2010 +0100
Getting the smaller things sorted ... * gtkpod_app_iface.c * Handle whether to save before exiting * Add some new signals for preference changes, itdb data changes and itdb data saving * Avoid segfault from displayed_tracks collection by copying glist * When tracks reordered, ensure the current playlist's members are the displayed tracks * Addition of menu items on Music and Edit menus and corrsponding actions TODO | 23 +++-- libgtkpod/gtkpod_app_iface.c | 51 ++++++++++-- libgtkpod/gtkpod_app_iface.h | 2 +- plugins/core_preferences/core_prefs.h | 4 +- plugins/details_editor/Makefile.am | 3 +- plugins/details_editor/details_editor.ui | 6 +- plugins/details_editor/details_editor_actions.c | 49 +++++++++++ plugins/details_editor/details_editor_actions.h | 41 +++++++++ plugins/details_editor/plugin.c | 9 ++ plugins/exporter/exporter_actions.h | 4 +- plugins/playlist_display/playlist_display.ui | 26 ++++++- .../playlist_display/playlist_display_actions.c | 11 +++ .../playlist_display/playlist_display_actions.h | 6 +- .../playlist_display_context_menu.c | 12 +++ plugins/playlist_display/plugin.c | 16 ++++ plugins/repository_editor/Makefile.am | 1 + plugins/repository_editor/plugin.c | 26 ++++++- plugins/repository_editor/repository_actions.c | 91 ++++++++++++++++++++ plugins/repository_editor/repository_actions.h | 43 +++++++++ plugins/repository_editor/repository_editor.ui | 14 +++- plugins/sorttab_display/display_sorttabs.h | 4 +- plugins/sorttab_display/sorttab_display_actions.h | 4 +- plugins/track_display/display_tracks.h | 1 + plugins/track_display/plugin.c | 9 ++ plugins/track_display/track_display.ui | 1 + plugins/track_display/track_display_actions.c | 5 + plugins/track_display/track_display_actions.h | 5 +- src/display_tracks.c | 49 ++++++----- src/gtkpod.c | 13 +-- src/misc.c | 1 - src/misc.h | 1 + src/misc_playlist.c | 38 ++++----- src/sort_window.h | 4 +- 33 files changed, 481 insertions(+), 92 deletions(-) --- diff --git a/TODO b/TODO index 9295486..46fe0fc 100644 --- a/TODO +++ b/TODO @@ -21,22 +21,22 @@ Music Menu # Add Folder # Add Playlists # Update Tracks from file -- Update mserv date from file -- Sync Playlists with Dir +# Update mserv date from file +# Sync Playlists with Dir # Export Tracks # Create Playlist -- Init ipod Directories -- Check ipod files +# Init ipod Directories +# Check ipod files Edit Menu -- Edit Track Details -- Edit Smart Playlist +# Edit Track Details +# Edit Smart Playlist (? Not Including) # Delete -- Create Playlists -- Sorting -- Randomize current playlist +# Create Playlists +# Sorting +# Randomize current playlist - Save Displayed track order -- Repo iPod Options +# Repo iPod Options # Preferences View Menu @@ -63,6 +63,9 @@ Tracks Plugin Sorttab Menu # popup menu +# Save on exit + +- Tools plugin - CoverArt Plugin - Filter Plugin - Progress bar for saving and lengthy operations diff --git a/libgtkpod/gtkpod_app_iface.c b/libgtkpod/gtkpod_app_iface.c index 2a5d41c..ba13de7 100644 --- a/libgtkpod/gtkpod_app_iface.c +++ b/libgtkpod/gtkpod_app_iface.c @@ -62,7 +62,7 @@ static void gtkpod_app_base_init(GtkPodAppInterface* klass) { = g_signal_new(SIGNAL_TRACK_UPDATED, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); gtkpod_app_signals[TRACKS_REORDERED] - = g_signal_new(SIGNAL_TRACKS_REORDERED, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + = g_signal_new(SIGNAL_TRACKS_REORDERED, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); gtkpod_app_signals[SORT_ENABLEMENT] = g_signal_new(SIGNAL_SORT_ENABLEMENT, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); @@ -80,13 +80,13 @@ static void gtkpod_app_base_init(GtkPodAppInterface* klass) { = g_signal_new(SIGNAL_ITDB_REMOVED, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); gtkpod_app_signals[PREFERENCE_CHANGE] - = g_signal_new(SIGNAL_PREFERENCE_CHANGE, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, _gtkpod_app_marshal_VOID__POINTER_INT, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_INT); + = g_signal_new(SIGNAL_PREFERENCE_CHANGE, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, _gtkpod_app_marshal_VOID__POINTER_INT, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_INT); gtkpod_app_signals[ITDB_DATA_CHANGED] - = g_signal_new(SIGNAL_ITDB_DATA_CHANGED, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); + = g_signal_new(SIGNAL_ITDB_DATA_CHANGED, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); gtkpod_app_signals[ITDB_DATA_SAVED] - = g_signal_new(SIGNAL_ITDB_DATA_SAVED, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); + = g_signal_new(SIGNAL_ITDB_DATA_SAVED, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); initialized = TRUE; } @@ -120,10 +120,44 @@ gchar* gtkpod_get_glade_xml() { } /** + * gtkpod_shutdown + * + * return value: TRUE if it's OK to quit. + */ +static gboolean ok_to_close_gtkpod(void) { + gint result = GTK_RESPONSE_OK; + + if (!files_are_saved()) { + const gchar + *str = + _("Data has been changed and not been saved. If you quit gtkpod, all unsaved changes will be lost.\n\nDo you want to save your changes first?"); + + result + = gtkpod_confirmation_hig(GTK_MESSAGE_WARNING, _("Save changes before quiting?"), str, GTK_STOCK_SAVE, GTK_STOCK_CANCEL, _("Quit without saving"), NULL); + } + + /* User pressed Cancel */ + if (result == GTK_RESPONSE_CANCEL) + return FALSE; + + /* User pressed Save */ + if (result == GTK_RESPONSE_OK) + handle_export(); + + return TRUE; +} + +/** * clean up bits n pieces */ -void gtkpod_cleanup_quit() { - gtkpod_shutdown(); +gint gtkpod_cleanup_quit() { + if (!widgets_blocked) { + if (ok_to_close_gtkpod()) { + gtkpod_shutdown(); + return TRUE; // Already to carry on quitting + } + } + return FALSE; // dont quit! } void gtkpod_statusbar_message(gchar* message, ...) { @@ -280,7 +314,7 @@ GList *gtkpod_get_displayed_tracks() { void gtkpod_set_displayed_tracks(GList *tracks) { g_return_if_fail (GTKPOD_IS_APP(gtkpod_app)); - GTKPOD_APP_GET_INTERFACE (gtkpod_app)->displayed_tracks = tracks; + GTKPOD_APP_GET_INTERFACE (gtkpod_app)->displayed_tracks = g_list_copy(tracks); g_signal_emit(gtkpod_app, gtkpod_app_signals[TRACKS_DISPLAYED], 0, tracks); } @@ -347,6 +381,9 @@ void gtkpod_broadcast_preference_change(gchar *preference_name, gint value) { void gtkpod_tracks_reordered() { g_return_if_fail (GTKPOD_IS_APP(gtkpod_app)); + g_return_if_fail (gtkpod_get_current_playlist()); + + gtkpod_set_displayed_tracks(gtkpod_get_current_playlist()->members); g_signal_emit(gtkpod_app, gtkpod_app_signals[TRACKS_REORDERED], 0); } diff --git a/libgtkpod/gtkpod_app_iface.h b/libgtkpod/gtkpod_app_iface.h index 1ddb63f..c018e47 100644 --- a/libgtkpod/gtkpod_app_iface.h +++ b/libgtkpod/gtkpod_app_iface.h @@ -151,7 +151,7 @@ void gp_init(GtkPodApp *window, int argc, char *argv[]); void gtkpod_app_set_glade_xml(gchar *xml_file); gchar* gtkpod_get_glade_xml(); -void gtkpod_cleanup_quit(); +gint gtkpod_cleanup_quit(); void gtkpod_statusbar_message(gchar* message, ...); void gtkpod_statusbar_busy_push(); diff --git a/plugins/core_preferences/core_prefs.h b/plugins/core_preferences/core_prefs.h index 0d62ca1..3494ead 100644 --- a/plugins/core_preferences/core_prefs.h +++ b/plugins/core_preferences/core_prefs.h @@ -27,8 +27,8 @@ | $Id$ */ -#ifndef __DETAILS_H__ -#define __DETAILS_H__ +#ifndef __CORE_PREFS_H__ +#define __CORE_PREFS_H__ #ifdef HAVE_CONFIG_H # include <config.h> diff --git a/plugins/details_editor/Makefile.am b/plugins/details_editor/Makefile.am index 17f76ce..4423e3a 100644 --- a/plugins/details_editor/Makefile.am +++ b/plugins/details_editor/Makefile.am @@ -26,7 +26,8 @@ plugin_LTLIBRARIES = libdetails_editor.la # Plugin sources libdetails_editor_la_SOURCES = plugin.c plugin.h \ - details.c details.h + details.c details.h \ + details_editor_actions.c details_editor_actions.h libdetails_editor_la_LDFLAGS = $(GTKPOD_PLUGIN_LDFLAGS) diff --git a/plugins/details_editor/details_editor.ui b/plugins/details_editor/details_editor.ui index 33f4355..6490e6f 100644 --- a/plugins/details_editor/details_editor.ui +++ b/plugins/details_editor/details_editor.ui @@ -1,9 +1,9 @@ <!--*- xml -*--> <ui> <menubar name="MenuMain"> - <menu name="MenuTools" action="ActionMenuTools"> - <placeholder name="PlaceholderToolsMenus"> - + <menu name="MenuEdit" action="ActionMenuEdit"> + <placeholder name="PlaceholderEditMenus"> + <menuitem name="Edit Track Details" action="ActionEditTrackDetails"/> </placeholder> </menu> </menubar> diff --git a/plugins/details_editor/details_editor_actions.c b/plugins/details_editor/details_editor_actions.c new file mode 100644 index 0000000..1e9532d --- /dev/null +++ b/plugins/details_editor/details_editor_actions.c @@ -0,0 +1,49 @@ +/* + | Copyright (C) 2002-2010 Jorg Schuler <jcsjcs at users sourceforge net> + | Paul Richardson <phantom_sf at users.sourceforge.net> + | Part of the gtkpod project. + | + | URL: http://www.gtkpod.org/ + | URL: http://gtkpod.sourceforge.net/ + | + | This program 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 2 of the License, or + | (at your option) any later version. + | + | This program 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 this program; if not, write to the Free Software + | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + | + | iTunes and iPod are trademarks of Apple + | + | This product is not supported/written/published by Apple! + | + | $Id$ + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "libgtkpod/gtkpod_app_iface.h" +#include "libgtkpod/misc.h" +#include "details.h" +#include "details_editor_actions.h" + +void on_edit_details_selected_tracks(GtkAction *action, DetailsEditorPlugin* plugin) { + GList *tracks = gtkpod_get_selected_tracks(); + + if (tracks) { + details_edit(tracks); + g_list_free(tracks); + } + else { + message_sb_no_tracks_selected(); + } +} diff --git a/plugins/details_editor/details_editor_actions.h b/plugins/details_editor/details_editor_actions.h new file mode 100644 index 0000000..1560e83 --- /dev/null +++ b/plugins/details_editor/details_editor_actions.h @@ -0,0 +1,41 @@ +/* +| Copyright (C) 2002-2010 Jorg Schuler <jcsjcs at users sourceforge net> +| Paul Richardson <phantom_sf at users.sourceforge.net> +| Part of the gtkpod project. +| +| URL: http://www.gtkpod.org/ +| URL: http://gtkpod.sourceforge.net/ +| +| This program 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 2 of the License, or +| (at your option) any later version. +| +| This program 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 this program; if not, write to the Free Software +| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +| +| iTunes and iPod are trademarks of Apple +| +| This product is not supported/written/published by Apple! +| +| $Id$ +*/ +#ifndef __DETAILS_EDITOR_ACTIONS_H__ +#define __DETAILS_EDITOR_ACTIONS_H__ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gtk/gtk.h> +#include "plugin.h" + +void on_edit_details_selected_tracks (GtkAction *action, DetailsEditorPlugin* plugin); + +#endif diff --git a/plugins/details_editor/plugin.c b/plugins/details_editor/plugin.c index 20158bd..401fc7a 100644 --- a/plugins/details_editor/plugin.c +++ b/plugins/details_editor/plugin.c @@ -34,12 +34,21 @@ #include "libgtkpod/gtkpod_app_iface.h" #include "plugin.h" #include "details.h" +#include "details_editor_actions.h" /* Parent class. Part of standard class definition */ static gpointer parent_class; static GtkActionEntry details_editor_actions[] = { + { + "ActionEditTrackDetails", /* Action name */ + GTK_STOCK_PREFERENCES, /* Stock icon */ + N_("Edit Track Details"), /* Display label */ + NULL, /* short-cut */ + NULL, /* Tooltip */ + G_CALLBACK (on_edit_details_selected_tracks) + }, }; static gboolean activate_plugin(AnjutaPlugin *plugin) { diff --git a/plugins/exporter/exporter_actions.h b/plugins/exporter/exporter_actions.h index ac2a846..97094c6 100644 --- a/plugins/exporter/exporter_actions.h +++ b/plugins/exporter/exporter_actions.h @@ -26,8 +26,8 @@ | | $Id$ */ -#ifndef __PLAYLIST_DISPLAY_H__ -#define __PLAYLIST_DISPLAY_H__ +#ifndef __EXPORTER_ACTIONS_H__ +#define __EXPORTED_ACTIONS_H__ #ifdef HAVE_CONFIG_H # include <config.h> diff --git a/plugins/playlist_display/playlist_display.ui b/plugins/playlist_display/playlist_display.ui index 0299c0d..90ad4a1 100644 --- a/plugins/playlist_display/playlist_display.ui +++ b/plugins/playlist_display/playlist_display.ui @@ -16,6 +16,7 @@ <menu name="Update mserv Data from File" action="ActionUpdateMservMenu"> <menuitem name="Selected Playlist" action="ActionUpdateMservPlaylist" /> </menu> + <menuitem name="Sync Playlist with Dir(s)" action="ActionSyncPlaylistWithDir"/> </placeholder> </menu> <menu name="MenuEdit" action="ActionMenuEdit"> @@ -25,6 +26,29 @@ <menuitem name="Selected Playlist including Tracks from Database" action="ActionDeleteSelectedPlaylistIncDb" /> <menuitem name="Selected Playlist including Tracks from Device" action="ActionDeleteSelectedPlaylistIncDev" /> </menu> + <separator/> + <menu name="Playlist Menu" action="NewPlaylistMenu"> + <menuitem name="Empty Playlist" action="ActionNewEmptyPlaylist"/> <!-- on_new_playlist1_activate" --> <!-- playlist --> + <menuitem name="Smart Playlist" action="ActionNewSmartPlaylist"/> <!-- on_smart_playlist_activate" --> + <menuitem name="Random Playlist from Displayed Tracks" action="ActionNewRandomPlaylist"/> <!-- on_random_playlist_activate --> + <menuitem name="Containing Displayed Tracks" action="ActionNewContainingDisplayedPlaylist"/> <!-- on_pl_containing_displayed_tracks_activate --> + <menuitem name="Containing Selected Tracks" action="ActionNewContainingSelectedPlaylist"/> <!-- on_pl_containing_selected_tracks_activate --> + <menuitem name="Best Rated Tracks" action="ActionNewBestRatedPlaylist"/> <!-- on_most_rated_tracks_playlist_s1_activate --> + <menuitem name="Tracks Most Often Listened To" action="ActionNewTracksMostOftenPlaylist"/> <!-- on_most_listened_tracks1_activate --> + <menuitem name="Most Recently Played Tracks" action="ActionNewMostRecentPlayledPlaylist"/> <!-- on_most_recent_played_tracks_activate --> + <menuitem name="All Tracks Played Since Last Time" action="ActionNewAllPlayedSinceLastTimePlaylist"/> <!-- on_played_since_last_time1_activate --> + <menuitem name="All Tracks Never Listened To" action="ActionNewAllNeverListenedPlaylist"/> <!-- on_all_tracks_never_listened_to1_activate --> + <menuitem name="All Tracks not Listed in any Playlist" action="ActionAllNeverListedPlaylist"/> <!-- on_all_tracks_not_listed_in_any_playlist1_activate --> + <separator/> + <menuitem name="One for each Artist" action="ActionNewOnePerArtistPlaylist"/> <!-- on_pl_for_each_artist_activate --> + <menuitem name="One for each Album" action="ActionNewOnePerAlbumPlaylist"/> <!-- on_pl_for_each_album_activate --> + <menuitem name="One for each Genre" action="ActionNewOnePerGenrePlaylist"/> <!-- on_pl_for_each_genre_activate --> + <menuitem name="One for each Composer" action="ActionNewOnePreComposerPlaylist"/> <!-- on_pl_for_each_composer_activate --> + <menuitem name="One for each Year" action="ActionNewOnePerYearPlaylist"/> <!-- on_pl_for_each_year_activate --> + <menuitem name="One for each Rating" action="ActionNewOnePerRatingPlaylist"/> <!-- on_pl_for_each_rating_activate --> + </menu> + <menuitem name="Randomize Current Playlist" action="ActionRandomizeCurrentPlaylist"/> + <separator/> </placeholder> </menu> </menubar> @@ -36,7 +60,7 @@ <toolitem name="Add Directory" action="ActionAddDirectory" /> <toolitem name="Add Playlist" action="ActionAddPlaylist" /> <toolitem name="New Playlist" action="ActionNewPlaylist"> - <menu name="test" action="NewPlaylistMenu"> + <menu name="Playlist Menu" action="NewPlaylistMenu"> <menuitem name="Empty Playlist" action="ActionNewEmptyPlaylist"/> <!-- on_new_playlist1_activate" --> <!-- playlist --> <menuitem name="Smart Playlist" action="ActionNewSmartPlaylist"/> <!-- on_smart_playlist_activate" --> <menuitem name="Random Playlist from Displayed Tracks" action="ActionNewRandomPlaylist"/> <!-- on_random_playlist_activate --> diff --git a/plugins/playlist_display/playlist_display_actions.c b/plugins/playlist_display/playlist_display_actions.c index 2987836..cc8e820 100644 --- a/plugins/playlist_display/playlist_display_actions.c +++ b/plugins/playlist_display/playlist_display_actions.c @@ -42,6 +42,7 @@ #include "libgtkpod/misc_playlist.h" #include "libgtkpod/gp_spl.h" #include "libgtkpod/file.h" +#include "libgtkpod/syncdir.h" #include <gdk/gdk.h> /* Callback after directories to add have been selected */ @@ -571,3 +572,13 @@ void on_update_mserv_selected_playlist (GtkAction *action, PlaylistDisplayPlugin mserv_from_file_tracks(pl->members); } } + +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_randomize_current_playlist(GtkAction *action, PlaylistDisplayPlugin* plugin) { + randomize_current_playlist(); +} diff --git a/plugins/playlist_display/playlist_display_actions.h b/plugins/playlist_display/playlist_display_actions.h index fb50dba..8b7ecc9 100644 --- a/plugins/playlist_display/playlist_display_actions.h +++ b/plugins/playlist_display/playlist_display_actions.h @@ -26,8 +26,8 @@ | | $Id$ */ -#ifndef __PLAYLIST_DISPLAY_H__ -#define __PLAYLIST_DISPLAY_H__ +#ifndef __PLAYLIST_DISPLAY_ACTIONS_H__ +#define __PLAYLIST_DISPLAY_ACTIONS_H__ #ifdef HAVE_CONFIG_H # include <config.h> @@ -68,5 +68,7 @@ void on_delete_selected_playlist_including_tracks_from_device(GtkAction *action, void on_update_selected_playlist (GtkAction *action, PlaylistDisplayPlugin* plugin); void on_update_mserv_selected_playlist (GtkAction *action, PlaylistDisplayPlugin* plugin); +void on_sync_playlist_with_dirs(GtkAction *action, PlaylistDisplayPlugin* plugin); +void on_randomize_current_playlist(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 e59d58f..1984f47 100644 --- a/plugins/playlist_display/playlist_display_context_menu.c +++ b/plugins/playlist_display/playlist_display_context_menu.c @@ -214,6 +214,12 @@ static void eject_ipod(GtkMenuItem *mi, gpointer data) { gp_eject_ipod(itdb); } +static void randomize_playlist(GtkMenuItem *mi, gpointer data) { + g_return_if_fail (gtkpod_get_current_playlist()); + + randomize_current_playlist(); +} + static GtkWidget *add_edit_ipod_properties(GtkWidget *menu) { if (!gtkpod_has_repository_editor()) return menu; @@ -247,6 +253,10 @@ static GtkWidget *add_eject_ipod(GtkWidget *menu) { return hookup_menu_item(menu, _("Eject iPod"), GTK_STOCK_DISCONNECT, G_CALLBACK (eject_ipod), NULL); } +static GtkWidget *add_randomize_playlist(GtkWidget *menu) { + return hookup_menu_item(menu, _("Randomize Tracks"), GTK_STOCK_DISCONNECT, G_CALLBACK (randomize_playlist), NULL); +} + void pm_context_menu_init(void) { GtkWidget *menu = NULL; Playlist *pl; @@ -278,6 +288,7 @@ void pm_context_menu_init(void) { if (eitdb->itdb_imported) { add_play_now(menu); add_enqueue(menu); + add_randomize_playlist(menu); add_update_tracks_from_file(menu); if (!pl->is_spl) { add_sync_playlist_with_dirs(menu); @@ -316,6 +327,7 @@ void pm_context_menu_init(void) { if (itdb->usertype & GP_ITDB_TYPE_LOCAL) { add_play_now(menu); add_enqueue(menu); + add_randomize_playlist(menu); add_update_tracks_from_file(menu); if (!pl->is_spl) { add_sync_playlist_with_dirs(menu); diff --git a/plugins/playlist_display/plugin.c b/plugins/playlist_display/plugin.c index 39125ad..3872b51 100644 --- a/plugins/playlist_display/plugin.c +++ b/plugins/playlist_display/plugin.c @@ -88,6 +88,14 @@ static GtkActionEntry playlist_actions[] = G_CALLBACK (on_create_add_playlists) /* callback */ }, { + "ActionSyncPlaylistWithDir", + GTK_STOCK_REFRESH, + N_("Sync Playlist with Dir(s)"), + NULL, + NULL, + G_CALLBACK (on_sync_playlist_with_dirs) + }, + { "NewPlaylistMenu", NULL, N_("_New Playlist Menu") @@ -267,6 +275,14 @@ static GtkActionEntry playlist_actions[] = NULL, NULL, G_CALLBACK (on_update_mserv_selected_playlist) + }, + { + "ActionRandomizeCurrentPlaylist", + NULL, + N_("Randomize Current Playlist"), + NULL, + NULL, + G_CALLBACK (on_randomize_current_playlist) } }; diff --git a/plugins/repository_editor/Makefile.am b/plugins/repository_editor/Makefile.am index baa9238..cf4feb6 100644 --- a/plugins/repository_editor/Makefile.am +++ b/plugins/repository_editor/Makefile.am @@ -27,6 +27,7 @@ plugin_LTLIBRARIES = librepository_editor.la # Plugin sources librepository_editor_la_SOURCES = plugin.c plugin.h \ repository.c repository.h \ + repository_actions.c repository_actions.h \ repository_init.c \ repository_editor.c \ repository_creator.c diff --git a/plugins/repository_editor/plugin.c b/plugins/repository_editor/plugin.c index ff94259..1854f44 100644 --- a/plugins/repository_editor/plugin.c +++ b/plugins/repository_editor/plugin.c @@ -34,13 +34,37 @@ #include "libgtkpod/gtkpod_app_iface.h" #include "plugin.h" #include "repository.h" +#include "repository_actions.h" /* Parent class. Part of standard class definition */ static gpointer parent_class; static GtkActionEntry repository_editor_actions[] = { - + { + "ActionInitRepository", + GTK_STOCK_EXECUTE, + N_("_Create iPod's Directories"), + NULL, + NULL, + G_CALLBACK (on_create_ipod_directories) + }, + { + "ActionCheckiPodFiles", + GTK_STOCK_FILE, + N_("_Check iPod's Files"), + NULL, + NULL, + G_CALLBACK (on_check_ipod_files) + }, + { + "ActionConfigRepositories", + GTK_STOCK_PREFERENCES, + N_("_Configure Repositories"), + NULL, + NULL, + G_CALLBACK (on_configure_repositories) + } }; static gboolean activate_plugin(AnjutaPlugin *plugin) { diff --git a/plugins/repository_editor/repository_actions.c b/plugins/repository_editor/repository_actions.c new file mode 100644 index 0000000..dc4c1e2 --- /dev/null +++ b/plugins/repository_editor/repository_actions.c @@ -0,0 +1,91 @@ +/* + | Copyright (C) 2002-2010 Jorg Schuler <jcsjcs at users sourceforge net> + | Paul Richardson <phantom_sf at users.sourceforge.net> + | Part of the gtkpod project. + | + | URL: http://www.gtkpod.org/ + | URL: http://gtkpod.sourceforge.net/ + | + | This program 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 2 of the License, or + | (at your option) any later version. + | + | This program 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 this program; if not, write to the Free Software + | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + | + | iTunes and iPod are trademarks of Apple + | + | This product is not supported/written/published by Apple! + | + | $Id$ + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "libgtkpod/itdb.h" +#include "libgtkpod/gtkpod_app_iface.h" +#include "libgtkpod/gp_itdb.h" +#include "libgtkpod/prefs.h" +#include "libgtkpod/misc.h" +#include "libgtkpod/misc_playlist.h" +#include "repository_actions.h" +#include "repository.h" + +void on_create_ipod_directories(GtkAction* action, RepositoryEditorPlugin* plugin) { + iTunesDB *itdb = gtkpod_get_current_itdb(); + if (!itdb) { + message_sb_no_ipod_itdb_selected(); + return; + } + + ExtraiTunesDBData *eitdb = itdb->userdata; + + g_return_if_fail (eitdb); + + if (!eitdb->itdb_imported) { + gchar *mountpoint = get_itdb_prefs_string(itdb, KEY_MOUNTPOINT); + gchar *str = g_strdup_printf(_("iPod at '%s' is not loaded.\nPlease load it first."), mountpoint); + gtkpod_warning(str); + g_free(str); + g_free(mountpoint); + } + else { + repository_ipod_init(itdb); + } +} + +void on_check_ipod_files(GtkAction* action, RepositoryEditorPlugin* plugin) { + iTunesDB *itdb = gtkpod_get_current_itdb(); + if (!itdb) { + message_sb_no_ipod_itdb_selected(); + return; + } + + ExtraiTunesDBData *eitdb = itdb->userdata; + + g_return_if_fail (eitdb); + + if (!eitdb->itdb_imported) { + gchar *mountpoint = get_itdb_prefs_string(itdb, KEY_MOUNTPOINT); + gchar *str = g_strdup_printf(_("iPod at '%s' is not loaded.\nPlease load it first."), mountpoint); + gtkpod_warning(str); + g_free(str); + g_free(mountpoint); + } + else { + check_db(itdb); + } +} + +void on_configure_repositories(GtkAction* action, RepositoryEditorPlugin* plugin) { + open_repository_editor(gtkpod_get_current_itdb(), gtkpod_get_current_playlist()); +} diff --git a/plugins/repository_editor/repository_actions.h b/plugins/repository_editor/repository_actions.h new file mode 100644 index 0000000..85d7420 --- /dev/null +++ b/plugins/repository_editor/repository_actions.h @@ -0,0 +1,43 @@ +/* +| Copyright (C) 2002-2010 Jorg Schuler <jcsjcs at users sourceforge net> +| Paul Richardson <phantom_sf at users.sourceforge.net> +| Part of the gtkpod project. +| +| URL: http://www.gtkpod.org/ +| URL: http://gtkpod.sourceforge.net/ +| +| This program 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 2 of the License, or +| (at your option) any later version. +| +| This program 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 this program; if not, write to the Free Software +| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +| +| iTunes and iPod are trademarks of Apple +| +| This product is not supported/written/published by Apple! +| +| $Id$ +*/ +#ifndef __REPOSITORY_ACTIONS_H__ +#define __REPOSITORY_ACTIONS_H__ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gtk/gtk.h> +#include "plugin.h" + +void on_create_ipod_directories(GtkAction* action, RepositoryEditorPlugin* plugin); +void on_check_ipod_files(GtkAction* action, RepositoryEditorPlugin* plugin); +void on_configure_repositories(GtkAction* action, RepositoryEditorPlugin* plugin); + +#endif diff --git a/plugins/repository_editor/repository_editor.ui b/plugins/repository_editor/repository_editor.ui index 33f4355..5e3dd14 100644 --- a/plugins/repository_editor/repository_editor.ui +++ b/plugins/repository_editor/repository_editor.ui @@ -1,9 +1,17 @@ <!--*- xml -*--> <ui> <menubar name="MenuMain"> - <menu name="MenuTools" action="ActionMenuTools"> - <placeholder name="PlaceholderToolsMenus"> - + <menu name="MenuMusic" action="ActionMenuMusic"> + <placeholder name="PlaceholderFileMenus"> + <separator/> + <menuitem name="Create iPod's Directories" action="ActionInitRepository" /> + <menuitem name="Check iPod's Files" action="ActionCheckiPodFiles" /> + <separator/> + </placeholder> + </menu> + <menu name="MenuEdit" action="ActionMenuEdit"> + <placeholder name="PlaceholderEditMenus"> + <menuitem name="Configure Repositories" action="ActionConfigRepositories"/> </placeholder> </menu> </menubar> diff --git a/plugins/sorttab_display/display_sorttabs.h b/plugins/sorttab_display/display_sorttabs.h index 5ace037..0ac9c09 100644 --- a/plugins/sorttab_display/display_sorttabs.h +++ b/plugins/sorttab_display/display_sorttabs.h @@ -27,8 +27,8 @@ | $Id$ */ -#ifndef __DISPLAY_SORTTAB_H__ -#define __DISPLAY_SORTTAB_H__ +#ifndef __DISPLAY_SORTTABS_H__ +#define __DISPLAY_SORTTABS_H__ #ifdef HAVE_CONFIG_H # include <config.h> diff --git a/plugins/sorttab_display/sorttab_display_actions.h b/plugins/sorttab_display/sorttab_display_actions.h index cb3226b..9fe84aa 100644 --- a/plugins/sorttab_display/sorttab_display_actions.h +++ b/plugins/sorttab_display/sorttab_display_actions.h @@ -26,8 +26,8 @@ | | $Id$ */ -#ifndef __SORTTAB_DISPLAY_H__ -#define __SORTTAB_DISPLAY_H__ +#ifndef __SORTTAB_DISPLAY_ACTIONS_H__ +#define __SORTTAB_DISPLAY_ACTIONS_H__ #ifdef HAVE_CONFIG_H # include <config.h> diff --git a/plugins/track_display/display_tracks.h b/plugins/track_display/display_tracks.h index f6244b0..2c85826 100644 --- a/plugins/track_display/display_tracks.h +++ b/plugins/track_display/display_tracks.h @@ -51,5 +51,6 @@ void track_display_set_sort_enablement(GtkPodApp *app, gboolean flag, gpointer d void track_display_track_removed_cb(GtkPodApp *app, gpointer tk, gint32 pos, gpointer data); void track_display_track_updated_cb(GtkPodApp *app, gpointer tk, gpointer data); void track_display_preference_changed_cb(GtkPodApp *app, gpointer pfname, gint32 value, gpointer data); +void track_display_tracks_reordered_cb(GtkPodApp *app, gpointer data); #endif /* DISPLAY_TRACKS_H_ */ diff --git a/plugins/track_display/plugin.c b/plugins/track_display/plugin.c index fd88e0c..6eb5709 100644 --- a/plugins/track_display/plugin.c +++ b/plugins/track_display/plugin.c @@ -87,6 +87,14 @@ static GtkActionEntry track_actions[] = NULL, NULL, G_CALLBACK (on_update_mserv_selected_tracks) + }, + { + "ActionChangeSortOrder", + NULL, + N_("Change Sort Order"), + NULL, + NULL, + G_CALLBACK (on_open_sort_window) } }; @@ -152,6 +160,7 @@ static gboolean activate_track_display_plugin(AnjutaPlugin *plugin) { g_signal_connect (gtkpod_app, SIGNAL_TRACK_REMOVED, G_CALLBACK (track_display_track_removed_cb), NULL); g_signal_connect (gtkpod_app, SIGNAL_TRACK_UPDATED, G_CALLBACK (track_display_track_updated_cb), NULL); g_signal_connect (gtkpod_app, SIGNAL_PREFERENCE_CHANGE, G_CALLBACK (track_display_preference_changed_cb), NULL); + g_signal_connect (gtkpod_app, SIGNAL_TRACKS_REORDERED, G_CALLBACK (track_display_tracks_reordered_cb), NULL); gtk_widget_show_all(track_display_plugin->track_window); anjuta_shell_add_widget(plugin->shell, track_display_plugin->track_window, "TrackDisplayPlugin", "Playlist Tracks", NULL, ANJUTA_SHELL_PLACEMENT_TOP, NULL); diff --git a/plugins/track_display/track_display.ui b/plugins/track_display/track_display.ui index 41fa764..fce895b 100644 --- a/plugins/track_display/track_display.ui +++ b/plugins/track_display/track_display.ui @@ -21,6 +21,7 @@ <menuitem name="Selected Tracks from Device" action="ActionDeleteSelectedTracksFromDevice" /> <separator name="separator2" /> </menu> + <menuitem name="Change Sort Orders" action="ActionChangeSortOrder"/> </placeholder> </menu> </menubar> diff --git a/plugins/track_display/track_display_actions.c b/plugins/track_display/track_display_actions.c index 243f6c9..b90597d 100644 --- a/plugins/track_display/track_display_actions.c +++ b/plugins/track_display/track_display_actions.c @@ -33,6 +33,7 @@ #include "track_display_actions.h" #include "display_tracks.h" +#include "sort_window.h" #include "libgtkpod/misc.h" #include "libgtkpod/misc_track.h" #include "libgtkpod/file.h" @@ -93,3 +94,7 @@ void on_update_mserv_selected_tracks (GtkAction *action, TrackDisplayPlugin* plu mserv_from_file_tracks(tracks); } } + +void on_open_sort_window (GtkAction *action, TrackDisplayPlugin* plugin) { + sort_window_create(); +} diff --git a/plugins/track_display/track_display_actions.h b/plugins/track_display/track_display_actions.h index 6979322..62f4b71 100644 --- a/plugins/track_display/track_display_actions.h +++ b/plugins/track_display/track_display_actions.h @@ -26,8 +26,8 @@ | | $Id$ */ -#ifndef __TRACK_DISPLAY_H__ -#define __TRACK_DISPLAY_H__ +#ifndef __TRACK_DISPLAY_ACTIONS_H__ +#define __TRACK_DISPLAY_ACTIONS_H__ #ifdef HAVE_CONFIG_H # include <config.h> @@ -43,5 +43,6 @@ void on_delete_selected_tracks_from_ipod(GtkAction *action, TrackDisplayPlugin* void on_delete_selected_tracks_from_device(GtkAction *action, TrackDisplayPlugin* plugin); void on_update_selected_tracks (GtkAction *action, TrackDisplayPlugin* plugin); void on_update_mserv_selected_tracks (GtkAction *action, TrackDisplayPlugin* plugin); +void on_open_sort_window (GtkAction *action, TrackDisplayPlugin* plugin); #endif diff --git a/src/display_tracks.c b/src/display_tracks.c index eb57f43..23ebeb4 100644 --- a/src/display_tracks.c +++ b/src/display_tracks.c @@ -1261,6 +1261,24 @@ static gint comp_int(gconstpointer a, gconstpointer b) { return (GPOINTER_TO_INT(a) - (GPOINTER_TO_INT(b))); } +/* Redisplays the tracks in the track view according to the order + * stored in the sort tab view. This only works if the track view is + * not sorted --> skip if sorted */ + +static void tm_adopt_order(void) { + if (prefs_get_int("tm_sort") == SORT_NONE) { + GList *gl, *tracks = NULL; + + /* retrieve the currently displayed tracks (non ordered) from + the last sort tab or from the selected playlist if no sort + tabs are being used */ + tm_remove_all_tracks(); + tracks = gtkpod_get_displayed_tracks(); + for (gl = tracks; gl; gl = gl->next) + tm_add_track_to_track_model((Track *) gl->data, NULL); + } +} + /** * Reorder tracks in playlist to match order of tracks displayed in track * view. Only the subset of tracks currently displayed is reordered. @@ -1342,7 +1360,7 @@ void tm_rows_reordered(void) { sort tabs */ if (changed) { data_changed(itdb); - gtkpod_tracks_reordered(); + tm_adopt_order(); } } } @@ -1744,24 +1762,6 @@ gint tm_sort_counter(gint inc) { return cnt; } -/* Redisplays the tracks in the track view according to the order - * stored in the sort tab view. This only works if the track view is - * not sorted --> skip if sorted */ - -void tm_adopt_order_in_sorttab(void) { - if (prefs_get_int("tm_sort") == SORT_NONE) { - GList *gl, *tracks = NULL; - - /* retrieve the currently displayed tracks (non ordered) from - the last sort tab or from the selected playlist if no sort - tabs are being used */ - tm_remove_all_tracks(); - tracks = gtkpod_get_displayed_tracks(); - for (gl = tracks; gl; gl = gl->next) - tm_add_track_to_track_model((Track *) gl->data, NULL); - } -} - /* redisplay the contents of the track view in it's unsorted order */ static void tm_unsort(void) { if (track_treeview) { @@ -1778,7 +1778,7 @@ static void tm_unsort(void) { /* gtk_tree_view_set_enable_search (GTK_TREE_VIEW * (track_treeview), FALSE);*/ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (model), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING); - tm_adopt_order_in_sorttab(); + tm_adopt_order(); } else { gtkpod_warning(_("Cannot unsort track view because of a bug in the GTK lib you are using (%d.%d.%d < 2.5.4). Once you sort the track view, you cannot go back to the unsorted state.\n\n"), gtk_major_version, gtk_minor_version, gtk_micro_version); @@ -2739,3 +2739,12 @@ void track_display_preference_changed_cb(GtkPodApp *app, gpointer pfname, gint32 } } +void track_display_tracks_reordered_cb(GtkPodApp *app, gpointer data) { + if (prefs_get_int("tm_autostore")) { + prefs_set_int("tm_autostore", FALSE); + gtkpod_warning(_("Auto Store of track view disabled.\n\n")); + } + + tm_adopt_order(); +} + diff --git a/src/gtkpod.c b/src/gtkpod.c index 37525fe..6886c7c 100644 --- a/src/gtkpod.c +++ b/src/gtkpod.c @@ -181,13 +181,11 @@ void gtkpod_init(int argc, char *argv[]) { /* callback for gtkpod window's close button */ static gboolean on_gtkpod_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { - // if (!widgets_blocked) { - // if (ok_to_close_gtkpod()) { - // gtkpod_shutdown(); - // /* returning FALSE to continue calling other handlers - // causes tons of errors. */ - // } - // } + + if (! gtkpod_cleanup_quit()) { + // Dont want to quit so avoid signalling any destroy event + return TRUE; + } AnjutaPluginManager *plugin_manager; AnjutaProfileManager *profile_manager; @@ -264,7 +262,6 @@ static gboolean on_gtkpod_delete_event(GtkWidget *widget, GdkEvent *event, gpoin } static void on_gtkpod_destroy(GtkWidget * w, gpointer data) { - gtkpod_cleanup_quit(); gtk_widget_hide(w); gtk_main_quit(); } diff --git a/src/misc.c b/src/misc.c index 96762f4..ec86b38 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1833,6 +1833,5 @@ void gtkpod_shutdown() { mp4_close(); call_script("gtkpod.out", NULL); - gtk_main_quit(); } diff --git a/src/misc.h b/src/misc.h index 883952d..1ef83e8 100644 --- a/src/misc.h +++ b/src/misc.h @@ -224,6 +224,7 @@ void delete_populate_settings(struct DeleteData *dd, gchar **label, gchar **titl void message_sb_no_itdb_selected (); void message_sb_no_playlist_selected (); void message_sb_no_tracks_selected (); +void message_sb_no_ipod_itdb_selected (); void gtkpod_shutdown (); diff --git a/src/misc_playlist.c b/src/misc_playlist.c index 0589674..b6e1a9a 100644 --- a/src/misc_playlist.c +++ b/src/misc_playlist.c @@ -251,26 +251,18 @@ Playlist *generate_random_playlist(iTunesDB *itdb) { } void randomize_current_playlist(void) { - g_message("TODO randomize_current_playlist commented out\n"); - // Playlist *pl= pm_get_selected_playlist (); - // - // if (!pl) - // { - // message_sb_no_playlist_selected (); - // return; - // } - // - // if (prefs_get_int("tm_autostore")) - // { - // prefs_set_int("tm_autostore", FALSE); - // gtkpod_warning (_("Auto Store of track view disabled.\n\n")); - ///* sort_window_update (); */ - // } - // - // itdb_playlist_randomize (pl); - // - // st_adopt_order_in_playlist (); - // tm_adopt_order_in_sorttab (); + Playlist *pl = gtkpod_get_current_playlist(); + + if (!pl) { + message_sb_no_playlist_selected(); + return; + } + + gtkpod_set_selected_tracks(NULL); + + itdb_playlist_randomize(pl); + + gtkpod_tracks_reordered(); } static void not_listed_make_track_list(gpointer key, gpointer track, gpointer tracks) { @@ -902,8 +894,6 @@ void check_db(iTunesDB *itdb) { } } - g_message("TODO check_db - status\n"); - // gtkpod_statusbar_timeout (30*STATUSBAR_TIMEOUT); block_widgets(); gtkpod_statusbar_message(_("Creating a tree of known files")); @@ -1462,3 +1452,7 @@ void message_sb_no_itdb_selected() { void message_sb_no_playlist_selected() { gtkpod_statusbar_message(_("No playlist selected")); } + +void message_sb_no_ipod_itdb_selected() { + gtkpod_statusbar_message(_("No iPod or iPod playlist selected")); +} diff --git a/src/sort_window.h b/src/sort_window.h index 5e5e391..79f9637 100644 --- a/src/sort_window.h +++ b/src/sort_window.h @@ -27,8 +27,8 @@ | | $Id$ */ -#ifndef _GTKPOD_PREFS_WINDOW_H -#define _GTKPOD_PREFS_WINDOW_H +#ifndef _SORT_WINDOW_H +#define _SORT_WINDOW_H #include <gtk/gtk.h> #include "libgtkpod/prefs.h" ------------------------------------------------------------------------------ _______________________________________________ gtkpod-cvs2 mailing list gtkpod-cvs2@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2