You can subscribe to this list here.
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(132) |
Dec
(135) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
(87) |
Feb
(82) |
Mar
(117) |
Apr
(108) |
May
(231) |
Jun
(265) |
Jul
(31) |
Aug
(32) |
Sep
(89) |
Oct
(50) |
Nov
(112) |
Dec
(92) |
2007 |
Jan
(136) |
Feb
(82) |
Mar
(66) |
Apr
(104) |
May
(74) |
Jun
(103) |
Jul
(50) |
Aug
(23) |
Sep
(22) |
Oct
(39) |
Nov
(56) |
Dec
(88) |
2008 |
Jan
(51) |
Feb
(6) |
Mar
(6) |
Apr
(9) |
May
(39) |
Jun
(24) |
Jul
(48) |
Aug
(40) |
Sep
(9) |
Oct
(21) |
Nov
(12) |
Dec
(31) |
2009 |
Jan
(68) |
Feb
(14) |
Mar
(29) |
Apr
(40) |
May
(27) |
Jun
(9) |
Jul
(1) |
Aug
(10) |
Sep
(3) |
Oct
(7) |
Nov
(11) |
Dec
(165) |
2010 |
Jan
(72) |
Feb
(49) |
Mar
(30) |
Apr
(41) |
May
(17) |
Jun
(13) |
Jul
(99) |
Aug
(88) |
Sep
(59) |
Oct
(23) |
Nov
(11) |
Dec
(44) |
2011 |
Jan
(50) |
Feb
(28) |
Mar
(27) |
Apr
(18) |
May
(38) |
Jun
(5) |
Jul
(59) |
Aug
(7) |
Sep
(44) |
Oct
(12) |
Nov
(7) |
Dec
(10) |
2012 |
Jan
(8) |
Feb
(11) |
Mar
(17) |
Apr
(11) |
May
(3) |
Jun
(11) |
Jul
(26) |
Aug
(3) |
Sep
|
Oct
(17) |
Nov
(9) |
Dec
(1) |
2013 |
Jan
|
Feb
(5) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: dforsi <df...@us...> - 2012-07-12 15:22:38
|
commit 68b60ca5877a2aeb978a3c0fc3c6518c31dc6220 Author: Daniele Forsi <da...@fo...> Date: Thu Jul 12 14:03:21 2012 +0200 Do not accept empty names for smart playlists Make the "Save" button insensitive if the name is empty. plugins/playlist_display/playlist_display_spl.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-) --- diff --git a/plugins/playlist_display/playlist_display_spl.c b/plugins/playlist_display/playlist_display_spl.c index c131c35..695e396 100644 --- a/plugins/playlist_display/playlist_display_spl.c +++ b/plugins/playlist_display/playlist_display_spl.c @@ -336,6 +336,14 @@ static void spl_set_combobox(GtkComboBox *cb, const ComboEntry centries[], guint } +static void spl_name_entry_changed(GtkEntry *entry, GtkWidget *button) { + g_return_if_fail (button); + if (gtk_entry_get_text_length (entry) >= 1) + gtk_widget_set_sensitive(button, TRUE); + else + gtk_widget_set_sensitive(button, FALSE); +} + static void spl_matchcheckedonly_toggled(GtkToggleButton *togglebutton, GtkWidget *spl_window) { Playlist *spl; @@ -1386,6 +1394,9 @@ static void spl_edit_all(iTunesDB *itdb, Playlist *spl, gint32 pos) { /* Set checkboxes and connect signal handlers */ if ((w = gtkpod_builder_xml_get_widget(spl_wizard->builder, "spl_name_entry"))) { + g_signal_connect (w, "changed", + G_CALLBACK (spl_name_entry_changed), + gtkpod_builder_xml_get_widget(spl_wizard->builder, "spl_ok_button")); if (spl_dup->name) gtk_entry_set_text(GTK_ENTRY (w), spl_dup->name); } |
From: dforsi <df...@us...> - 2012-07-12 15:22:32
|
commit 9729176e98956eb5b4988c371146424e703d80a0 Author: Daniele Forsi <da...@fo...> Date: Thu Jul 12 12:36:39 2012 +0200 Make it easier for the user to retry entering a valid playlist name Automatically ask again a name if the one provided by the user was empty or duplicated. plugins/playlist_display/playlist_display_spl.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) --- diff --git a/plugins/playlist_display/playlist_display_spl.c b/plugins/playlist_display/playlist_display_spl.c index d6ceee1..c131c35 100644 --- a/plugins/playlist_display/playlist_display_spl.c +++ b/plugins/playlist_display/playlist_display_spl.c @@ -1504,20 +1504,22 @@ void add_new_pl_or_spl_user_name(iTunesDB *itdb, gchar *dflt, gint32 position) { return; } + name = dflt ? dflt : _("New Playlist"); +retry: name - = get_user_string(_("New Playlist"), _("Please enter a name for the new playlist"), dflt ? dflt : _("New Playlist"), _("Smart Playlist"), &is_spl, GTK_STOCK_ADD); + = get_user_string(_("New Playlist"), _("Please enter a name for the new playlist"), name, _("Smart Playlist"), &is_spl, GTK_STOCK_ADD); if (!name) return; if (strlen(name) == 0) { gtkpod_warning_simple(_("Playlist name cannot be blank")); - return; + goto retry; } Playlist *pl = itdb_playlist_by_name(itdb, name); if (pl) { gtkpod_warning_simple(_("A playlist named '%s' already exists"), name); - return; + goto retry; } if (!is_spl) { /* add standard playlist */ |
From: dforsi <df...@us...> - 2012-07-12 15:22:26
|
commit 6e72f43fa4db515b729337debc4b786ee5bca51d Author: Daniele Forsi <da...@fo...> Date: Thu Jul 12 12:18:58 2012 +0200 Don't check twice if name is NULL It is already checked after calling get_user_string(). plugins/playlist_display/playlist_display_spl.c | 14 ++++++-------- 1 files changed, 6 insertions(+), 8 deletions(-) --- diff --git a/plugins/playlist_display/playlist_display_spl.c b/plugins/playlist_display/playlist_display_spl.c index 42cb6dc..d6ceee1 100644 --- a/plugins/playlist_display/playlist_display_spl.c +++ b/plugins/playlist_display/playlist_display_spl.c @@ -1520,14 +1520,12 @@ void add_new_pl_or_spl_user_name(iTunesDB *itdb, gchar *dflt, gint32 position) { return; } - if (name) { - if (!is_spl) { /* add standard playlist */ - gp_playlist_add_new(itdb, name, FALSE, position); - gtkpod_tracks_statusbar_update (); - } - else { /* add smart playlist */ - spl_edit_new(itdb, name, position); - } + if (!is_spl) { /* add standard playlist */ + gp_playlist_add_new(itdb, name, FALSE, position); + gtkpod_tracks_statusbar_update (); + } + else { /* add smart playlist */ + spl_edit_new(itdb, name, position); } } |
From: dforsi <df...@us...> - 2012-07-12 09:48:25
|
commit 4641514a85ef2898b6328c9ea1b0d2dfd0229536 Author: Daniele Forsi <da...@fo...> Date: Thu Jul 12 11:32:01 2012 +0200 Fix setting default width of main window Only used when window Geometry couldn't be read from ~/.gtkpod/session/anjuta.session file. src/anjuta-app.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) --- diff --git a/src/anjuta-app.c b/src/anjuta-app.c index b78e345..9f4d6db 100644 --- a/src/anjuta-app.c +++ b/src/anjuta-app.c @@ -650,7 +650,7 @@ void anjuta_app_set_geometry(AnjutaApp *app, const gchar *geometry) { width = gdk_screen_width() - 10; height = gdk_screen_height() - 25; width = (width < 790) ? width : 790; - height = (height < 575) ? width : 575; + height = (height < 575) ? height : 575; if (gtk_widget_get_realized (GTK_WIDGET (app)) == FALSE) { gtk_window_set_default_size(GTK_WINDOW (app), width, height); gtk_window_move(GTK_WINDOW (app), posx, posy); |
From: dforsi <df...@us...> - 2012-07-11 16:21:29
|
commit e8df41ea903485e65d3ce6f34f3a1719d9b70420 Author: Daniele Forsi <da...@fo...> Date: Wed Jul 11 18:14:16 2012 +0200 Actually use the translation and change capitalization The N_() macro only marks a string for translation but it's a noop at compile time. src/main.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) --- diff --git a/src/main.c b/src/main.c index 8be6dfe..1dd44d7 100644 --- a/src/main.c +++ b/src/main.c @@ -78,7 +78,7 @@ main (int argc, char *argv[]) gtk_init (&argc, &argv); #endif - ctx = g_option_context_new (N_("- Interface with your ipod")); + ctx = g_option_context_new (_("- Interface with your iPod")); g_option_context_add_group (ctx, gtk_get_option_group (TRUE)); #ifdef HAVE_GSTREAMER |
From: dforsi <df...@us...> - 2012-07-11 13:14:23
|
commit 277f24deb663c3960c583d2ba920481ab60148fe Author: Daniele Forsi <da...@fo...> Date: Wed Jul 11 13:50:11 2012 +0200 Make more strings translatable libgtkpod/context_menus.c | 2 +- .../playlist_display_context_menu.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) --- diff --git a/libgtkpod/context_menus.c b/libgtkpod/context_menus.c index 1a56c90..dfe42e0 100644 --- a/libgtkpod/context_menus.c +++ b/libgtkpod/context_menus.c @@ -122,7 +122,7 @@ GtkWidget *add_exec_commands(GtkWidget *menu) { mm = menu; } else { - GtkWidget *submenu = add_sub_menu(menu, "Execute", GTK_STOCK_EXECUTE); + GtkWidget *submenu = add_sub_menu(menu, _("Execute"), GTK_STOCK_EXECUTE); mm = submenu; } diff --git a/plugins/playlist_display/playlist_display_context_menu.c b/plugins/playlist_display/playlist_display_context_menu.c index 72b1bf5..2bfc7f9 100644 --- a/plugins/playlist_display/playlist_display_context_menu.c +++ b/plugins/playlist_display/playlist_display_context_menu.c @@ -378,7 +378,7 @@ static void _populate_single_playlist_menu(GtkWidget *menu) { add_delete_all_podcasts_from_ipod(menu); } else { - GtkWidget *delete_menu = add_sub_menu(menu, "Delete", GTK_STOCK_DELETE); + 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); } @@ -419,7 +419,7 @@ static void _populate_single_playlist_menu(GtkWidget *menu) { add_delete_all_tracks_from_database(menu); } else { - GtkWidget *delete_menu = add_sub_menu(menu, "Delete", GTK_STOCK_DELETE); + GtkWidget *delete_menu = add_sub_menu(menu, _("Delete"), GTK_STOCK_DELETE); add_delete_playlist_including_tracks_database(delete_menu); add_delete_playlist_including_tracks_harddisk(delete_menu); add_delete_playlist_but_keep_tracks(delete_menu); @@ -451,7 +451,7 @@ static void _populate_single_playlist_menu(GtkWidget *menu) { static void _populate_multi_playlist_menu(GtkWidget *menu) { - GtkWidget *delete_menu = add_sub_menu(menu, "Delete", GTK_STOCK_DELETE); + 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); |
From: dforsi <df...@us...> - 2012-07-11 13:14:16
|
commit ab2acf1fff26cf5354bdbbf256fa57a292d8124d Author: Daniele Forsi <da...@fo...> Date: Sun Jul 8 18:52:29 2012 +0200 Add missing newlines to a message string libgtkpod/tools.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) --- diff --git a/libgtkpod/tools.c b/libgtkpod/tools.c index 19e15e1..27a6a06 100644 --- a/libgtkpod/tools.c +++ b/libgtkpod/tools.c @@ -339,9 +339,9 @@ static gboolean nm_get_soundcheck(Track *track, GError **error) { } } else { - buf = g_strdup_printf(_("Normalization failed for file %s: file type not supported." - "To normalize mp3 and aac files ensure the following commands paths have been set in the Tools section" - "\tmp3 files: mp3gain" + buf = g_strdup_printf(_("Normalization failed for file %s: file type not supported.\n" + "To normalize mp3 and aac files ensure the following commands paths have been set in the Tools section\n" + "\tmp3 files: mp3gain\n" "\taac files: aacgain"), path); gtkpod_log_error(error, buf); g_free(buf); |
From: dforsi <df...@us...> - 2012-07-11 13:14:10
|
commit 1d74b254dc47b945d072812ed8e0ef3c89424b6b Author: Daniele Forsi <da...@fo...> Date: Sun Jul 8 18:44:04 2012 +0200 Use the spelling "Normalize" like in other strings plugins/track_display/plugin.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) --- diff --git a/plugins/track_display/plugin.c b/plugins/track_display/plugin.c index a0e1e65..3b57113 100644 --- a/plugins/track_display/plugin.c +++ b/plugins/track_display/plugin.c @@ -216,7 +216,7 @@ static void ipreferences_iface_init(IAnjutaPreferencesIface* iface) { static void track_command_iface_init(TrackCommandInterface *iface) { iface->id = "track_display_normalise_track_command"; - iface->text = _("Normalise"); + iface->text = _("Normalize"); iface->execute = nm_tracks_list; } |
From: phantomjinx <pha...@us...> - 2012-07-11 09:14:04
|
commit 70a777bd7e51a4c76c15a905dfa2478a20e5aa1f Author: phantomjinx <p.g...@ph...> Date: Mon Jul 9 22:33:34 2012 +0100 Fix an identified buffer overflow 3536102 - Buffer overflow in atomic parsley libs/atomic-parsley/AtomicParsley.cpp | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) --- diff --git a/libs/atomic-parsley/AtomicParsley.cpp b/libs/atomic-parsley/AtomicParsley.cpp index 8603885..69830d5 100644 --- a/libs/atomic-parsley/AtomicParsley.cpp +++ b/libs/atomic-parsley/AtomicParsley.cpp @@ -1887,7 +1887,7 @@ char* APar_ExtractDataAtom(int this_atom_number) { } else { //purl & egid would end up here too, but Apple switched it to a text string (0x00), so gets taken care above explicitly - char* result = (char*) malloc(sizeof(char) * 6); + char* result = (char*) malloc(sizeof(char) * 7); sprintf(result, "hex 0x"); for (int hexx = 1; hexx <= (int) (thisAtom->AtomicLength - atom_header_size); ++hexx) { |
From: phantomjinx <pha...@us...> - 2012-07-11 09:13:58
|
commit 3efad8785222434724235b9c9a2a4617bf78af35 Author: phantomjinx <p.g...@ph...> Date: Mon Jul 9 21:42:43 2012 +0100 Register all upper case version of filetype suffixes * Should files have upper case file type suffixes then such files are not recognised by the filetype plugins. * Registers each filetype plugin against all suffixes and their upper case versions. 3538271 - MP3 extensions do not get loaded libgtkpod/gtkpod_app_iface.c | 17 ++++++++++++++++- 1 files changed, 16 insertions(+), 1 deletions(-) --- diff --git a/libgtkpod/gtkpod_app_iface.c b/libgtkpod/gtkpod_app_iface.c index e161e7a..61df6fa 100644 --- a/libgtkpod/gtkpod_app_iface.c +++ b/libgtkpod/gtkpod_app_iface.c @@ -669,7 +669,9 @@ void gtkpod_register_filetype(FileType *filetype) { s = suffixes; while(s) { + gchar *uc = g_ascii_strup(s->data, -1); g_hash_table_insert(gp_iface->filetypes, s->data, filetype); + g_hash_table_insert(gp_iface->filetypes, uc, filetype); s = g_list_next(s); } } @@ -679,7 +681,20 @@ void gtkpod_unregister_filetype(FileType *filetype) { g_return_if_fail(GTKPOD_IS_APP(gtkpod_app)); GtkPodAppInterface *gp_iface = GTKPOD_APP_GET_INTERFACE (gtkpod_app); - g_hash_table_remove(gp_iface->filetypes, filetype_get_name(filetype)); + GList *s; + + GList *suffixes = filetype_get_suffixes(filetype); + if (!suffixes) + return; + + s = suffixes; + while(s) { + gchar *uc = g_ascii_strup(s->data, -1); + g_hash_table_remove(gp_iface->filetypes, s->data); + g_hash_table_remove(gp_iface->filetypes, uc); + s = g_list_next(s); + g_free(uc); + } } gboolean gtkpod_filetype_is_supported(gchar *name) { |
From: phantomjinx <pha...@us...> - 2012-07-09 19:09:52
|
commit e373e21a4930b117ffa6b3c3f63eb3bee82d2be4 Author: phantomjinx <p.g...@ph...> Date: Thu Jun 28 09:33:20 2012 +0100 Update version script to 2.1.3 version.sh | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) --- diff --git a/version.sh b/version.sh index 024ea41..f90773b 100755 --- a/version.sh +++ b/version.sh @@ -4,10 +4,10 @@ if [ -d .git ]; then COMMIT=`git rev-parse --short HEAD` # Use this line for unstable dev builds - REVISION="2.1.2~${COMMIT}" + REVISION="2.1.3~${COMMIT}" # Use this line for releases - #REVISION="2.1.2" + #REVISION="2.1.3" echo $REVISION > version fi |
From: phantomjinx <pha...@us...> - 2012-06-28 08:31:57
|
commit ad7653e188ae268e88379fc9d6f9953fc7eafc9f Author: phantomjinx <p.g...@ph...> Date: Sun Jun 17 21:34:24 2012 +0100 Update Changelog * Release 2.1.2 ChangeLog | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-) --- diff --git a/ChangeLog b/ChangeLog index 3001490..b949316 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +phantomjinx <p.g...@ph...> 2012-06-17 + + Update Changelog + + * Release 2.1.2 + +phantomjinx <p.g...@ph...> 2012-06-11 + + Avoid Creating new uint definitions + + * Include stdint.h in AP_commons.h instead + + * Allows compilation of freebsd + + * Thanks to Matteo <mfv.debian at gmail.com> for the investigation and + patch + phantomjinx <p.g...@ph...> 2012-06-01 Update Changelog |
From: phantomjinx <pha...@us...> - 2012-06-28 08:31:11
|
The unsigned tag 'gtkpod-2.1.2' was created. Tagger: phantomjinx <p.g...@ph...> Date: Thu Jun 28 09:29:28 2012 +0100 gtkpod-2.1.2 Changes since the last tag 'gtkpod-2.1.2-beta2': phantomjinx (2): Avoid Creating new uint definitions Update Changelog |
From: phantomjinx <pha...@us...> - 2012-06-11 21:39:38
|
commit f6a1f020d78c5e26b1dfe519a5d0ccbc8c4b7b38 Author: phantomjinx <p.g...@ph...> Date: Mon Jun 11 22:38:26 2012 +0100 Avoid Creating new uint definitions * Include stdint.h in AP_commons.h instead * Allows compilation of freebsd * Thanks to Matteo <mfv.debian at gmail.com> for the investigation and patch libs/atomic-parsley/AP_commons.h | 31 +------------------------------ 1 files changed, 1 insertions(+), 30 deletions(-) --- diff --git a/libs/atomic-parsley/AP_commons.h b/libs/atomic-parsley/AP_commons.h index a9f061b..ddd13c7 100644 --- a/libs/atomic-parsley/AP_commons.h +++ b/libs/atomic-parsley/AP_commons.h @@ -20,36 +20,7 @@ //==================================================================// #include <sys/types.h> #include <sys/stat.h> - -#ifndef _UINT8_T -#define _UINT8_T -typedef unsigned char uint8_t; -#endif /*_UINT8_T */ - -#ifndef _UINT16_T -#define _UINT16_T -typedef unsigned short uint16_t; -#endif /* _UINT16_T */ - -#ifndef _UINT32_T -#ifndef __uint32_t_defined -typedef unsigned int uint32_t; -#endif -#endif /*_UINT32_T */ - -#ifndef _UINT64_T -#define _UINT64_T -#if defined (_MSC_VER) -typedef unsigned __int64 uint64_t; -#else -typedef unsigned long long uint64_t; -#endif /* _MSC_VER */ -#endif /* _UINT64_T */ - -#ifndef _INT16_T -#define _INT16_T -typedef short int16_t; -#endif /* _INT16_T */ +#include <stdint.h> #if defined (__ppc__) || defined (__ppc64__) #define SWAP16(x) (x) |
From: phantomjinx <pha...@us...> - 2012-06-04 21:59:00
|
The unsigned tag 'gtkpod-2.1.2-beta2' was created. Tagger: phantomjinx <p.g...@ph...> Date: Mon Jun 4 22:41:15 2012 +0100 gtkpod-2.1.2-beta2 Changes since the last tag 'gtkpod-2.1.2-beta1': phantomjinx (4): Modifications due to change in gthreads API Change to anjuta preference creation causing crash in pref dialog Fix typo for musicbrainz3 compilation option Update Changelog |
From: phantomjinx <pha...@us...> - 2012-06-01 22:10:25
|
commit bafd316c2ef14cb3bde6c1e01d15d56857590621 Author: phantomjinx <p.g...@ph...> Date: Fri Jun 1 23:06:58 2012 +0100 Update Changelog ChangeLog | 29 ++++++++++++++++++++++++++++- 1 files changed, 28 insertions(+), 1 deletions(-) --- diff --git a/ChangeLog b/ChangeLog index 5abb28f..3001490 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,31 @@ -phantomjinx <p.g...@ph...> 2012-05-12 +phantomjinx <p.g...@ph...> 2012-06-01 + + Update Changelog + +phantomjinx <p.g...@ph...> 2012-06-01 + + Fix typo for musicbrainz3 compilation option + +phantomjinx <p.g...@ph...> 2012-05-31 + + Change to anjuta preference creation causing crash in pref dialog + + * The use of anjuta_prefences_add_from_builder assumes all the widgets in + the builder have related preferences in the gsettings of the core gtkpod + xml. The disable_splash_screen is not in there as it is from .prefs. + + * Reverts modifications made by f671cc889 with a little bit of tidying up + +phantomjinx <p.g...@ph...> 2012-05-31 + + Modifications due to change in gthreads API + + * Threading API in glib-2.0 < 2.31 has been deprecated so must be + migrated to new API. + + * Preserves backward compatibility with glib-2.0 < 2.31 + +phantomjinx <p.g...@ph...> 2012-05-25 Updates NEWS and Changelog |
From: phantomjinx <pha...@us...> - 2012-06-01 22:10:19
|
commit 3e1a304b8908fff8ec7a11ecb94322ee5a9cd085 Author: phantomjinx <p.g...@ph...> Date: Fri Jun 1 23:01:53 2012 +0100 Fix typo for musicbrainz3 compilation option configure.ac | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) --- diff --git a/configure.ac b/configure.ac index fd60c35..e0dcee1 100644 --- a/configure.ac +++ b/configure.ac @@ -388,7 +388,7 @@ if test "x$have_mb4" = "xyes"; then AM_CONDITIONAL(HAVE_MUSICBRAINZ4, true) dnl do not need musicbrainz 3 AM_CONDITIONAL(HAVE_MUSICBRAINZ3, false) -elif test "xhave_mb3" = "xyes"; then +elif test "x$have_mb3" = "xyes"; then AM_CONDITIONAL(HAVE_MUSICBRAINZ4, false) AM_CONDITIONAL(HAVE_MUSICBRAINZ3, true) else |
From: phantomjinx <pha...@us...> - 2012-06-01 08:18:53
|
commit ff9b4abf55b474fd9f6c6ecd7d56d95e88f3e141 Author: phantomjinx <p.g...@ph...> Date: Thu May 31 23:39:16 2012 +0100 Change to anjuta preference creation causing crash in pref dialog * The use of anjuta_prefences_add_from_builder assumes all the widgets in the builder have related preferences in the gsettings of the core gtkpod xml. The disable_splash_screen is not in there as it is from .prefs. * Reverts modifications made by f671cc889 with a little bit of tidying up src/anjuta-app.c | 22 +++++++++++++++++----- 1 files changed, 17 insertions(+), 5 deletions(-) --- diff --git a/src/anjuta-app.c b/src/anjuta-app.c index 73ad2af..b78e345 100644 --- a/src/anjuta-app.c +++ b/src/anjuta-app.c @@ -697,9 +697,11 @@ void anjuta_app_layout_reset(AnjutaApp *app) { } void anjuta_app_install_preferences(AnjutaApp *app) { + gchar *img_path; + GdkPixbuf *pixbuf; GtkBuilder* builder = gtk_builder_new(); GError* error = NULL; - GtkWidget *notebook, *splash_toggle, *shortcuts, *plugins, *remember_plugins; + GtkWidget *parent, *notebook, *splash_toggle, *shortcuts, *plugins, *remember_plugins; /* Create preferences page */ gchar *glade_path = g_build_filename(get_glade_dir(), CORE_GTKPOD_XML, NULL); @@ -716,11 +718,18 @@ void anjuta_app_install_preferences(AnjutaApp *app) { gtk_builder_connect_signals(builder, NULL); - gchar *icon_path = g_build_filename(get_icon_dir(), ICON_FILE, NULL); - anjuta_preferences_add_from_builder(app->preferences, builder, app->settings, "General", _("General"), ICON_FILE); - g_free(icon_path); - notebook = GTK_WIDGET(gtk_builder_get_object(builder, "General")); + parent = gtk_widget_get_parent(notebook); + g_object_ref(notebook); + gtk_container_remove(parent, notebook); + gtk_widget_destroy(parent); + + img_path = anjuta_res_get_pixmap_file(ICON_FILE); + pixbuf = gdk_pixbuf_new_from_file(img_path, NULL); + anjuta_preferences_dialog_add_page(ANJUTA_PREFERENCES_DIALOG(anjuta_preferences_get_dialog(app->preferences)), "plugins", _(" Plugins"), pixbuf, notebook); + + // Cannot use anjuta_preferences_add_from_builder() since this requires the splash screen key to be a gsetting + shortcuts = anjuta_ui_get_accel_editor(ANJUTA_UI(app->ui)); plugins = anjuta_plugin_manager_get_plugins_page(app->plugin_manager); remember_plugins = anjuta_plugin_manager_get_remembered_plugins_page(app->plugin_manager); @@ -734,6 +743,9 @@ void anjuta_app_install_preferences(AnjutaApp *app) { gtk_notebook_append_page(GTK_NOTEBOOK (notebook), shortcuts, gtk_label_new(_("Shortcuts"))); g_object_unref(builder); + g_object_unref(notebook); + g_free(img_path); + g_object_unref(pixbuf); } /* AnjutaShell Implementation */ |
From: phantomjinx <pha...@us...> - 2012-06-01 08:18:47
|
commit 525bfe4b174b2037dd9ea34c37867748b0a06162 Author: phantomjinx <p.g...@ph...> Date: Thu May 31 23:33:37 2012 +0100 Modifications due to change in gthreads API * Threading API in glib-2.0 < 2.31 has been deprecated so must be migrated to new API. * Preserves backward compatibility with glib-2.0 < 2.31 configure.ac | 15 +- libgtkpod/autodetection.c | 43 +++++- libgtkpod/file_convert.c | 189 +++++++++++++++++++-------- libgtkpod/file_itunesdb.c | 128 +++++++++++++++--- libgtkpod/prefs.c | 41 +++++- libgtkpod/tools.c | 99 ++++++++++++--- plugins/sjcd/libjuicer/sj-metadata-getter.c | 14 ++- src/main.c | 6 + 8 files changed, 424 insertions(+), 111 deletions(-) --- diff --git a/configure.ac b/configure.ac index ed37002..fd60c35 100644 --- a/configure.ac +++ b/configure.ac @@ -38,8 +38,8 @@ AC_CANONICAL_HOST AC_SEARCH_LIBS([strerror],[cposix]) AC_DIAGNOSE([obsolete],[AM_PROG_CC_STDC: - your code should no longer depend upon `am_cv_prog_cc_stdc', but upon - `ac_cv_prog_cc_stdc'. Remove this warning and the assignment when + your code should no longer depend upon am_cv_prog_cc_stdc, but upon + ac_cv_prog_cc_stdc. Remove this warning and the assignment when you adjust the code. You can also remove the above call to AC_PROG_CC if you already called it elsewhere.]) am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc @@ -110,17 +110,18 @@ PKG_CHECK_MODULES(MUSICBRAINZ4, libmusicbrainz4 >= 4.0.0, [have_mb4="yes"], [hav GTK_CLEANLINESS_FLAGS="-DG_DISABLE_SINGLE_INCLUDES -DGDK_PIXBUF_DISABLE_SINGLE_INCLUDES -DGTK_DISABLE_SINGLE_INCLUDES -DGSEAL_ENABLE" AC_MSG_CHECKING(for using DISABLE_DEPRECATED flags) -if expr "$LIBGTKPOD_VERSION" : '.*~' >/dev/null; then + +dnl if expr "$LIBGTKPOD_VERSION" : '.*~' >/dev/null; then dnl The version contains a tilde so this is not a release dnl Thus, we can add in disable deprecated flags to avoid dnl using deprecated functions - GTK_CLEANLINESS_FLAGS="$GTK_CLEANLINESS_FLAGS -DG_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED" - AC_MSG_RESULT(yes) -else +dnl GTK_CLEANLINESS_FLAGS="$GTK_CLEANLINESS_FLAGS -DG_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED" +dnl AC_MSG_RESULT(yes) +dnl else dnl The version is a release so do not include deprecated dnl flags. AC_MSG_RESULT(no) -fi +dnl fi dnl Force C99 mode (no implicit int declarations) CFLAGS="$CFLAGS -std=gnu99 -Werror-implicit-function-declaration" diff --git a/libgtkpod/autodetection.c b/libgtkpod/autodetection.c index e0bc5b0..48b9f4c 100644 --- a/libgtkpod/autodetection.c +++ b/libgtkpod/autodetection.c @@ -106,13 +106,42 @@ typedef struct _AutoDetect AutoDetect; static gboolean ad_timeout_cb(gpointer data); struct _AutoDetect { +#if GLIB_CHECK_VERSION(2,31,0) + GMutex mutex; /* shared lock */ +#else GMutex *mutex; /* shared lock */ +#endif + GList *new_ipod_uris; /* list of new mounts */ guint timeout_id; }; static AutoDetect *autodetect; +static void _create_mutex(AutoDetect *ad) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_init(&ad->mutex); +#else + ad->mutex = g_mutex_new (); +#endif +} + +static void _lock_mutex(AutoDetect *ad) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_lock (&ad->mutex); +#else + g_mutex_lock (ad->mutex); +#endif +} + +static void _unlock_mutex(AutoDetect *ad) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_unlock (&ad->mutex); +#else + g_mutex_unlock (ad->mutex); +#endif +} + /* adapted from rb-ipod-plugin.c (rhythmbox ipod plugin) */ static gboolean ad_mount_is_ipod(GMount *mount) { gboolean result = FALSE; @@ -146,9 +175,9 @@ static void ad_volume_mounted_cb(GVolumeMonitor *volumemonitor, GMount *mount, A if (uri) { debug ("mounted iPod: '%s'\n", uri); - g_mutex_lock (ad->mutex); + _lock_mutex(ad); ad->new_ipod_uris = g_list_prepend(ad->new_ipod_uris, uri); - g_mutex_unlock (ad->mutex); + _unlock_mutex(ad); } else { fprintf(stderr, "ERROR: could not get activation root!\n"); @@ -167,7 +196,7 @@ void autodetection_init() { g_once (&g_type_init_once, (GThreadFunc)g_type_init, NULL); autodetect = g_new0 (AutoDetect, 1); - autodetect->mutex = g_mutex_new (); + _create_mutex(autodetect); /* Check if an iPod is already mounted and add it to the list */ mounts = g_volume_monitor_get_mounts(g_volume_monitor_get()); @@ -198,7 +227,7 @@ static gboolean ad_timeout_cb(gpointer data) { /* Don't interfere with a blocked display -- try again later */ if (!widgets_blocked) { gdk_threads_enter(); - g_mutex_lock (ad->mutex); + _lock_mutex(ad); while (ad->new_ipod_uris) { iTunesDB *itdb = NULL, *loaded_itdb = NULL; @@ -211,7 +240,7 @@ static gboolean ad_timeout_cb(gpointer data) { ad->new_ipod_uris = g_list_delete_link(ad->new_ipod_uris, gl); - g_mutex_unlock (ad->mutex); + _unlock_mutex(ad); g_return_val_if_fail (mount_uri, (gdk_threads_leave(), release_widgets(), TRUE)); @@ -276,9 +305,9 @@ static gboolean ad_timeout_cb(gpointer data) { g_free(mount_uri); g_free(displaymp); - g_mutex_lock (ad->mutex); + _lock_mutex(ad); } - g_mutex_unlock (ad->mutex); + _unlock_mutex(ad); gdk_threads_leave(); } diff --git a/libgtkpod/file_convert.c b/libgtkpod/file_convert.c index 5dbc27e..567c1a9 100644 --- a/libgtkpod/file_convert.c +++ b/libgtkpod/file_convert.c @@ -110,6 +110,8 @@ processed next. */ +#define CONVERSION_THREAD "Conversion Thread" + /* Preferences keys */ const gchar *FILE_CONVERT_CACHEDIR = "file_convert_cachedir"; const gchar *FILE_CONVERT_MAXDIRSIZE = "file_convert_maxdirsize"; @@ -163,32 +165,37 @@ struct GaplessData { }; struct _Conversion { - GMutex *mutex; /* shared lock */ +#if GLIB_CHECK_VERSION(2,31,0) + GMutex mutex; /* mutex for this struct */ + GCond finished_cond; /* signals if a new track is added to the finished list */ + GCond dirsize_cond; /* signal when dirsize has been updated */ + GCond prune_cond; /* signal when dir has been pruned */ +#else + GMutex *mutex; /* mutex for this struct */ + GCond *finished_cond; /* signals if a new track is added to the finished list */ + GCond *dirsize_cond; /* signal when dirsize has been updated */ + GCond *prune_cond; /* signal when dir has been pruned */ +#endif + GList *scheduled; /* tracks scheduled for conversion */ GList *processing; /* tracks currently being converted */ GList *failed; /* tracks with failed conversion */ - GList *converted; /* tracks successfully converted but not - yet unscheduled */ - GList *finished; /* tracks unscheduled but not yet - transferred */ - GCond *finished_cond; /* signals if a new track is added to the - finished list */ + GList *converted; /* tracks successfully converted but not yet unscheduled */ + GList *finished; /* tracks unscheduled but not yet transferred */ + gchar *cachedir; /* directory for converted files */ gchar *template; /* name template to use for converted files */ gint max_threads_num; /* maximum number of allowed threads */ GList *threads; /* list of threads */ gint threads_num; /* number of threads currently running */ - gboolean conversion_force; /* force a new thread to start even if - the dirsize is too large */ + gboolean conversion_force; /* force a new thread to start even if the dirsize is too large */ gint64 max_dirsize; /* maximum size of cache directory in bytes */ gint64 dirsize; /* current size of cache directory in bytes */ gboolean dirsize_in_progress; /* currently determining dirsize */ - GCond *dirsize_cond; /* signal when dirsize has been updated */ gboolean prune_in_progress; /* currently pruning directory */ - GCond *prune_cond; /* signal when dir has been pruned */ - gboolean force_prune_in_progress; /* do another prune right after - the current process finishes */ + gboolean force_prune_in_progress; /* do another prune right after the current process finishes */ guint timeout_id; + /* data for log display */ GtkWidget *log_window; /* display log window */ gboolean log_window_hidden; /* whether the window was closed */ @@ -201,9 +208,9 @@ struct _Conversion { GList *pages; /* list with pages currently added */ GtkStatusbar *log_statusbar; /* statusbar of log display */ guint log_context_id; /* context ID for statusbar */ + /* data for background transfer */ - GList *transfer_itdbs; /* list with TransferItdbs for background - transfer */ + GList *transfer_itdbs; /* list with TransferItdbs for background transfer */ gchar *last_error_msg; /* keep a record of the last error message */ }; @@ -259,6 +266,103 @@ enum { static Conversion *conversion = NULL; +static GThread *_create_thread(GThreadFunc func, gpointer userdata) { +#if GLIB_CHECK_VERSION(2,31,0) + return g_thread_new (CONVERSION_THREAD, func, userdata); +#else + return g_thread_create_full(func, + userdata, + 0, /* stack size */ + FALSE, /* joinable */ + TRUE, /* bound */ + G_THREAD_PRIORITY_NORMAL, NULL); /* error */ +#endif +} + +static void _create_mutex(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_init(&c->mutex); +#else + c->mutex = g_mutex_new (); +#endif +} + +static gboolean _try_lock(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + return g_mutex_trylock(&c->mutex); +#else + return g_mutex_trylock(c->mutex); +#endif +} + +static void _lock_mutex(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_lock (&c->mutex); +#else + g_mutex_lock (c->mutex); +#endif +} + +static void _unlock_mutex(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_unlock (&c->mutex); +#else + g_mutex_unlock (c->mutex); +#endif +} + +static void _create_cond(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_init(&c->finished_cond); + g_cond_init(&c->dirsize_cond); + g_cond_init(&c->prune_cond); +#else + c->finished_cond = g_cond_new (); + c->dirsize_cond = g_cond_new (); + c->prune_cond = g_cond_new (); +#endif +} + +static void _broadcast_prune_cond(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_broadcast (&c->prune_cond); +#else + g_cond_broadcast (c->prune_cond); +#endif +} + +static void _broadcast_dirsize_cond(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_broadcast (&c->dirsize_cond); +#else + g_cond_broadcast (c->dirsize_cond); +#endif +} + +static void _broadcast_finished_cond(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_broadcast (&c->finished_cond); +#else + g_cond_broadcast (c->finished_cond); +#endif +} + +static void _wait_prune_cond(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_wait (&c->prune_cond, &c->mutex); +#else + g_cond_wait (c->prune_cond, c->mutex); +#endif +} + +static void _wait_dirsize_cond(Conversion *c) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_wait (&c->dirsize_cond, &c->mutex); +#else + g_cond_wait (c->dirsize_cond, c->mutex); +#endif +} + /* Set up conversion infrastructure. Must only be called once. */ void file_convert_init() { GtkBuilder *log_builder; @@ -268,11 +372,9 @@ void file_convert_init() { return; conversion = g_new0 (Conversion, 1); - conversion->mutex = g_mutex_new (); + _create_mutex(conversion); - conversion->finished_cond = g_cond_new (); - conversion->dirsize_cond = g_cond_new (); - conversion->prune_cond = g_cond_new (); + _create_cond(conversion); conversion_setup_cachedir(conversion); if (!prefs_get_string_value(FILE_CONVERT_TEMPLATE, NULL)) { @@ -347,12 +449,12 @@ void file_convert_shutdown() { static void file_convert_lock(Conversion *conv) { debug ("Locking conversion"); - g_mutex_lock(conv->mutex); + _lock_mutex(conv); } static void file_convert_unlock(Conversion *conv) { debug("Unlocking conversion"); - g_mutex_unlock(conv->mutex); + _unlock_mutex(conv); } /* This is called just before gtkpod closes down */ @@ -626,12 +728,7 @@ static void conversion_prefs_changed(Conversion *conv) { if ((conv->dirsize == CONV_DIRSIZE_INVALID) || (conv->dirsize > conv->max_dirsize)) { /* Prune dir of unused files if size is too big, calculate and set the size of the directory. Do all that in the background. */ - g_thread_create_full(conversion_prune_dir, - conv, /* user data */ - 0, /* stack size */ - FALSE, /* joinable */ - TRUE, /* bound */ - G_THREAD_PRIORITY_NORMAL, NULL); /* error */ + _create_thread(conversion_prune_dir, conv); } background_transfer = prefs_get_int(FILE_CONVERT_BACKGROUND_TRANSFER); @@ -1291,11 +1388,7 @@ static gboolean conversion_scheduler_unlocked(Conversion *conv) { GList *gl; GThread *thread; - thread = g_thread_create_full(conversion_thread, conv, /* user data */ - 0, /* stack size */ - FALSE, /* joinable */ - TRUE, /* bound */ - G_THREAD_PRIORITY_LOW, NULL); /* error */ + thread = _create_thread(conversion_thread, conv); /* Add thread to thread list. Use first available slot */ gl = g_list_find(conv->threads, NULL); @@ -1438,7 +1531,7 @@ static gboolean conversion_scheduler_unlocked(Conversion *conv) { g_return_val_if_fail (tr && tr->itdb && tr->userdata, TRUE); etr = tr->userdata; /* broadcast finished track */ - g_cond_broadcast (conv->finished_cond); + _broadcast_finished_cond(conv); tri = transfer_get_tri(conv, tr->itdb); g_return_val_if_fail (tri, TRUE); @@ -1477,11 +1570,7 @@ static gboolean conversion_scheduler_unlocked(Conversion *conv) { g_return_val_if_fail (tri, TRUE); if (tri->scheduled) { if ((tri->thread == NULL) && (tri->transfer == TRUE) && (tri->status != FILE_TRANSFER_DISK_FULL)) { /* start new thread */ - tri->thread = g_thread_create_full(transfer_thread, tri, /* user data */ - 0, /* stack size */ - FALSE, /* joinable */ - TRUE, /* bound */ - G_THREAD_PRIORITY_LOW, NULL); /* error */ + tri->thread = _create_thread(transfer_thread, tri); } } @@ -1579,7 +1668,7 @@ static gboolean conversion_scheduler(gpointer data) { // debug ("conversion_scheduler enter\n"); gdk_threads_enter(); - if (!g_mutex_trylock(conv->mutex)) { + if (!_try_lock(conv)) { gdk_threads_leave(); /* Do not destroy the timeout function by returning FALSE */ return TRUE; @@ -1608,7 +1697,7 @@ static gpointer conversion_update_dirsize(gpointer data) { file_convert_lock(conv); if (conv->dirsize_in_progress) { /* another thread is already working on the directory size. We'll wait until it has finished and just return. */ - g_cond_wait (conv->dirsize_cond, conv->mutex); + _wait_dirsize_cond(conv); file_convert_unlock(conv); debug ("%p update_dirsize concurrent exit\n", g_thread_self ()); return NULL; @@ -1635,7 +1724,7 @@ static gpointer conversion_update_dirsize(gpointer data) { /* We're finished doing the directory upgrade. Unset the flag and broadcast to all threads waiting to wake them up. */ conv->dirsize_in_progress = FALSE; - g_cond_broadcast (conv->dirsize_cond); + _broadcast_dirsize_cond(conv); file_convert_unlock(conv); debug ("%p update_dirsize exit\n", g_thread_self ()); @@ -1734,7 +1823,7 @@ static gpointer conversion_prune_dir(gpointer data) { file_convert_lock(conv); if (conv->prune_in_progress) { /* another thread is already working on the directory prune. We'll wait until it has finished and just return. */ - g_cond_wait (conv->prune_cond, conv->mutex); + _wait_prune_cond(conv); file_convert_unlock(conv); return NULL; } @@ -1766,7 +1855,7 @@ static gpointer conversion_prune_dir(gpointer data) { for (gl = conv->transfer_itdbs; gl; gl = gl->next) { TransferItdb *tri = gl->data; g_return_val_if_fail (tri, (conv->prune_in_progress = FALSE, - g_cond_broadcast (conv->prune_cond), + _broadcast_prune_cond(conv), file_convert_unlock(conv), NULL)); conversion_prune_needed_add(hash_needed_files, tri->scheduled); @@ -1795,11 +1884,11 @@ static gpointer conversion_prune_dir(gpointer data) { for (gl = files; gl && (dirsize > maxsize); gl = gl->next) { struct conversion_prune_file *cpf = gl->data; g_return_val_if_fail (cpf, (conv->prune_in_progress = FALSE, - g_cond_broadcast (conv->prune_cond), + _broadcast_prune_cond(conv), NULL)); g_return_val_if_fail (cpf->filename, (conv->prune_in_progress = FALSE, - g_cond_broadcast (conv->prune_cond), + _broadcast_prune_cond(conv), NULL)); if (g_hash_table_lookup(hash_needed_files, cpf->filename) == NULL) { /* file is not among those remove */ if (g_remove(cpf->filename) == 0) { @@ -1821,7 +1910,7 @@ static gpointer conversion_prune_dir(gpointer data) { file_convert_lock(conv); conv->prune_in_progress = FALSE; - g_cond_broadcast (conv->prune_cond); + _broadcast_prune_cond(conv); file_convert_unlock(conv); debug ("%p prune_dir exit\n", g_thread_self ()); @@ -2677,7 +2766,7 @@ static gpointer transfer_force_prune_dir(gpointer data) { return NULL; } conv->force_prune_in_progress = TRUE; - g_cond_wait (conv->prune_cond, conv->mutex); + _wait_prune_cond(conv); conv->force_prune_in_progress = FALSE; } @@ -2861,11 +2950,7 @@ static gpointer transfer_thread(gpointer data) { if (conv->dirsize > conv->max_dirsize) { /* we just transferred a track -- there should be space available again -> force a directory prune */ - g_thread_create_full(transfer_force_prune_dir, conv, /* user data */ - 0, /* stack size */ - FALSE, /* joinable */ - TRUE, /* bound */ - G_THREAD_PRIORITY_NORMAL, NULL); /* error */ + _create_thread(transfer_force_prune_dir, conv); } } diff --git a/libgtkpod/file_itunesdb.c b/libgtkpod/file_itunesdb.c index 921fe69..f3f96f6 100644 --- a/libgtkpod/file_itunesdb.c +++ b/libgtkpod/file_itunesdb.c @@ -52,6 +52,8 @@ #define debug(s) printf(__FILE__":" TO_STR(__LINE__) ":" s) #define debugx(s,...) printf(__FILE__":" TO_STR(__LINE__) ":" s,__VA_ARGS__) +#define TRANSFER_THREAD "Transfer Data Thread" + #define WRITE_EXTENDED_INFO TRUE /* #define WRITE_EXTENDED_INFO prefs_get_int("write_extended_info") */ @@ -82,9 +84,15 @@ struct track_extended_info { }; typedef struct { +#if GLIB_CHECK_VERSION(2,31,0) + GMutex mutex; /* mutex for this struct */ + GCond finished_cond; /* used to signal end of thread */ +#else GMutex *mutex; /* mutex for this struct */ - gboolean abort; /* TRUE = abort */ GCond *finished_cond; /* used to signal end of thread */ +#endif + + gboolean abort; /* TRUE = abort */ gboolean finished; /* background thread has finished */ Track *track; /* Current track */ const gchar *filename; /* Filename to copy/remove */ @@ -100,6 +108,83 @@ static float extendedinfoversion = 0.0; /* Some declarations */ static gboolean gp_write_itdb(iTunesDB *itdb); +static GThread *_create_thread(GThreadFunc func, gpointer userdata) { +#if GLIB_CHECK_VERSION(2,31,0) + return g_thread_new (TRANSFER_THREAD, func, userdata); +#else + return g_thread_create (func, userdata, TRUE, NULL); +#endif +} + +static void _create_mutex(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_init(&td->mutex); +#else + td->mutex = g_mutex_new (); +#endif +} + +static void _lock_mutex(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_lock (&td->mutex); +#else + g_mutex_lock (td->mutex); +#endif +} + +static void _unlock_mutex(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_unlock (&td->mutex); +#else + g_mutex_unlock (td->mutex); +#endif +} + +static void _clear_mutex(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_clear (&td->mutex); +#else + if (td->mutex) + g_mutex_free (td->mutex); +#endif +} + +static void _create_cond(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_init(&td->finished_cond); +#else + td->finished_cond = g_cond_new (); +#endif +} + +static void _cond_signal(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_signal (&td->finished_cond); +#else + g_cond_signal (td->finished_cond); +#endif +} + +static void _cond_timed_wait(TransferData *td, glong timeout) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_wait_until (&td->finished_cond, &td->mutex, (gint64) timeout); +#else + GTimeVal gtime; + g_get_current_time(>ime); + g_time_val_add(>ime, timeout); + g_cond_timed_wait (td->finished_cond, td->mutex, >ime); +#endif +} + +static void _clear_cond(TransferData *td) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_clear (&td->finished_cond); +#else + if (td->finished_cond) + g_cond_free (td->finished_cond); +#endif +} + /* fills in extended info if available */ /* num/total are used to give updates in case the sha1 checksums have to be matched against the files which is very time consuming */ @@ -1181,17 +1266,18 @@ gboolean gp_create_extended_info(iTunesDB *itdb) { TransferData *transfer_data_new(void) { TransferData *transfer_data; transfer_data = g_new0 (TransferData, 1); - transfer_data->mutex = g_mutex_new (); - transfer_data->finished_cond = g_cond_new (); + + _create_mutex(transfer_data); + _create_cond(transfer_data); + transfer_data->current_progress = 0; return transfer_data; } void transfer_data_free(TransferData *transfer_data) { - if (transfer_data->mutex) - g_mutex_free (transfer_data->mutex); - if (transfer_data->finished_cond) - g_cond_free (transfer_data->finished_cond); + _clear_mutex(transfer_data); + _clear_cond(transfer_data); + g_free(transfer_data); } @@ -1202,10 +1288,15 @@ static gpointer th_remove(gpointer userdata) { gint result; result = g_remove(td->filename); - g_mutex_lock (td->mutex); + + _lock_mutex(td); + td->finished = TRUE; /* signal that thread will end */ - g_cond_signal (td->finished_cond); - g_mutex_unlock (td->mutex); + + _cond_signal(td); + + _unlock_mutex(td); + return GINT_TO_POINTER(result); } @@ -1330,31 +1421,26 @@ static gboolean delete_files(iTunesDB *itdb, TransferData *td) { td->finished = FALSE; td->filename = filename; - g_mutex_lock (td->mutex); + _lock_mutex (td); - thread = g_thread_create (th_remove, td, TRUE, NULL); + thread = _create_thread(th_remove, td); do { - GTimeVal gtime; - td->current_progress = set_progress(start, n, count, 0, td->current_progress, "deletion completed"); - g_mutex_unlock (td->mutex); + _unlock_mutex (td); while (widgets_blocked && gtk_events_pending()) gtk_main_iteration(); - g_mutex_lock (td->mutex); + _lock_mutex (td); /* wait a maximum of 20 ms or until cond is signaled */ - g_get_current_time(>ime); - g_time_val_add(>ime, 20000); - g_cond_timed_wait (td->finished_cond, - td->mutex, >ime); + _cond_timed_wait(td, 20000); } while (!td->finished); - g_mutex_unlock (td->mutex); + _unlock_mutex (td); rmres = GPOINTER_TO_INT(g_thread_join (thread)); diff --git a/libgtkpod/prefs.c b/libgtkpod/prefs.c index 249d71d..97ffc38 100644 --- a/libgtkpod/prefs.c +++ b/libgtkpod/prefs.c @@ -99,7 +99,39 @@ struct sub_data { /* Pointer to preferences hash table */ static GHashTable *prefs_table = NULL; + +#if GLIB_CHECK_VERSION(2,31,0) +static GMutex prefs_table_mutex; +#else static GMutex *prefs_table_mutex = NULL; +#endif + +static void _create_mutex() { +#if GLIB_CHECK_VERSION(2,31,0) + // As it is static the mutex needs no initialisation +#else + if (!prefs_table_mutex) + prefs_table_mutex = g_mutex_new (); +#endif +} + +static void _lock_mutex() { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_lock (&prefs_table_mutex); +#else + g_return_if_fail (prefs_table_mutex); + g_mutex_lock (prefs_table_mutex); +#endif +} + +static void _unlock_mutex() { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_unlock (&prefs_table_mutex); +#else + g_return_if_fail (prefs_table_mutex); + g_mutex_unlock (prefs_table_mutex); +#endif +} /* * Functions used by this module only @@ -119,14 +151,12 @@ enum { /* Lock the prefs table. If the table is already locked the calling * thread will remain blocked until the lock is released by the other thread. */ static void lock_prefs_table() { - g_return_if_fail (prefs_table_mutex); - g_mutex_lock (prefs_table_mutex); + _lock_mutex(); } /* Unlock the prefs table again. */ static void unlock_prefs_table() { - g_return_if_fail (prefs_table_mutex); - g_mutex_unlock (prefs_table_mutex); + _unlock_mutex(); } /* Set default preferences */ @@ -873,8 +903,7 @@ static void cleanup_keys() { /* Initialize the prefs table and read configuration */ void prefs_init(int argc, char *argv[]) { - if (!prefs_table_mutex) - prefs_table_mutex = g_mutex_new (); + _create_mutex(); lock_prefs_table(); diff --git a/libgtkpod/tools.c b/libgtkpod/tools.c index 6847444..19e15e1 100644 --- a/libgtkpod/tools.c +++ b/libgtkpod/tools.c @@ -45,6 +45,8 @@ #include <unistd.h> #include <glib/gi18n-lib.h> +#define TOOLS_THREAD "Tools Thread" + /* Structure to keep all necessary information */ struct nm { Track *track; /* track to be normalised */ @@ -67,11 +69,81 @@ enum { ------------------------------------------------------------ */ #ifdef G_THREADS_ENABLED + +#if GLIB_CHECK_VERSION(2,31,0) +static GMutex mutex; +static GCond cond; +#else static GMutex *mutex = NULL; static GCond *cond = NULL; +#endif + static gboolean mutex_data = FALSE; #endif +static GThread *_create_thread(GThreadFunc func, gpointer userdata) { +#if GLIB_CHECK_VERSION(2,31,0) + return g_thread_new (TOOLS_THREAD, func, userdata); +#else + return g_thread_create (func, userdata, TRUE, NULL); +#endif +} + +static void _create_cond() { +#if GLIB_CHECK_VERSION(2,31,0) + // As it is static the cond needs no initialisation +#else + if (!cond) + cond = g_cond_new (); +#endif +} + +static void _cond_signal() { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_signal (&cond); +#else + g_cond_signal (cond); +#endif +} + +static void _cond_timed_wait(glong timeout) { +#if GLIB_CHECK_VERSION(2,31,0) + g_cond_wait_until (&cond, &mutex, (gint64) timeout); +#else + GTimeVal gtime; + g_get_current_time(>ime); + g_time_val_add(>ime, timeout); + g_cond_timed_wait (cond, mutex, >ime); +#endif +} + +static void _create_mutex() { +#if GLIB_CHECK_VERSION(2,31,0) + // As it is static the mutex needs no initialisation +#else + if (!mutex) + mutex = g_mutex_new (); +#endif +} + +static void _lock_mutex() { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_lock (&mutex); +#else + g_return_if_fail (mutex); + g_mutex_lock (mutex); +#endif +} + +static void _unlock_mutex() { +#if GLIB_CHECK_VERSION(2,31,0) + g_mutex_unlock (&mutex); +#else + g_return_if_fail (mutex); + g_mutex_unlock (mutex); +#endif +} + /* Run @command on @track_path. * * Command may include options, like "mp3gain -q -k %s" @@ -283,10 +355,10 @@ static gboolean nm_get_soundcheck(Track *track, GError **error) { static gpointer th_nm_get_soundcheck(gpointer data) { struct nm *nm = data; gboolean success = nm_get_soundcheck(nm->track, &(nm->error)); - g_mutex_lock(mutex); + _lock_mutex(); mutex_data = TRUE; /* signal that thread will end */ - g_cond_signal(cond); - g_mutex_unlock(mutex); + _cond_signal(); + _unlock_mutex(); return GUINT_TO_POINTER(success); } #endif @@ -342,11 +414,9 @@ void nm_tracks_list(GList *list) { #ifdef G_THREADS_ENABLED GThread *thread = NULL; - GTimeVal gtime; - if (!mutex) - mutex = g_mutex_new (); - if (!cond) - cond = g_cond_new (); + + _create_mutex(); + _create_cond(); #endif block_widgets(); @@ -380,21 +450,18 @@ void nm_tracks_list(GList *list) { #ifdef G_THREADS_ENABLED mutex_data = FALSE; - thread = g_thread_create (th_nm_get_soundcheck, nm, TRUE, NULL); + thread = _create_thread(th_nm_get_soundcheck, nm); if (thread) { - g_mutex_lock(mutex); + _lock_mutex(); do { while (widgets_blocked && gtk_events_pending()) gtk_main_iteration(); - /* wait a maximum of 10 ms */ - - g_get_current_time(>ime); - g_time_val_add(>ime, 20000); - g_cond_timed_wait(cond, mutex, >ime); + /* wait a maximum of 20 ms */ + _cond_timed_wait(20000); } while (!mutex_data); success = GPOINTER_TO_UINT(g_thread_join (thread)); - g_mutex_unlock(mutex); + _unlock_mutex(); } else { g_warning("Thread creation failed, falling back to default.\n"); diff --git a/plugins/sjcd/libjuicer/sj-metadata-getter.c b/plugins/sjcd/libjuicer/sj-metadata-getter.c index 11002fa..820248a 100644 --- a/plugins/sjcd/libjuicer/sj-metadata-getter.c +++ b/plugins/sjcd/libjuicer/sj-metadata-getter.c @@ -38,6 +38,8 @@ #include "sj-metadata-gvfs.h" #include "sj-error.h" +#define SJ_METADATA_THREAD "SJ MetaData Thread" + enum { METADATA, LAST_SIGNAL @@ -94,7 +96,7 @@ static void sj_metadata_getter_finalize (GObject *object) { SjMetadataGetterPrivate *priv = GETTER_PRIVATE (object); - + g_free (priv->url); g_free (priv->cdrom); g_free (priv->proxy_host); @@ -240,13 +242,21 @@ lookup_cd (SjMetadataGetter *mdg) return NULL; } +static GThread *_create_thread(GThreadFunc func, gpointer userdata, GError **error) { +#if GLIB_CHECK_VERSION(2,31,0) + return g_thread_new (SJ_METADATA_THREAD, func, userdata); +#else + return g_thread_create (func, userdata, TRUE, error); +#endif +} + gboolean sj_metadata_getter_list_albums (SjMetadataGetter *mdg, GError **error) { GThread *thread; g_object_ref (mdg); - thread = g_thread_create ((GThreadFunc)lookup_cd, mdg, TRUE, error); + thread = _create_thread((GThreadFunc)lookup_cd, mdg, error); if (thread == NULL) { g_set_error (error, SJ_ERROR, SJ_ERROR_INTERNAL_ERROR, diff --git a/src/main.c b/src/main.c index 2197894..8be6dfe 100644 --- a/src/main.c +++ b/src/main.c @@ -58,8 +58,14 @@ main (int argc, char *argv[]) #endif #ifdef G_THREADS_ENABLED + +#if GLIB_CHECK_VERSION(2,31,0) + /* No longer need to init threads manually anymore */ +#else /* this must be called before gtk_init () */ g_thread_init (NULL); +#endif + /* FIXME: this call causes gtkpod to freeze as soon as tracks should be displayed */ gdk_threads_init (); |
From: phantomjinx <pha...@us...> - 2012-06-01 08:18:41
|
commit 02f8f2e52dba531562e42d6dfb38d5505c51502d Author: phantomjinx <p.g...@ph...> Date: Fri May 25 10:09:25 2012 +0100 Updates NEWS and Changelog ChangeLog | 453 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INSTALL | 17 +-- NEWS | 23 +++ 3 files changed, 484 insertions(+), 9 deletions(-) --- diff --git a/ChangeLog b/ChangeLog index 1b0d3fa..5abb28f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,436 @@ +phantomjinx <p.g...@ph...> 2012-05-12 + + Updates NEWS and Changelog + +phantomjinx <p.g...@ph...> 2012-05-25 + + Update language files ready for release 2.1.2 + +phantomjinx <p.g...@ph...> 2012-05-25 + + Update and fix sjcd plugin + + * Update sjcd plugin to reflect latest developements in sound juicer + including use of musicbrainz 4 + + * sj_extracting.c + * Avoid segfaulting if a track value is empty. Happen to have a CD that + failed to return any track names for an album - maybe a bug in the + sound juicer musicbrainz 4 code + +phantomjinx <p.g...@ph...> 2012-05-09 + + Improve performance of playlist selection + + * For playlists / ipods with many tracks, playlist selection can be very + slow. Turns out this is due to excessive track display signals being + fired while tracks are added. + + * Use gtk_list_store_insert_with_values since this triggers fewer signals + than the gtk_list_store_append/gtk_list_store_set couplet + + * Turn off sorting then turn back on afterwards since sorting makes adding + very slow! + +phantomjinx <p.g...@ph...> 2012-04-24 + + Fix sjcd preference dialog + + * Sound juicer dialog opening one but failing to open correctly on + subsquent occasions. + + * Ensures that the dialog is fully constructed from scratch and fully + destroyed when closed, inclusing unbinding and disconnecting the + g_settings + +phantomjinx <p.g...@ph...> 2012-04-23 + + Fix for double free segfault + + * Occurs when adding a directory + + * Directory names inserted into hash table, added as both key and value then + being freed as key and then freed as value. Second free causing the + segfault + + Fixes 3477268 (sf.net) + Fixes FS#92 + +phantomjinx <p.g...@ph...> 2012-04-22 + + Fix deadlock when mult metadata is available in sjcd + + * When preparing to rip a CD and cddb returns more than one choice for the + CD's metadata, a dialog is displayed so user can choose which metadata to + take. Pressing continue, causes a deadlock in application. + + * Surrounding gtk_dialog_run function with gdk_threads_enter/leave solves + the deadlock by ensuring gtkpod's main loop owns the lock. + +phantomjinx <p.g...@ph...> 2012-04-19 + + Fix for not setting artwork correctly + + * Mistake in code that points to the temporary file rather than extracting + the pixbuf data from it. Fixed to manually extract and apply data as + artwork. + +phantomjinx <p.g...@ph...> 2012-04-19 + + Tidy up variables for library compilation + + * configure.ac + * Set the so version of the atomic parsley library + * Some default CFLAGS are inappropriate for C++ compilation so provide + reduced CFLAGS for atomic parsley library + + * libgkpod/Makefile.am + * Remove unnecessary variable definitions + + * atomic-parsley/Makefile.am + * Apply CFLAGS and SO_VERSION to library + +phantomjinx <p.g...@ph...> 2012-04-17 + + Fix deprecations in sjcd plugin + + * Deprecated code causing compile errors in rpm compilations + +phantomjinx <p.g...@ph...> 2012-04-15 + + Fix language files + + * Update po files to reflect changes in plugins. Include atomic parsley + library for translation of error messages + +phantomjinx <p.g...@ph...> 2012-04-14 + + Build libs directory before plugins + + * atomic parsley library required for plugins but depends on libgtkpod + +phantomjinx <p.g...@ph...> 2012-04-11 + + Small fixes and reformatting + + * Reformats all atomic-parsley files to same formatting as the other + gtkpod sources + + * Convert some atom strings to defines + + * Fix some bugs after testing + + * Disable gapless reading since there is a lot more to it than just the + gapless flag. May be sorted in the future + +phantomjinx <p.g...@ph...> 2012-04-10 + + Support for writing mp4 tags using atomic parsley + + * AtomicParsleyBridge + * Include read / write lyric support for the first time + * Include write metadata function + + * m4afile.[ch] + * Mirror the function calls in mp4file.c + * Could we make these common somehow?? + +phantomjinx <p.g...@ph...> 2012-04-14 + + Remove the dependency on libmp4v2 + + * The dependency on libmp4v2 is a license violation when + linked to the GPL codebase. + + * Integrate a modified version of the GPL AtomicParsely code + into the filetype_mp4 plugin instead. This code is written + in C++ so use of the CXX bits n pieces is required. Small + price to pay to avoid the license violation. + + * Atomic Parsley library added to separate libs directory to + allow linkage from both mp4 and m4a plugins. + + * TODO + * Only read is currently supported so write needs implementing + +phantomjinx <p.g...@ph...> 2012-04-08 + + Small fixes + + * file.c + * Fix incorrect logic when error handling file info + + * gtkpod_app_iface.c + * Avoid winding on the suffixes list permanently when registering file + types. + +phantomjinx <p.g...@ph...> 2012-02-11 + + Remove canberra dependency + + * All use has been removed from sjcd plugin so no need to include the + actual dependency. + +phantomjinx <p.g...@ph...> 2012-02-11 + + Modify potfiles for sjcd and external player plugins + +Daniele Forsi <df...@sr...> 2012-03-27 + + strcmp() needs #include <string.h> + + This reverts one hunk of commit 1c640e4bbc5efa6e7a85456b54d1c86376e0ccc4 + +Daniele Forsi <df...@sr...> 2012-03-27 + + Add the border to the spin button + + So it looks like all other spin buttons. + +Daniele Forsi <df...@sr...> 2012-03-27 + + Use a GtkLabel like all other dialogs + + So it looks like all other text. + +Daniele Forsi <df...@sr...> 2012-03-26 + + Trivial: s/lyrics/details/ in license text + + Possibly a side effect of a global search and replace. + +Daniele Forsi <df...@sr...> 2012-03-25 + + Add const keywords (warnings by clang) + + At some time they were added to gtk too. + Eg. see http://developer.gnome.org/gtk/2.24/GtkCellRenderer.html + Fixes: + CC rb_cell_renderer_rating.lo + rb_cell_renderer_rating.c:159:23: warning: incompatible pointer types assigning to 'void (*)(GtkCellRenderer *, GtkWidget *, const GdkRectangle *, gint *, gint *, gint *, gint *)' from 'void (GtkCellRenderer *, GtkWidget *, GdkRectangle *, gint *, gint *, gint *, gint *)' + cell_class->get_size = rb_cell_renderer_rating_get_size; + ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + rb_cell_renderer_rating.c:161:23: warning: incompatible pointer types assigning to 'gboolean (*)(GtkCellRenderer *, GdkEvent *, GtkWidget *, const gchar *, const GdkRectangle *, const GdkRectangle *, GtkCellRendererState)' from 'gboolean (GtkCellRenderer *, GdkEvent *, GtkWidget *, const gchar *, GdkRectangle *, GdkRectangle *, GtkCellRendererState)' + cell_class->activate = rb_cell_renderer_rating_activate; + ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + rb_cell_renderer_rating.c:287:50: warning: passing 'const GdkRectangle *' (aka 'const struct _cairo_rectangle_int *') to parameter of type 'GdkRectangle *' (aka 'struct _cairo_rectangle_int *') discards qualifiers + rb_cell_renderer_rating_get_size (cell, widget, cell_area, + ^~~~~~~~~ + rb_cell_renderer_rating.c:244:21: note: passing argument to parameter 'cell_area' here + GdkRectangle *cell_area, + ^ + 3 warnings generated. + +Daniele Forsi <df...@sr...> 2012-03-25 + + Fix visibility of enum GtkPodSortTypes (warnings by clang) + + Fixes: + CC special_sorttab_page.lo + In file included from special_sorttab_page.c:37: + In file included from ./special_sorttab_page.h:33: + ./sorttab_widget.h:108:53: warning: declaration of 'enum GtkPodSortTypes' will not be visible outside of this function + void sort_tab_widget_sort(SortTabWidget *self, enum GtkPodSortTypes order); + ^ + 1 warning generated. + CC special_sorttab_page_calendar.lo + In file included from special_sorttab_page_calendar.c:36: + ./sorttab_widget.h:108:53: warning: declaration of 'enum GtkPodSortTypes' will not be visible outside of this function + void sort_tab_widget_sort(SortTabWidget *self, enum GtkPodSortTypes order); + ^ + 1 warning generated. + CC sorttab_widget.lo + CC display_sorttabs.lo + CC sorttab_display_actions.lo + In file included from sorttab_display_actions.c:38: + In file included from ./display_sorttabs.h:36: + ./sorttab_widget.h:108:53: warning: declaration of 'enum GtkPodSortTypes' will not be visible outside of this function + void sort_tab_widget_sort(SortTabWidget *self, enum GtkPodSortTypes order); + ^ + 1 warning generated. + +Daniele Forsi <df...@sr...> 2012-03-25 + + Do not include itself + +Daniele Forsi <df...@sr...> 2012-03-25 + + Do not pass arguments to void functions (warnings by clang) + + Fixes: + repository_editor.c:455:35: warning: too many arguments in call to 'update_buttons' + update_buttons(repository_view); + ~~~~~~~~~~~~~~ ^ + repository_editor.c:583:39: warning: too many arguments in call to 'update_buttons' + update_buttons(repository_view); + ~~~~~~~~~~~~~~ ^ + repository_editor.c:600:39: warning: too many arguments in call to 'update_buttons' + update_buttons(repository_view); + ~~~~~~~~~~~~~~ ^ + repository_editor.c:641:39: warning: too many arguments in call to 'update_buttons' + update_buttons(repository_view); + ~~~~~~~~~~~~~~ ^ + repository_editor.c:673:35: warning: too many arguments in call to 'update_buttons' + update_buttons(repository_view); + ~~~~~~~~~~~~~~ ^ + repository_editor.c:817:35: warning: too many arguments in call to 'update_buttons' + update_buttons(repository_view); + ~~~~~~~~~~~~~~ ^ + WARNING: While resolving call to function 'update_buttons' arguments were dropped! + WARNING: While resolving call to function 'update_buttons' arguments were dropped! + WARNING: While resolving call to function 'update_buttons' arguments were dropped! + WARNING: While resolving call to function 'update_buttons' arguments were dropped! + WARNING: While resolving call to function 'update_buttons' arguments were dropped! + WARNING: While resolving call to function 'init_repository_combo' arguments were dropped! + WARNING: While resolving call to function 'update_buttons' arguments were dropped! + +Daniele Forsi <df...@sr...> 2012-03-15 + + Fix segfault when g_settings schema isn't installed + + * src/anjuta-app.c + * Use a NULL safe string comparison function + + Fixes: + Program received signal SIGSEGV, Segmentation fault. + (gdb) bt + #0 __GI___strcasecmp (s1=0x0, s2=0x805459c "Text") at strcasecmp.c:65 + #1 0x08050d15 in on_gdl_style_changed (settings=0x80b6af0, key=0x8054609 "gdl-style", user_data=0x80c4008) at anjuta-app.c:243 + +phantomjinx <p.g...@ph...> 2012-02-11 + + Plugin for attaching use of an external player + + * Allow the user to plug in their own player to play tracks + + * xmms added back as the default preference + +phantomjinx <p.g...@ph...> 2012-02-11 + + Ignore generated marshalling source files + +phantomjinx <p.g...@ph...> 2012-02-04 + + Update INSTALL file with sjcd plugin details + +phantomjinx <p.g...@ph...> 2012-01-29 + + Configure script failing without musicbrainz available + + * Check for musicbrainz3 as one of the optional dependencies + + * Don't enable sjcd plugin unless we have musicbrainz 3 + +phantomjinx <p.g...@ph...> 2012-01-29 + + Add sjcd plugin icon for preference dialog + + * Use the sound juicer icon for the category icon for sjcd in the + preferences dialog + +phantomjinx <p.g...@ph...> 2012-01-28 + + Import tracks once sjcd has ripped them + + * bacon-message-connection files not necessary since a flashing application + is not required. + + * sj-extractor.c + * documentation recommends using gst_bus_timed_pop_filtered instead of + gt_bus_poll + + * sj-main.c + * Remove unneeded callbacks + + * sj-extracing.c + * Remove remaining play button references as not used and generating + warnings + * add import_files_to_itdb function to take the files ripped by sjcd and + import them into the selected itdb + +phantomjinx <p.g...@ph...> 2012-01-28 + + Clear up and handle threading issues correctly + + * main.c + * It is recommended practice to have gdk_threads functions surrounding + the gtk_main function + + * normal_sorttab_page.c + * media_player.c + * display_tracks.c + * tidy up some erroneous debug statements + * replace g_idle_add with gdk_threads_add_idle + +phantomjinx <p.g...@ph...> 2012-01-21 + + Get the preference window to appear correctly + + * Window available as separate dialog from sj edit menu or from the gtkpod + preference window. + +phantomjinx <p.g...@ph...> 2012-01-21 + + Fix errors to get the sj gui to appear cleanly + + * configure.ac + * gstreamer-pbutils is required + * Split out the SOUND_JUICER package checks since brasero is needed to be + checked on initialisation of main app. + * Declare and link both gstreamer and brasero so that their goptions can + be properly checked when starting gtkpod. This is necessary in the case + of gstreamer as certain arrays and hashmaps in gstvalue are only inited + via the parsing of the gst_init_option_group function. + + * plugins/sjcd + * Needs to link against brasero and canberra explicitly due to configure + changes + * Restore stock_init function for loading the CD extract icon + * Audio volume changed callback not required + * Remove some exit(1)s + * Remove destroy callbacks + + * src/main.c + * Support for goption use on the command line + +phantomjinx <p.g...@ph...> 2012-01-02 + + Refactor sjcd plugin codebase for use in gtkpod + + * sj-main.c + * Most refactoring to return the gtk vbox rather than displaying a window + independently. + +phantomjinx <p.g...@ph...> 2012-01-02 + + Refactor the configure script to group together the module checks + + * Since more libraries are being used by multiple plugins, it is better to + check the libraries then enable the plugins accordingly. + +phantomjinx <p.g...@ph...> 2012-01-02 + + Boiler plate for sjcd plugin + + * includes acknowledgement of sound-juicer authors in AUTHORS file + +phantomjinx <p.g...@ph...> 2012-01-02 + + Initial addition of sound juicer codebase as sjcd plugin + +phantomjinx <p.g...@ph...> 2012-01-28 + + Update version to reflect unstable builds + +Merge: 1939051 4de9e60 +phantomjinx <p.g...@ph...> 2012-01-28 + + Merge branch 'gtk-3.0' + + Conflicts: +po/it.po +version.sh + phantomjinx <p.g...@ph...> 2012-01-08 Updates to Changelog and NEWS @@ -290,6 +723,16 @@ phantomjinx <p.g...@ph...> 2011-10-03 Fixes:3413192 - Not obvious how to delete a playlist without selecting from +Daniele Forsi <da...@fo...> 2011-09-26 + + Update Italian translation + +Daniele Forsi <da...@fo...> 2011-09-26 + + Translation fixes + + * Mark more strings as translatable + phantomjinx <p.g...@ph...> 2011-09-25 Fix for fail message when initialising an ipod @@ -417,6 +860,12 @@ Matteo F. Vescovi <m.v...@re...> 2011-09-07 Signed-off-by: Matteo F. Vescovi <m.v...@re...> +Matteo F. Vescovi <m.v...@re...> 2011-09-07 + + version.sh: update unstable builds separator + + Signed-off-by: Matteo F. Vescovi <m.v...@re...> + phantomjinx <p.g...@ph...> 2011-09-04 Support for updating clarity when a track is modified @@ -453,6 +902,10 @@ phantomjinx <p.g...@ph...> 2011-09-04 Update version to reflect for unstable builds +phantomjinx <p.g...@ph...> 2011-09-04 + + Update version to reflect for unstable builds + phantomjinx <p.g...@ph...> 2011-09-03 Clarity text not being cleared diff --git a/INSTALL b/INSTALL index 48c3dfc..a737c78 100644 --- a/INSTALL +++ b/INSTALL @@ -4,8 +4,7 @@ How to compile/install gtkpod: 1. First, make sure you have compiled and installed the dependencies. Most Linux distros will include them, except maybe for libid3tag - (http://sourceforge.net/project/showfiles.php?group_id=12349) and - libmp4v2 (http://mpeg4ip.sourceforge.net/). + (http://sourceforge.net/project/showfiles.php?group_id=12349). Please do not confuse the libid3 library with the libid3tag library -- they are not related. libid3tag is part of the MAD @@ -29,7 +28,6 @@ How to compile/install gtkpod: anjuta libid3tag (at least 0.15) libgnome-vfs-2.0 > 2.6 (for iPod autodetection under GNOME) - libhal > 0.5 < 0.6 (in combination with libgnome-vfs: better detection of iPods) Optional Packages @@ -49,7 +47,6 @@ How to compile/install gtkpod: libogg libvorbis lame - libmp4v2 faad2 For opengl coverart display (clarity) plugin: @@ -81,14 +78,15 @@ How to compile/install gtkpod: libogg-dev \ libvorbis-dev \ libmp3lame-dev \ - libmp4v2-dev \ libclutter-gtk-1.0-dev \ libgpod-dev \ libanjuta-dev \ libgdl-3-dev \ libid3tag0-dev faad \ - libcurl3 + libcurl3 \ + libbrasero-media3-dev \ + libmusicbrainz3-dev The following can be used for installing the dependencies on fedora 15: @@ -103,14 +101,15 @@ How to compile/install gtkpod: libogg-devel.i686 \ libvorbis-devel.i686 \ lame-devel.i686 \ - libmp4v2-devel.i686 \ clutter-gtk-devel.i686 \ libpod-devel \ anjuta-devel \ libgdl-devel \ libid3tag-devel \ faad2 \ - curl + curl-devel \ + brasero-devel \ + libmusicbrainz3-devel 2. If you install libraries to /usr/local/lib please don't forget to add the path to LD_LIBRARY_PATH and PKG_CONFIG_PATH @@ -183,7 +182,7 @@ The following steps were necessary to install libgpod and gtkpod on a fairly vir sudo apt-get install autoconf flex gettext libglib2.0-dev libgtk2.0-dev libglade2-dev libid3tag0-dev libxml-parser-perl pkg-config automake gcc git-core gtk-doc-tools # recommended packages -sudo apt-get install libcurl4-dev libflac-dev libgnomevfs2-dev libhal-dev libvorbis-dev libmp4v2-dev libwebkit-dev +sudo apt-get install libcurl4-dev libflac-dev libgnomevfs2-dev libhal-dev libvorbis-dev libwebkit-dev # checkout libgpod and gtkpod git clone git://gtkpod.git.sourceforge.net/gitroot/gtkpod/libgpod diff --git a/NEWS b/NEWS index d2711ea..e6cc985 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,26 @@ +gtkpod V2.1.2 + + Incremental release + + FEATURE: sjcd plugin, incorporating the sound juicer CD ripper into gtkpod + + FEATURE: external player plugin restoring functionality to play tracks through a configured external + media player + + FEATURE: replace dependency on libmp4v2 (incompatible licence) with integrated mp4 read/write library + based on the atomic parsley application (http://atomicparsley.sourceforge.net) + + IMPROVEMENT: Reduce time for listing of tracks in track display in big repositories + + BUGFIX: Fix threading issues / deadlocks with music player, filters and track display + + BUGFIX: Fix crash when anjuta g_settings schema is not installed + + BUGFIX: Fixes highlighted by clang compiler (thank to Daniel Forsi) + + BUGFIX: Fix for double free when adding music using the 'add folder' command + + gtkpod V2.1.1 Incremental release |
From: phantomjinx <pha...@us...> - 2012-06-01 08:18:28
|
commit 0ca1e68ddd703d6b30de2888c67119b97d55d0c7 Author: phantomjinx <p.g...@ph...> Date: Fri May 25 09:57:55 2012 +0100 Update and fix sjcd plugin * Update sjcd plugin to reflect latest developements in sound juicer including use of musicbrainz 4 * sj_extracting.c * Avoid segfaulting if a track value is empty. Happen to have a CD that failed to return any track names for an album - maybe a bug in the sound juicer musicbrainz 4 code configure.ac | 50 ++- plugins/sjcd/data/Makefile.am | 1 + plugins/sjcd/libjuicer/Makefile.am | 13 +- plugins/sjcd/libjuicer/sj-metadata-getter.c | 6 + plugins/sjcd/libjuicer/sj-metadata-musicbrainz4.c | 621 +++++++++++++++++++++ plugins/sjcd/libjuicer/sj-metadata-musicbrainz4.h | 56 ++ plugins/sjcd/libjuicer/sj-structures.c | 22 + plugins/sjcd/libjuicer/sj-structures.h | 25 + plugins/sjcd/sj-extracting.c | 15 + plugins/sjcd/sj-main.c | 23 +- po/POTFILES.in | 1 + 11 files changed, 796 insertions(+), 37 deletions(-) --- diff --git a/configure.ac b/configure.ac index 779f3dd..ed37002 100644 --- a/configure.ac +++ b/configure.ac @@ -105,6 +105,7 @@ PKG_CHECK_MODULES(BRASERO, libbrasero-media3 >= 3.0, [have_brasero="yes"], [have dnl musicbrainz 3 is deprecated so may not be included. However required by sound juicer dnl will probably need replacing faily soon PKG_CHECK_MODULES(MUSICBRAINZ3, libmusicbrainz3 >= 3.0.2, [have_mb3="yes"], [have_mb3="no"]) +PKG_CHECK_MODULES(MUSICBRAINZ4, libmusicbrainz4 >= 4.0.0, [have_mb4="yes"], [have_mb4="no"]) GTK_CLEANLINESS_FLAGS="-DG_DISABLE_SINGLE_INCLUDES -DGDK_PIXBUF_DISABLE_SINGLE_INCLUDES -DGTK_DISABLE_SINGLE_INCLUDES -DGSEAL_ENABLE" @@ -189,7 +190,7 @@ dnl Check for libcurl dnl ------------------------------------------------------------- AC_ARG_WITH(curl, AS_HELP_STRING([--without-curl],[Disable coverart download support])) if test "x$with_curl" != "xno" -a "x$have_curl" = "xno"; then - AC_MSG_ERROR([curl support explicitly requested but curl couldn't be found]) + AC_MSG_ERROR([curl support explicitly requested but curl could not be found]) fi AM_CONDITIONAL(HAVE_CURL, test "x$have_curl" = "xyes") @@ -287,7 +288,7 @@ dnl Checks for filetype_ogg plugin dnl ------------------------------------------------------------- AC_ARG_WITH(ogg, AS_HELP_STRING([--without-ogg],[Disable Ogg/Vorbis support])) if test "x$with_ogg" != "xno" -a "x$have_vorbis" = "xno"; then - AC_MSG_ERROR([Ogg/Vorbis support explicitly requested but ogg/vorbis libs couldn't be found]) + AC_MSG_ERROR([Ogg/Vorbis support explicitly requested but ogg/vorbis libs could not be found]) fi AM_CONDITIONAL(HAVE_PLUGIN_FILETYPE_OGG, test "x$have_vorbis" = "xyes") if test "x$have_vorbis" = "xyes"; then @@ -299,7 +300,7 @@ dnl Checks for filetype_flac plugin dnl ------------------------------------------------------------- AC_ARG_WITH(flac, AS_HELP_STRING([--without-flac],[Disable FLAC support])) if test "xwith_flac" = "xyes" -a "x$have_flac" = "xno"; then - AC_MSG_ERROR([FLAC support explicitly requested but flac libs couldn't be found]) + AC_MSG_ERROR([FLAC support explicitly requested but flac libs could not be found]) fi AM_CONDITIONAL(HAVE_PLUGIN_FILETYPE_FLAC, test "x$have_flac" = "xyes") if test "x$have_flac" = "xyes"; then @@ -357,23 +358,42 @@ if test "$user_disabled_sjcd" = 1; then else AC_MSG_RESULT(no) AC_MSG_CHECKING(sjcd plugin dependencies) - if test "x$have_gstreamer" = "xyes" -a "x$have_brasero" = "xyes" -a "x$have_mb3" = "xyes"; then - AC_MSG_RESULT(yes) - have_sjcd="yes" + if test "x$have_gstreamer" = "xyes" -a "x$have_brasero" = "xyes"; then + if test "x$have_mb3" = "xyes" -o "x$have_mb4" = "xyes"; then + + AC_MSG_RESULT(yes) + have_sjcd="yes" - dnl Checks for components of gstreamer - AM_GST_ELEMENT_CHECK(vorbisenc,,AC_MSG_WARN([The 'vorbisenc' element was not found. This will cause encoding to Ogg Vorbis to fail.])) - AM_GST_ELEMENT_CHECK(flacenc,,AC_MSG_WARN([The 'flacenc' element was not found. This will cause encoding to FLAC to fail.])) - AM_GST_ELEMENT_CHECK(wavenc,,AC_MSG_WARN([The 'wavenc' element was not found. This will cause encoding to Wave to fail.])) - AM_GST_ELEMENT_CHECK(giosink,,AC_MSG_WARN([The 'giosink' element was not found. This will cause Sound Juicer to fail at runtime.])) + dnl Checks for components of gstreamer + AM_GST_ELEMENT_CHECK(vorbisenc,,AC_MSG_WARN([The 'vorbisenc' element was not found. This will cause encoding to Ogg Vorbis to fail.])) + AM_GST_ELEMENT_CHECK(flacenc,,AC_MSG_WARN([The 'flacenc' element was not found. This will cause encoding to FLAC to fail.])) + AM_GST_ELEMENT_CHECK(wavenc,,AC_MSG_WARN([The 'wavenc' element was not found. This will cause encoding to Wave to fail.])) + AM_GST_ELEMENT_CHECK(giosink,,AC_MSG_WARN([The 'giosink' element was not found. This will cause Sound Juicer to fail at runtime.])) - AC_DEFINE([HAVE_MUSICBRAINZ3], 1, [Whether libmusicbrainz3 is available]) - else - AC_MSG_RESULT(no) + if test "x$have_mb4" = "xyes"; then + AC_DEFINE([HAVE_MUSICBRAINZ4], 1, [Whether libmusicbrainz4 is available]) + elif test "x$have_mb3" = "xyes"; then + dnl fallback to musicbrainz 3 + AC_DEFINE([HAVE_MUSICBRAINZ3], 1, [Whether libmusicbrainz3 is available]) + fi + + else + AC_MSG_RESULT(no) + fi fi fi -AM_CONDITIONAL(HAVE_MUSICBRAINZ3, [test "x$have_mb3" = "xyes"]) +if test "x$have_mb4" = "xyes"; then + AM_CONDITIONAL(HAVE_MUSICBRAINZ4, true) + dnl do not need musicbrainz 3 + AM_CONDITIONAL(HAVE_MUSICBRAINZ3, false) +elif test "xhave_mb3" = "xyes"; then + AM_CONDITIONAL(HAVE_MUSICBRAINZ4, false) + AM_CONDITIONAL(HAVE_MUSICBRAINZ3, true) +else + AM_CONDITIONAL(HAVE_MUSICBRAINZ4, false) + AM_CONDITIONAL(HAVE_MUSICBRAINZ3, false) +fi AM_CONDITIONAL(HAVE_PLUGIN_SJCD, [test "x$have_sjcd" = "xyes"]) if test "x$have_sjcd" = "xyes"; then AC_DEFINE(HAVE_PLUGIN_SJCD, 1, [Define if you have sound juicer support]) diff --git a/plugins/sjcd/data/Makefile.am b/plugins/sjcd/data/Makefile.am index 5f2a768..3040511 100644 --- a/plugins/sjcd/data/Makefile.am +++ b/plugins/sjcd/data/Makefile.am @@ -1,5 +1,6 @@ profilesdir = $(pkgdatadir)/data profiles_DATA = rhythmbox.gep +dist_profiles_DATA = rhythmbox.gep # gsettings_SCHEMAS is a list of all the schemas you want to install schema_in_files = org.gtkpod.sjcd.gschema.xml.in diff --git a/plugins/sjcd/libjuicer/Makefile.am b/plugins/sjcd/libjuicer/Makefile.am index dceb8fa..7854e15 100644 --- a/plugins/sjcd/libjuicer/Makefile.am +++ b/plugins/sjcd/libjuicer/Makefile.am @@ -25,13 +25,11 @@ libjuicer_la_CPPFLAGS = \ libjuicer_la_CFLAGS = \ $(WARN_CFLAGS) \ $(SOUND_JUICER_CFLAGS) \ - $(MUSICBRAINZ3_CFLAGS) \ $(GSTREAMER_CFLAGS) \ $(AM_CFLAGS) libjuicer_la_LIBADD = \ $(SOUND_JUICER_LIBS) \ - $(MUSICBRAINZ3_LIBS) \ $(GSTREAMER_LIBS) libjuicer_la_LDFLAGS = \ @@ -42,8 +40,19 @@ if HAVE_MUSICBRAINZ3 libjuicer_la_SOURCES += \ sj-metadata-musicbrainz3.h \ sj-metadata-musicbrainz3.c +libjuicer_la_LIBADD += $(MUSICBRAINZ3_LIBS) +libjuicer_la_CFLAGS += $(MUSICBRAINZ3_CFLAGS) endif +if HAVE_MUSICBRAINZ4 +libjuicer_la_SOURCES += \ + sj-metadata-musicbrainz4.h \ + sj-metadata-musicbrainz4.c +libjuicer_la_LIBADD += $(MUSICBRAINZ4_LIBS) +libjuicer_la_CFLAGS += $(MUSICBRAINZ4_CFLAGS) +endif + + # # Build the GValue marshals # diff --git a/plugins/sjcd/libjuicer/sj-metadata-getter.c b/plugins/sjcd/libjuicer/sj-metadata-getter.c index 1aff2f5..11002fa 100644 --- a/plugins/sjcd/libjuicer/sj-metadata-getter.c +++ b/plugins/sjcd/libjuicer/sj-metadata-getter.c @@ -26,6 +26,9 @@ #include "sj-metadata-getter.h" #include "sj-metadata-marshal.h" #include "sj-metadata.h" +#ifdef HAVE_MUSICBRAINZ4 +#include "sj-metadata-musicbrainz4.h" +#endif /* HAVE_MUSICBRAINZ4 */ #ifdef HAVE_MUSICBRAINZ3 #include "sj-metadata-musicbrainz3.h" #endif /* HAVE_MUSICBRAINZ3 */ @@ -175,6 +178,9 @@ lookup_cd (SjMetadataGetter *mdg) GError *error = NULL; gboolean found = FALSE; GType types[] = { +#ifdef HAVE_MUSICBRAINZ4 + SJ_TYPE_METADATA_MUSICBRAINZ4, +#endif /* HAVE_MUSICBRAINZ4 */ #ifdef HAVE_MUSICBRAINZ3 SJ_TYPE_METADATA_MUSICBRAINZ3, #endif /* HAVE_MUSICBRAINZ3 */ diff --git a/plugins/sjcd/libjuicer/sj-metadata-musicbrainz4.c b/plugins/sjcd/libjuicer/sj-metadata-musicbrainz4.c new file mode 100644 index 0000000..3af7558 --- /dev/null +++ b/plugins/sjcd/libjuicer/sj-metadata-musicbrainz4.c @@ -0,0 +1,621 @@ +/* + * sj-metadata-musicbrainz4.c + * Copyright (C) 2008 Ross Burton <ro...@bu...> + * Copyright (C) 2008 Bastien Nocera <ha...@ha...> + * Copyright (C) 2011 Christophe Fergeau <cfe...@re...> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <string.h> +#include <stdlib.h> +#include <glib.h> +#include <glib-object.h> +#include <gio/gio.h> +#include <discid/discid.h> +#include <musicbrainz4/mb4_c.h> + +#include "sj-metadata-musicbrainz4.h" +#include "sj-structures.h" +#include "sj-error.h" + +#define GET(field, function, obj) { \ + function (obj, buffer, sizeof (buffer)); \ + if (field) \ + g_free (field); \ + if (*buffer == '\0') \ + field = NULL; \ + else \ + field = g_strdup (buffer); \ +} + +#if 0 +#define SJ_SETTINGS_MUSICBRAINZ_SERVER "/apps/sound-juicer/musicbrainz_server" +#endif +#define SJ_SETTINGS_PROXY_USE_PROXY "enabled" +#define SJ_SETTINGS_PROXY_HOST "host" +#define SJ_SETTINGS_PROXY_PORT "port" +#define SJ_SETTINGS_PROXY_USE_AUTHENTICATION "use-authentication" +#define SJ_SETTINGS_PROXY_USERNAME "authentication-user" +#define SJ_SETTINGS_PROXY_PASSWORD "authentication-password" +#define SJ_MUSICBRAINZ_USER_AGENT "libjuicer-"VERSION + +typedef struct { + Mb4Query mb; + DiscId *disc; + char *cdrom; + /* Proxy */ + char *http_proxy; + int http_proxy_port; +} SjMetadataMusicbrainz4Private; + +#define GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), SJ_TYPE_METADATA_MUSICBRAINZ4, SjMetadataMusicbrainz4Private)) + +enum { + PROP_0, + PROP_DEVICE, + PROP_USE_PROXY, + PROP_PROXY_HOST, + PROP_PROXY_PORT, +}; + +static void metadata_interface_init (gpointer g_iface, gpointer iface_data); + +G_DEFINE_TYPE_WITH_CODE (SjMetadataMusicbrainz4, + sj_metadata_musicbrainz4, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (SJ_TYPE_METADATA, + metadata_interface_init)); + + +/* + * Private methods + */ +#ifdef DUMP_DETAILS +static void +sj_mb4_album_details_dump (AlbumDetails *details) +{ + if (details->country) + g_print ("Country: %s\n", details->country); + if (details->type) + g_print ("Type: %s\n", details->type); + if (details->lyrics_url) + g_print ("Lyrics URL: %s\n", details->lyrics_url); +} +#else +#define sj_mb4_album_details_dump(...) +#endif + +static GList * +get_artist_list (Mb4ArtistCredit credit) +{ + Mb4NameCreditList name_list; + GList *artists; + unsigned int i; + char buffer[512]; /* for the GET macro */ + + if (credit == NULL) + return NULL; + + name_list = mb4_artistcredit_get_namecreditlist (credit); + if (name_list == NULL) { + return NULL; + } + + artists = NULL; + for (i = 0; i < mb4_namecredit_list_size (name_list); i++) { + Mb4NameCredit name_credit; + Mb4Artist artist; + ArtistDetails *details; + + name_credit = mb4_namecredit_list_item (name_list, i); + details = g_new0 (ArtistDetails, 1); + GET (details->joinphrase, mb4_namecredit_get_joinphrase, name_credit); + artists = g_list_prepend (artists, details); + artist = mb4_namecredit_get_artist (name_credit); + if (!artist) { + g_warning ("no Mb4Artist associated with Mb4NameCredit, falling back to Mb4NameCredit::name"); + GET (details->name, mb4_namecredit_get_name, name_credit); + continue; + } + + GET (details->id, mb4_artist_get_id, artist); + GET (details->name, mb4_artist_get_name, artist); + GET (details->sortname, mb4_artist_get_sortname, artist); + GET (details->disambiguation, mb4_artist_get_disambiguation, artist); + GET (details->gender, mb4_artist_get_gender, artist); + GET (details->country, mb4_artist_get_country, artist); + } + + return g_list_reverse(artists); +} + +static void +get_artist_info (GList *artists, char **name, char **sortname, char **id) +{ + GString *artist_name; + GList *it; + unsigned int artist_count; + + artist_name = g_string_new (NULL); + artist_count = 0; + for (it = artists; it != NULL; it = it->next) { + ArtistDetails *details = (ArtistDetails *)it->data; + artist_count++; + g_string_append (artist_name, details->name); + if (details->joinphrase != NULL) + g_string_append (artist_name, details->joinphrase); + } + + if (artist_count != 1) { + g_warning ("multiple artists"); + if (sortname != NULL) + *sortname = NULL; + if (id != NULL) + *id = NULL; + } else { + ArtistDetails *details = (ArtistDetails *)artists->data; + if (sortname != NULL) + *sortname = g_strdup (details->sortname); + if (id != NULL) + *id = g_strdup (details->id); + } + + if (name != NULL) + *name = artist_name->str; + + g_string_free (artist_name, FALSE); +} + + +static void +fill_relations (Mb4RelationList relations, AlbumDetails *album) +{ + unsigned int i; + + for (i = 0; i < mb4_relation_list_size (relations); i++) { + Mb4Relation relation; + char buffer[512]; /* for the GET() macro */ + char *type = NULL; + + relation = mb4_relation_list_item (relations, i); + if (relation == NULL) + continue; + + GET (type, mb4_relation_get_type, relation); + if (type == NULL) { + continue; + } + if (g_str_equal (type, "wikipedia")) { + char *wikipedia = NULL; + GET (wikipedia, mb4_relation_get_target, relation); + if (wikipedia != NULL) { + g_free (album->wikipedia); + album->wikipedia = wikipedia; + } + } else if (g_str_equal (type, "discogs")) { + char *discogs = NULL; + GET (discogs, mb4_relation_get_target, relation); + if (discogs != NULL) { + g_free (album->discogs); + album->discogs = discogs; + } + } else if (g_str_equal (type, "lyrics")) { + char *lyrics = NULL; + GET (lyrics, mb4_relation_get_target, relation); + if (lyrics != NULL) { + g_free (album->lyrics_url); + album->lyrics_url = lyrics; + } + } + g_free (type); + } +} + +static void +fill_tracks_from_medium (Mb4Medium medium, AlbumDetails *album) +{ + Mb4TrackList track_list; + GList *tracks; + unsigned int i; + char buffer[512]; /* for the GET() macro */ + + track_list = mb4_medium_get_tracklist (medium); + if (!track_list) + return; + + album->number = mb4_track_list_size (track_list); + + tracks = NULL; + + for (i = 0; i < mb4_track_list_size (track_list); i++) { + Mb4Track mbt; + Mb4ArtistCredit credit; + Mb4Recording recording; + TrackDetails *track; + + mbt = mb4_track_list_item (track_list, i); + if (!mbt) + continue; + + track = g_new0 (TrackDetails, 1); + + track->album = album; + + track->number = mb4_track_get_position (mbt); + recording = mb4_track_get_recording (mbt); + if (recording != NULL) { + GET (track->title, mb4_recording_get_title, recording); + GET (track->track_id, mb4_recording_get_id, recording); + track->duration = mb4_recording_get_length (recording) / 1000; + credit = mb4_recording_get_artistcredit (recording); + } else { + GET (track->title, mb4_track_get_title, mbt); + track->duration = mb4_track_get_length (mbt) / 1000; + credit = mb4_track_get_artistcredit (mbt); + } + + if (credit) { + GList *artists; + artists = get_artist_list (credit); + if (artists) { + get_artist_info (artists, &track->artist, + &track->artist_sortname, + &track->artist_id); + } + track->artists = artists; + } + if (track->artist == NULL) + track->artist = g_strdup (album->artist); + if (track->artist_sortname == NULL) + track->artist_sortname = g_strdup (album->artist_sortname); + if (track->artist_id == NULL) + track->artist_id = g_strdup (album->artist_id); + + tracks = g_list_prepend (tracks, track); + } + album->tracks = g_list_reverse (tracks); +} + +static AlbumDetails * +make_album_from_release (Mb4ReleaseGroup group, + Mb4Release release, + Mb4Medium medium) +{ + AlbumDetails *album; + Mb4ArtistCredit credit; + GList *artists; + char *date = NULL; + char buffer[512]; /* for the GET macro */ + + g_assert (release); + g_return_val_if_fail (medium != NULL, NULL); + + album = g_new0 (AlbumDetails, 1); + + GET (album->album_id, mb4_release_get_id, release); + GET (album->title, mb4_medium_get_title, medium); + if (album->title == NULL) + GET (album->title, mb4_release_get_title, release); + + credit = mb4_release_get_artistcredit (release); + + artists = get_artist_list (credit); + if (artists) { + get_artist_info (artists, &album->artist, + &album->artist_sortname, + &album->artist_id); + } + album->artists = artists; + + GET (date, mb4_release_get_date, release); + album->release_date = sj_metadata_helper_scan_date (date); + g_free (date); + + GET (album->asin, mb4_release_get_asin, release); + GET (album->country, mb4_release_get_country, release); + if (group) { + GET (album->type, mb4_releasegroup_get_type, group); + if (g_str_has_suffix (album->type, "Spokenword") + || g_str_has_suffix (album->type, "Interview") + || g_str_has_suffix (album->type, "Audiobook")) { + album->is_spoken_word = TRUE; + } + fill_relations (mb4_releasegroup_get_relationlist(group), album); + } + + album->disc_number = mb4_medium_get_position (medium); + fill_tracks_from_medium (medium, album); + fill_relations (mb4_release_get_relationlist (release), album); + + sj_mb4_album_details_dump (album); + return album; +} + +/* + * Virtual methods + */ +static GList * +mb4_list_albums (SjMetadata *metadata, char **url, GError **error) +{ + SjMetadataMusicbrainz4Private *priv; + GList *albums = NULL; + Mb4ReleaseList releases; + Mb4Release release; + const char *discid = NULL; + char buffer[1024]; + int i; + g_return_val_if_fail (SJ_IS_METADATA_MUSICBRAINZ4 (metadata), NULL); + + priv = GET_PRIVATE (metadata); + + if (sj_metadata_helper_check_media (priv->cdrom, error) == FALSE) { + return NULL; + } + + priv->disc = discid_new (); + if (priv->disc == NULL) + return NULL; + if (discid_read (priv->disc, priv->cdrom) == 0) + return NULL; + + if (url != NULL) + *url = g_strdup (discid_get_submission_url (priv->disc)); + + if (g_getenv("MUSICBRAINZ_FORCE_DISC_ID")) { + discid = g_getenv("MUSICBRAINZ_FORCE_DISC_ID"); + } else { + discid = discid_get_id (priv->disc); + } + + releases = mb4_query_lookup_discid(priv->mb, discid); + + if (releases == NULL) { + return NULL; + } + + if (mb4_release_list_size (releases) == 0) { + return NULL; + } + + for (i = 0; i < mb4_release_list_size (releases); i++) { + AlbumDetails *album; + + release = mb4_release_list_item (releases, i); + if (release) { + char *releaseid = NULL; + Mb4Release full_release; + + releaseid = NULL; + GET(releaseid, mb4_release_get_id, release); + + full_release = mb4_query_lookup_release (priv->mb, releaseid); + g_free (releaseid); + if (full_release) { + Mb4MediumList media; + Mb4Metadata metadata = NULL; + Mb4ReleaseGroup group; + unsigned int j; + + group = mb4_release_get_releasegroup (full_release); + if (group) { + /* The release-group information we can extract from the + * lookup_release query doesn't have the url relations for the + * release-group, so run a separate query to get these urls + */ + char *releasegroupid = NULL; + char *params_names[] = { "inc" }; + char *params_values[] = { "artists url-rels" }; + + GET (releasegroupid, mb4_releasegroup_get_id, group); + metadata = mb4_query_query (priv->mb, "release-group", releasegroupid, "", + 1, params_names, params_values); + g_free (releasegroupid); + } + + if (metadata && mb4_metadata_get_releasegroup (metadata)) + group = mb4_metadata_get_releasegroup (metadata); + + media = mb4_release_media_matching_discid (full_release, discid); + for (j = 0; j < mb4_medium_list_size (media); j++) { + Mb4Medium medium; + medium = mb4_medium_list_item (media, j); + if (medium) { + album = make_album_from_release (group, full_release, medium); + album->metadata_source = SOURCE_MUSICBRAINZ; + albums = g_list_append (albums, album); + } + } + mb4_metadata_delete (metadata); + mb4_medium_list_delete (media); + mb4_release_delete (full_release); + } + } + } + mb4_release_list_delete (releases); + return albums; +} + +/* + * GObject methods + */ + +static void +metadata_interface_init (gpointer g_iface, gpointer iface_data) +{ + SjMetadataClass *klass = (SjMetadataClass*)g_iface; + + klass->list_albums = mb4_list_albums; +} + +static void +sj_metadata_musicbrainz4_init (SjMetadataMusicbrainz4 *self) +{ + GSettings *settings; + + SjMetadataMusicbrainz4Private *priv; + + priv = GET_PRIVATE (self); + + settings = g_settings_new ("org.gnome.system.proxy.http"); + +#if 0 + gchar *server_name; + + server_name = g_settings_get_string (settings, SJ_SETTINGS_MUSICBRAINZ_SERVER); + + if (server_name && (*server_name == '\0')) { + g_free (server_name); + server_name = NULL; + } + + priv->mb = mb4_query_new (SJ_MUSICBRAINZ_USER_AGENT, server_name, 0); + g_free (server_name); +#endif + + priv->mb = mb4_query_new (SJ_MUSICBRAINZ_USER_AGENT, NULL, 0); + + /* Set the HTTP proxy */ + if (g_settings_get_boolean (settings, SJ_SETTINGS_PROXY_USE_PROXY)) { + char *proxy_host; + int port; + + proxy_host = g_settings_get_string (settings, SJ_SETTINGS_PROXY_HOST); + mb4_query_set_proxyhost (priv->mb, proxy_host); + g_free (proxy_host); + + port = g_settings_get_int (settings, SJ_SETTINGS_PROXY_PORT); + mb4_query_set_proxyport (priv->mb, port); + + if (g_settings_get_boolean (settings, SJ_SETTINGS_PROXY_USE_AUTHENTICATION)) { + char *username, *password; + + username = g_settings_get_string (settings, SJ_SETTINGS_PROXY_USERNAME); + mb4_query_set_proxyusername (priv->mb, username); + g_free (username); + + password = g_settings_get_string (settings, SJ_SETTINGS_PROXY_PASSWORD); + mb4_query_set_proxypassword (priv->mb, password); + g_free (password); + } + } + + g_object_unref (settings); +} + +static void +sj_metadata_musicbrainz4_get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + SjMetadataMusicbrainz4Private *priv = GET_PRIVATE (object); + g_assert (priv); + + switch (property_id) { + case PROP_DEVICE: + g_value_set_string (value, priv->cdrom); + break; + case PROP_PROXY_HOST: + g_value_set_string (value, priv->http_proxy); + break; + case PROP_PROXY_PORT: + g_value_set_int (value, priv->http_proxy_port); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +sj_metadata_musicbrainz4_set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + SjMetadataMusicbrainz4Private *priv = GET_PRIVATE (object); + g_assert (priv); + + switch (property_id) { + case PROP_DEVICE: + if (priv->cdrom) + g_free (priv->cdrom); + priv->cdrom = g_value_dup_string (value); + break; + case PROP_PROXY_HOST: + if (priv->http_proxy) { + g_free (priv->http_proxy); + } + priv->http_proxy = g_value_dup_string (value); + /* TODO: check this unsets the proxy if NULL, or should we pass "" ? */ + mb4_query_set_proxyhost (priv->mb, priv->http_proxy); + break; + case PROP_PROXY_PORT: + priv->http_proxy_port = g_value_get_int (value); + mb4_query_set_proxyport (priv->mb, priv->http_proxy_port); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +sj_metadata_musicbrainz4_finalize (GObject *object) +{ + SjMetadataMusicbrainz4Private *priv; + + priv = GET_PRIVATE (object); + + if (priv->mb != NULL) { + mb4_query_delete (priv->mb); + priv->mb = NULL; + } + if (priv->disc != NULL) { + discid_free (priv->disc); + priv->disc = NULL; + } + g_free (priv->cdrom); + + G_OBJECT_CLASS (sj_metadata_musicbrainz4_parent_class)->finalize (object); +} + +static void +sj_metadata_musicbrainz4_class_init (SjMetadataMusicbrainz4Class *class) +{ + GObjectClass *object_class = (GObjectClass*)class; + + g_type_class_add_private (class, sizeof (SjMetadataMusicbrainz4Private)); + + object_class->get_property = sj_metadata_musicbrainz4_get_property; + object_class->set_property = sj_metadata_musicbrainz4_set_property; + object_class->finalize = sj_metadata_musicbrainz4_finalize; + + g_object_class_override_property (object_class, PROP_DEVICE, "device"); + g_object_class_override_property (object_class, PROP_PROXY_HOST, "proxy-host"); + g_object_class_override_property (object_class, PROP_PROXY_PORT, "proxy-port"); +} + + +/* + * Public methods. + */ + +GObject * +sj_metadata_musicbrainz4_new (void) +{ + return g_object_new (SJ_TYPE_METADATA_MUSICBRAINZ4, NULL); +} diff --git a/plugins/sjcd/libjuicer/sj-metadata-musicbrainz4.h b/plugins/sjcd/libjuicer/sj-metadata-musicbrainz4.h new file mode 100644 index 0000000..5a73e9b --- /dev/null +++ b/plugins/sjcd/libjuicer/sj-metadata-musicbrainz4.h @@ -0,0 +1,56 @@ +/* + * sj-metadata-musicbrainz4.h + * Copyright (C) 2008 Ross Burton <ro...@bu...> + * Copyright (C) 2008 Bastien Nocera <ha...@ha...> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SJ_METADATA_MUSICBRAINZ4_H +#define SJ_METADATA_MUSICBRAINZ4_H + +#include <glib-object.h> +#include "sj-metadata.h" + +G_BEGIN_DECLS + +#define SJ_TYPE_METADATA_MUSICBRAINZ4 (sj_metadata_musicbrainz4_get_type ()) +#define SJ_METADATA_MUSICBRAINZ4(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SJ_TYPE_METADATA_MUSICBRAINZ4, SjMetadataMusicbrainz4)) +#define SJ_METADATA_MUSICBRAINZ4_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), SJ_TYPE_METADATA_MUSICBRAINZ4, SjMetadataMusicbrainz4Class)) +#define SJ_IS_METADATA_MUSICBRAINZ4(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SJ_TYPE_METADATA_MUSICBRAINZ4)) +#define SJ_IS_METADATA_MUSICBRAINZ4_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), SJ_TYPE_METADATA_MUSICBRAINZ4)) +#define SJ_METADATA_MUSICBRAINZ4_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SJ_TYPE_METADATA_MUSICBRAINZ4, SjMetadataMusicbrainz4Class)) + +typedef struct _SjMetadataMusicbrainz4 SjMetadataMusicbrainz4; +typedef struct _SjMetadataMusicbrainz4Class SjMetadataMusicbrainz4Class; + +struct _SjMetadataMusicbrainz4 +{ + GObject parent; +}; + +struct _SjMetadataMusicbrainz4Class +{ + GObjectClass parent; +}; + +GType sj_metadata_musicbrainz4_get_type (void); + +GObject *sj_metadata_musicbrainz4_new (void); + +G_END_DECLS + +#endif /* SJ_METADATA_MUSICBRAINZ4_H */ diff --git a/plugins/sjcd/libjuicer/sj-structures.c b/plugins/sjcd/libjuicer/sj-structures.c index 3d23ce6..b4577d4 100644 --- a/plugins/sjcd/libjuicer/sj-structures.c +++ b/plugins/sjcd/libjuicer/sj-structures.c @@ -35,6 +35,8 @@ void track_details_free(TrackDetails *track) g_free (track->track_id); g_free (track->artist_id); g_free (track->artist_sortname); + g_list_foreach (track->artists, (GFunc)artist_details_free, NULL); + g_free (track); } @@ -55,5 +57,25 @@ void album_details_free(AlbumDetails *album) g_free (album->asin); g_free (album->discogs); g_free (album->wikipedia); + g_free (album->lyrics_url); + g_free (album->country); + g_free (album->type); + g_list_foreach (album->artists, (GFunc)artist_details_free, NULL); + g_free (album); } + +/* + * Free a ArtistDetails* + */ +void artist_details_free (ArtistDetails *artist) +{ + g_free (artist->id); + g_free (artist->name); + g_free (artist->sortname); + g_free (artist->disambiguation); + g_free (artist->gender); + g_free (artist->country); + g_free (artist->joinphrase); + g_free (artist); +} diff --git a/plugins/sjcd/libjuicer/sj-structures.h b/plugins/sjcd/libjuicer/sj-structures.h index 07ccc60..46d67e9 100644 --- a/plugins/sjcd/libjuicer/sj-structures.h +++ b/plugins/sjcd/libjuicer/sj-structures.h @@ -29,6 +29,7 @@ typedef enum _MetadataSource MetadataSource; typedef struct _AlbumDetails AlbumDetails; +typedef struct _ArtistDetails ArtistDetails; typedef struct _TrackDetails TrackDetails; enum _MetadataSource { @@ -48,6 +49,7 @@ struct _TrackDetails { int duration; /* seconds */ char* track_id; char* artist_id; + GList *artists; }; struct _AlbumDetails { @@ -66,9 +68,32 @@ struct _AlbumDetails { char* wikipedia; MetadataSource metadata_source; gboolean is_spoken_word; + + /* some of the new properties that we can get with the NGS musicbrainz + * API + */ + char *type; + char *lyrics_url; + char *country; + GList *artists; }; +struct _ArtistDetails { + char *id; + char *name; + char *sortname; + char *disambiguation; + char *gender; + char *country; + + /* doesn't belong in here, prevent sharing the artist structure between + * distinct ReleaseGroups - more convenient for now */ + char *joinphrase; +}; + + void album_details_free(AlbumDetails *album); +void artist_details_free(ArtistDetails *artist); void track_details_free(TrackDetails *track); #endif diff --git a/plugins/sjcd/sj-extracting.c b/plugins/sjcd/sj-extracting.c index be1d6fa..a9604fe 100644 --- a/plugins/sjcd/sj-extracting.c +++ b/plugins/sjcd/sj-extracting.c @@ -50,6 +50,8 @@ #include "sj-genres.h" #include "egg-play-preview.h" +#define UNKNOWN_TAG_VALUE "???" + typedef struct { int seconds; struct timeval time; @@ -899,6 +901,11 @@ sanitize_path (const char* str, const char* filesystem_type) gchar *res = NULL; gchar *s; + if (str == NULL) { + /* Not a lot we can do other than return an empty string */ + return g_strdup_printf(UNKNOWN_TAG_VALUE); + } + /* Skip leading periods, otherwise files disappear... */ while (*str == '.') str++; @@ -1050,10 +1057,18 @@ filepath_parse_pattern (const char* pattern, const TrackDetails *track) switch (*++p) { case 't': string = sanitize_path (track->title, filesystem_type); + if (g_strcmp0(string, UNKNOWN_TAG_VALUE) == 0) { + g_free(string); + string = g_strdup_printf ("%d", track->number); + } break; case 'T': tmp = g_utf8_strdown (track->title, -1); string = sanitize_path (tmp, filesystem_type); + if (g_strcmp0(string, UNKNOWN_TAG_VALUE) == 0) { + g_free(string); + string = g_strdup_printf ("%d", track->number); + } g_free(tmp); break; case 'a': diff --git a/plugins/sjcd/sj-main.c b/plugins/sjcd/sj-main.c index 8ad0cc8..484c6d0 100644 --- a/plugins/sjcd/sj-main.c +++ b/plugins/sjcd/sj-main.c @@ -237,7 +237,7 @@ set_info_bar_text_and_icon (GtkInfoBar *infobar, ally_target = gtk_widget_get_accessible (button); - hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); + hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); gtk_widget_show (hbox_content); image = gtk_image_new_from_stock (icon_stock_id, GTK_ICON_SIZE_DIALOG); @@ -245,7 +245,7 @@ set_info_bar_text_and_icon (GtkInfoBar *infobar, gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0); - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_widget_show (vbox); gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0); @@ -977,24 +977,7 @@ static void profile_changed_cb (GSettings *settings, gchar *key, gpointer user_d g_object_set (extractor, "profile", profile, NULL); if (profile == NULL || !sj_extractor_supports_profile(profile)) { - GtkWidget *dialog; - int response; - - dialog = gtk_message_dialog_new (GTK_WINDOW (gtkpod_app), - GTK_DIALOG_MODAL, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - _("The currently selected audio profile is not available on your installation.")); - gtk_dialog_add_button (GTK_DIALOG (dialog), "gtk-quit", GTK_RESPONSE_REJECT); - gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Change Profile"), GTK_RESPONSE_ACCEPT); - response = gtk_dialog_run (GTK_DIALOG (dialog)); - if (response == GTK_RESPONSE_ACCEPT) { - gtk_widget_destroy (dialog); - on_edit_preferences_cb (NULL, NULL); - } else { - /* Can't use gtk_main_quit here, we may be outside the main loop */ - return; - } + gtkpod_warning(_("sjcd plugin: the currently selected audio profile is not available on your installation.")); } if (profile != NULL) diff --git a/po/POTFILES.in b/po/POTFILES.in index 47b1dd8..af2c6ef 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -135,6 +135,7 @@ plugins/sjcd/libjuicer/sj-extractor.c plugins/sjcd/libjuicer/sj-metadata-getter.c plugins/sjcd/libjuicer/sj-metadata-gvfs.c plugins/sjcd/libjuicer/sj-metadata.c +plugins/sjcd/libjuicer/sj-metadata-musicbrainz4.c plugins/sjcd/plugin.c plugins/sjcd/sj-extracting.c plugins/sjcd/sj-genres.c |
From: phantomjinx <pha...@us...> - 2012-06-01 08:17:22
|
The unsigned tag 'gtkpod-2.1.2-beta1' was created. Tagger: phantomjinx <p.g...@ph...> Date: Fri Jun 1 09:17:04 2012 +0100 gtkpod 2.1.2 beta1 Changes since the last tag 'gtkpod-2.1.1': Daniele Forsi (11): Translation fixes Update Italian translation Fix segfault when g_settings schema isn't installed Do not pass arguments to void functions (warnings by clang) Do not include itself Fix visibility of enum GtkPodSortTypes (warnings by clang) Add const keywords (warnings by clang) Trivial: s/lyrics/details/ in license text Use a GtkLabel like all other dialogs Add the border to the spin button strcmp() needs #include <string.h> Matteo F. Vescovi (1): version.sh: update unstable builds separator phantomjinx (34): Update version to reflect for unstable builds Merge branch 'gtk-3.0' Update version to reflect unstable builds Initial addition of sound juicer codebase as sjcd plugin Boiler plate for sjcd plugin Refactor the configure script to group together the module checks Refactor sjcd plugin codebase for use in gtkpod Fix errors to get the sj gui to appear cleanly Get the preference window to appear correctly Clear up and handle threading issues correctly Import tracks once sjcd has ripped them Add sjcd plugin icon for preference dialog Configure script failing without musicbrainz available Update INSTALL file with sjcd plugin details Ignore generated marshalling source files Plugin for attaching use of an external player Modify potfiles for sjcd and external player plugins Remove canberra dependency Small fixes Remove the dependency on libmp4v2 Support for writing mp4 tags using atomic parsley Small fixes and reformatting Build libs directory before plugins Fix language files Fix deprecations in sjcd plugin Tidy up variables for library compilation Fix for not setting artwork correctly Fix deadlock when mult metadata is available in sjcd Fix for double free segfault Fix sjcd preference dialog Improve performance of playlist selection Update and fix sjcd plugin Update language files ready for release 2.1.2 Updates NEWS and Changelog |
From: phantomjinx <pha...@us...> - 2012-05-09 21:30:40
|
commit acb4ca013d66069b53e4bac86c52e2d5480417e7 Author: phantomjinx <p.g...@ph...> Date: Wed May 9 22:29:04 2012 +0100 Improve performance of playlist selection * For playlists / ipods with many tracks, playlist selection can be very slow. Turns out this is due to excessive track display signals being fired while tracks are added. * Use gtk_list_store_insert_with_values since this triggers fewer signals than the gtk_list_store_append/gtk_list_store_set couplet * Turn off sorting then turn back on afterwards since sorting makes adding very slow! plugins/track_display/display_tracks.c | 15 ++++++++++++++- 1 files changed, 14 insertions(+), 1 deletions(-) --- diff --git a/plugins/track_display/display_tracks.c b/plugins/track_display/display_tracks.c index da57139..f98f723 100644 --- a/plugins/track_display/display_tracks.c +++ b/plugins/track_display/display_tracks.c @@ -2376,15 +2376,28 @@ gboolean tm_add_filelist(gchar *data, GtkTreePath *path, GtkTreeViewDropPosition void track_display_set_tracks_cb(GtkPodApp *app, gpointer tks, gpointer data) { GList *tracks = tks; + GtkTreeModel *model = NULL; + tm_remove_all_tracks(); + // Unsort the track view to improve performance + model = gtk_tree_view_get_model(track_treeview); + gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (model), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING); + while (tracks != NULL) { /* add all tracks to model */ Track *track = tracks->data; - tm_add_track_to_track_model(track, NULL); + gtk_list_store_insert_with_values (get_model_as_store(model), NULL, -1, READOUT_COL, track, -1); tracks = tracks->next; } + if (model) { + int column = prefs_get_int("tm_sortcol"); + int order = prefs_get_int("tm_sort"); + if (order != SORT_NONE) { + gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (model), column, order); + } + } } void track_display_set_playlist_cb(GtkPodApp *app, gpointer pl, gpointer data) { |
From: phantomjinx <pha...@us...> - 2012-05-04 20:44:05
|
commit 7982c5554f78dde47fd006afbeff659201d6db3d Author: Matěj Laitl <ma...@la...> Date: Sat Mar 31 14:11:18 2012 +0200 Update .gitignore .gitignore | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) --- diff --git a/.gitignore b/.gitignore index bb5a3b2..74464ed 100644 --- a/.gitignore +++ b/.gitignore @@ -103,6 +103,7 @@ bindings/mono/libgpod-sharp/libgpod-sharp.pidb # /tests/ /tests/get-timezone /tests/test-checksum +/tests/test-cp /tests/test-firewire-id /tests/test-init-ipod /tests/test-ipod-device @@ -116,6 +117,7 @@ bindings/mono/libgpod-sharp/libgpod-sharp.pidb # /tools/ /tools/90-libgpod.rules +/tools/iphone-set-info /tools/ipod-read-sysinfo-extended /tools/ipod-set-info /tools/ipod-time-sync |
From: phantomjinx <pha...@us...> - 2012-05-04 20:43:58
|
commit dfde73caacb70185c77f095d20e467dab125f8ac Author: Matěj Laitl <ma...@la...> Date: Sat Mar 31 14:11:17 2012 +0200 Accept also M4A, m4a filetype description for MPEG4 audio files ...in itdb_track_set_defaults(). convert_filetype() already has it. src/itdb_track.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) --- diff --git a/src/itdb_track.c b/src/itdb_track.c index 52a9fd4..9794631 100644 --- a/src/itdb_track.c +++ b/src/itdb_track.c @@ -67,7 +67,7 @@ static gboolean haystack (gchar *filetype, gchar **desclist) static void itdb_track_set_defaults (Itdb_Track *tr) { gchar *mp3_desc[] = {"MPEG", "MP3", "mpeg", "mp3", NULL}; - gchar *mp4_desc[] = {"AAC", "MP4", "aac", "mp4", NULL}; + gchar *mp4_desc[] = {"AAC", "MP4", "M4A", "aac", "mp4", "m4a", NULL}; gchar *audible_subdesc[] = {"Audible", "audible", "Book", "book", NULL}; gchar *wav_desc[] = {"WAV", "wav", NULL}; gchar *m4v_desc[] = {"M4V", "MP4", "MP4V", "m4v", "mp4", "mp4v", NULL}; |