Update of /cvsroot/gtkpod/gtkpod/src
In directory sc8-pr-cvs2.sourceforge.net:/tmp/cvs-serv23058/src
Modified Files:
Tag: threaded_conversion_branch
file_convert.c file_itunesdb.c
Log Message:
* gtkpod.glade
src/file_convert.c
src/file_itunesdb.c: Adapted export progress dialog and
moved layout to gtkpod.glade
Index: file_convert.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/file_convert.c,v
retrieving revision 1.5.2.1
retrieving revision 1.5.2.2
diff -u -d -r1.5.2.1 -r1.5.2.2
--- file_convert.c 19 Apr 2007 14:46:07 -0000 1.5.2.1
+++ file_convert.c 20 Apr 2007 17:08:36 -0000 1.5.2.2
@@ -655,6 +655,12 @@
static gpointer conversion_prune_dir (gpointer data);
static void conversion_convtrack_free (ConvTrack *ctr);
static gchar *conversion_get_fname_extension (Conversion *conv, ConvTrack
*ctr);
+static gboolean conversion_setup_cachedir (Conversion *conv);
+static gboolean conversion_add_track (Conversion *conv, Track *track);
+static void conversion_itdb_first (Conversion *conv, iTunesDB *itdb);
+static void conversion_cancel_itdb (Conversion *conv, iTunesDB *itdb);
+static void conversion_cancel_track (Conversion *conv, Track *track);
+static Track *conversion_timed_wait (Conversion *conv, iTunesDB *itdb, gint
ms);
static const gchar *FILE_CONVERT_CACHEDIR = "file_convert_cachedir";
static const gchar *FILE_CONVERT_MAXDIRSIZE = "file_convert_maxdirsize";
@@ -676,6 +682,8 @@
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 */
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 */
@@ -722,6 +730,110 @@
static Conversion *conversion;
+/* Set up conversion infrastructure. Must only be called once. */
+void file_convert_init ()
+{
+ GThread *thread;
+ g_return_if_fail (conversion==NULL);
+
+ conversion = g_new0 (Conversion, 1);
+ conversion->max_threads_num = 2; /* FIXME */
+ conversion->max_dirsize = 1024 * 1024 * prefs_get_int
(FILE_CONVERT_MAXDIRSIZE);
+ if (conversion->max_dirsize == 0)
+ { /* set default of 4 GB */
+ conversion->max_dirsize = (gint64)4 * 1024 * 1024 * 1024;
+ prefs_set_int (FILE_CONVERT_MAXDIRSIZE,
+ conversion->max_dirsize / 1024 / 1024);
+ }
+ conversion->dirsize = CONV_DIRSIZE_INVALID;
+ conversion->mutex = g_mutex_new ();
+ conversion->finished_cond = g_cond_new ();
+ conversion->dirsize_cond = g_cond_new ();
+ conversion->prune_cond = g_cond_new ();
+ conversion_setup_cachedir (conversion);
+
+ if (!prefs_get_string_value (FILE_CONVERT_TEMPLATE, NULL))
+ {
+ prefs_set_string (FILE_CONVERT_TEMPLATE, "%A/%t_%T");
+ }
+
+ conversion->timeout_id = g_timeout_add (100, /* every 100 ms */
+ conversion_scheduler,
+ conversion);
+
+ /* Prune dir of unused files if size is too big, calculate and set
+ the size of the directory. Do all that in the background. */
+ thread = g_thread_create_full (conversion_prune_dir,
+ conversion, /* user data */
+ 0, /* stack size */
+ FALSE, /* joinable */
+ TRUE, /* bound */
+ G_THREAD_PRIORITY_NORMAL,
+ NULL); /* error */
+}
+
+
+/* Shut down conversion infrastructure */
+void file_convert_shutdown ()
+{
+ g_return_if_fail (conversion);
+
+ /* nothing to do so far */
+
+ /* in other words: not sure how we can shut this down... */
+}
+
+
+/* Add @track to the list of tracks to be converted if conversion is
+ * necessary.
+ *
+ * Return value: FALSE if an error occured, TRUE otherwise
+ */
+gboolean file_convert_add_track (Track *track)
+{
+ return conversion_add_track (conversion, track);
+}
+
+
+/* Reorder the scheduled list so that tracks in @itdb are converted first */
+void file_convert_itdb_first (iTunesDB *itdb)
+{
+ conversion_itdb_first (conversion, itdb);
+}
+
+
+/* Cancel conversion for all tracks of @itdb */
+void file_convert_cancel_itdb (iTunesDB *itdb)
+{
+ conversion_cancel_itdb (conversion, itdb);
+}
+
+
+/* Cancel conversion for @tracks */
+void file_convert_cancel_track (Track *track)
+{
+ conversion_cancel_track (conversion, track);
+}
+
+/* Wait at most @ms milliseconds for the next track in @itdb to finish
+ * conversion. If a track has finished conversion return a pointer to
+ * that track, NULL otherwise. Returns immediately if a track in @itdb
+ * is already in the finished list. If @itdb == NULL, wait for track
+ * of any itdb. If @ms is zero, wait indefinitely. */
+Track *file_convert_timed_wait (iTunesDB *itdb, gint ms)
+{
+ return conversion_timed_wait (conversion, itdb, ms);
+}
+
+
+/* ----------------------------------------------------------------
+
+ from here on down only static functions
+
+ ---------------------------------------------------------------- */
+
+
+
/* Reorder the scheduled list so that tracks in @itdb are converted first */
static void conversion_itdb_first (Conversion *conv, iTunesDB *itdb)
{
@@ -958,7 +1070,7 @@
* that track, NULL otherwise. Returns immediately if a track in @itdb
* is already in the finished list. If @itdb == NULL, wait for track
* of any itdb. If @ms is zero, wait indefinitely. */
-Track *conversion_timed_wait (Conversion *conv, iTunesDB *itdb, gint ms)
+static Track *conversion_timed_wait (Conversion *conv, iTunesDB *itdb, gint ms)
{
Track *result = NULL;
@@ -981,6 +1093,11 @@
do
{
+ /* make sure at least one thread is started even if the
+ * dirsize is too large */
+ if (conv->threads_num == 0)
+ conv->conversion_force = TRUE;
+
if (g_cond_timed_wait (conv->finished_cond, conv->mutex, abs_time))
{ /* a track has actually finished conversion! */
result = conversion_timed_wait_sub (conv, itdb);
@@ -1259,102 +1376,6 @@
-/* Set up conversion infrastructure. Must only be called once. */
-void file_convert_init ()
-{
- GThread *thread;
- g_return_if_fail (conversion==NULL);
-
- conversion = g_new0 (Conversion, 1);
- conversion->max_threads_num = 2; /* FIXME */
- conversion->max_dirsize = 1024 * 1024 * prefs_get_int
(FILE_CONVERT_MAXDIRSIZE);
- if (conversion->max_dirsize == 0)
- { /* set default of 4 GB */
- conversion->max_dirsize = (gint64)4 * 1024 * 1024 * 1024;
- prefs_set_int (FILE_CONVERT_MAXDIRSIZE,
- conversion->max_dirsize / 1024 / 1024);
- }
- conversion->dirsize = CONV_DIRSIZE_INVALID;
- conversion->mutex = g_mutex_new ();
- conversion->finished_cond = g_cond_new ();
- conversion->dirsize_cond = g_cond_new ();
- conversion->prune_cond = g_cond_new ();
- conversion_setup_cachedir (conversion);
-
- if (!prefs_get_string_value (FILE_CONVERT_TEMPLATE, NULL))
- {
- prefs_set_string (FILE_CONVERT_TEMPLATE, "%A/%t_%T");
- }
-
- conversion->timeout_id = g_timeout_add (100, /* every 100 ms */
- conversion_scheduler,
- conversion);
-
- /* Prune dir of unused files if size is too big, calculate and set
- the size of the directory. Do all that in the background. */
- thread = g_thread_create_full (conversion_prune_dir,
- conversion, /* user data */
- 0, /* stack size */
- FALSE, /* joinable */
- TRUE, /* bound */
- G_THREAD_PRIORITY_NORMAL,
- NULL); /* error */
-}
-
-
-/* Shut down conversion infrastructure */
-void file_convert_shutdown ()
-{
- g_return_if_fail (conversion);
-
- /* nothing to do so far */
-
- /* in other words: not sure how we can shut this down... */
-}
-
-
-/* Add @track to the list of tracks to be converted if conversion is
- * necessary.
- *
- * Return value: FALSE if an error occured, TRUE otherwise
- */
-gboolean file_convert_add_track (Track *track)
-{
- return conversion_add_track (conversion, track);
-}
-
-
-/* Reorder the scheduled list so that tracks in @itdb are converted first */
-void file_convert_itdb_first (iTunesDB *itdb)
-{
- conversion_itdb_first (conversion, itdb);
-}
-
-
-/* Cancel conversion for all tracks of @itdb */
-void file_convert_cancel_itdb (iTunesDB *itdb)
-{
- conversion_cancel_itdb (conversion, itdb);
-}
-
-
-/* Cancel conversion for @tracks */
-void file_convert_cancel_track (Track *track)
-{
- conversion_cancel_track (conversion, track);
-}
-
-/* Wait at most @ms milliseconds for the next track in @itdb to finish
- * conversion. If a track has finished conversion return a pointer to
- * that track, NULL otherwise. Returns immediately if a track in @itdb
- * is already in the finished list. If @itdb == NULL, wait for track
- * of any itdb. If @ms is zero, wait indefinitely. */
-Track *file_convert_timed_wait (iTunesDB *itdb, gint ms)
-{
- return conversion_timed_wait (conversion, itdb, ms);
-}
-
-
/* called in conversion_scheduler to g_spawn_close_pid() and unref the
io-channel after the conversion has finished/has failed/has been
killed. If output is buffered in the io-channel it's appended to
@@ -1406,10 +1427,11 @@
if (conv->scheduled)
{
if ((conv->threads_num < conv->max_threads_num) &&
- (conv->dirsize <= conv->max_dirsize))
+ ((conv->dirsize <= conv->max_dirsize) || conv->conversion_force))
{
GList *gl;
GThread *thread;
+
thread = g_thread_create_full (conversion_thread,
conv, /* user data */
0, /* stack size */
@@ -1433,6 +1455,9 @@
}
}
+ /* reset the conversion_force flag */
+ conv->conversion_force = FALSE;
+
if (conv->processing)
{
GList *gl;
Index: file_itunesdb.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/file_itunesdb.c,v
retrieving revision 1.117.2.1
retrieving revision 1.117.2.2
diff -u -d -r1.117.2.1 -r1.117.2.2
--- file_itunesdb.c 19 Apr 2007 14:46:07 -0000 1.117.2.1
+++ file_itunesdb.c 20 Apr 2007 17:08:36 -0000 1.117.2.2
@@ -1315,7 +1315,7 @@
td->track && td->track->userdata, NULL);
etr = td->track->userdata;
- fprintf (stderr, "Trying to copy: %s\n", td->filename);
+/* fprintf (stderr, "Trying to copy: %s\n", td->filename);*/
itdb_cp_track_to_ipod (td->track, td->filename, &error);
/* delete old size */
@@ -1377,94 +1377,116 @@
}
static GtkWidget *create_file_dialog (GtkWidget **progress_bar,
+ GtkWidget **text_label,
GtkWidget **text_view,
TransferData *transfer_data)
{
- GtkWidget *dialog, *label, *image, *hbox, *expander, *scrolled_window;
- gint defx = 0, defy = 0;
- gboolean details_expanded;
+ GladeXML *dialog_xml;
+ GtkWidget *dialog, *widget;
+ gint defx, defy;
- /* create the dialog window */
- dialog = gtk_dialog_new_with_buttons (_("Information"),
- GTK_WINDOW (gtkpod_window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_NONE,
- NULL);
+ dialog_xml = glade_xml_new (xml_file, "file_transfer_information_dialog",
NULL);
+ glade_xml_signal_autoconnect (dialog_xml);
- /* emulate gtk_message_dialog_new */
- image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO,
- GTK_ICON_SIZE_DIALOG);
- label = gtk_label_new (
- _("Press button to abort.\nExport can be continued at a later time."));
+ dialog = gtkpod_xml_get_widget (dialog_xml,
"file_transfer_information_dialog");
+ g_return_val_if_fail (dialog, NULL);
- gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
- gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
- gtk_label_set_selectable (GTK_LABEL (label), TRUE);
+ /* show/hide progress bar */
+ widget = gtkpod_xml_get_widget (dialog_xml, "progressbar");
+ if (progress_bar)
+ {
+ *progress_bar = widget;
+ }
+ else
+ {
+ gtk_widget_hide (widget);
+ }
- /* hbox to put the image+label in */
- hbox = gtk_hbox_new (FALSE, 6);
- gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ /* show/hide text label */
+ widget = gtkpod_xml_get_widget (dialog_xml, "textlabel");
+ if (text_label)
+ {
+ *text_label = widget;
+ }
+ else
+ {
+ gtk_widget_hide (widget);
+ }
- /* Create the progress bar */
- if (progress_bar) {
- *progress_bar = gtk_progress_bar_new ();
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
- *progress_bar, FALSE, FALSE, 0);
- }
+ /* show/hide details */
+ widget = gtkpod_xml_get_widget (dialog_xml, "details");
+ if (text_view)
+ {
+ *text_view = gtkpod_xml_get_widget (dialog_xml, "textview");
+ gtk_expander_set_expanded (GTK_EXPANDER (widget),
+ prefs_get_int
("file_dialog_details_expanded"));
+ g_signal_connect (GTK_OBJECT (widget), "notify::expanded",
+ G_CALLBACK (file_dialog_expander_notify),
+ NULL);
+ defx = prefs_get_int ("size_file_dialog_details.x");
+ defy = prefs_get_int ("size_file_dialog_details.y");
+ }
+ else
+ {
+ gtk_widget_hide (widget);
+ defx = prefs_get_int ("size_file_dialog.x");
+ defy = prefs_get_int ("size_file_dialog.y");
+ }
- /* Create details log */
- if (text_view) {
- expander = gtk_expander_new (_("Details..."));
- scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- *text_view = gtk_text_view_new();
- gtk_container_add (GTK_CONTAINER (scrolled_window), *text_view);
- gtk_container_add (GTK_CONTAINER (expander), scrolled_window);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
- expander, TRUE, TRUE, 0);
+ gtk_window_set_default_size(GTK_WINDOW (dialog), defx, defy);
- defx = prefs_get_int ("size_file_dialog_details.x");
- defy = prefs_get_int ("size_file_dialog_details.y");
- details_expanded = prefs_get_int ("file_dialog_details_expanded");
- gtk_expander_set_expanded (GTK_EXPANDER (expander), details_expanded);
-
- g_signal_connect (GTK_OBJECT (expander), "notify::expanded",
- G_CALLBACK (file_dialog_expander_notify),
- NULL);
+ /* Indicate that user wants to abort */
+ widget = gtkpod_xml_get_widget (dialog_xml, "abortbutton");
+ g_signal_connect_swapped (GTK_OBJECT (widget), "clicked",
+ G_CALLBACK (file_dialog_abort),
+ transfer_data);
- }
- else {
- defx = prefs_get_int ("size_file_dialog.x");
- defy = prefs_get_int ("size_file_dialog.y");
- }
+ gtk_widget_show (dialog);
- gtk_window_set_default_size(GTK_WINDOW (dialog), defx, defy);
+ return dialog;
+}
- /* Indicate that user wants to abort */
- g_signal_connect_swapped (GTK_OBJECT (dialog), "response",
- G_CALLBACK (file_dialog_abort),
- transfer_data);
- /* Add the image/label + progress bar to dialog */
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
- hbox, FALSE, FALSE, 0);
-
- gtk_widget_show_all (dialog);
+static gchar *flush_tracks_get_progtext (time_t start, gint n, gint count)
+{
+ gchar *progtext;
- return dialog;
+ if (count == 0)
+ {
+ progtext = g_strdup (_("0% (First Track)"));
+ }
+ else
+ {
+ time_t diff, fullsecs, hrs, mins, secs;
+
+ diff = time(NULL) - start;
+ fullsecs = (diff*n/count)-diff+5;
+ hrs = fullsecs / 3600;
+ mins = (fullsecs % 3600) / 60;
+ secs = ((fullsecs % 60) / 5) * 5;
+ /* don't bounce up too quickly (>10% change only) */
+ /* left = ((mins < left) || (100*mins >= 110*left)) ? mins : left;*/
+ progtext = g_strdup_printf (
+ _("%d%% (%d/%d %d:%02d:%02d left)"),
+ count*100/n, count, n, (gint)hrs, (gint)mins, (gint)secs);
+ }
+
+ return progtext;
}
+
/* Removes all tracks that were marked for deletion from the iPod or
the local harddisk (for itdb->usertype == GP_ITDB_TYPE_LOCAL) */
/* Returns TRUE on success, FALSE if some error occurred and not all
files were removed */
static gboolean delete_files (iTunesDB *itdb)
{
- GtkWidget *dialog, *progress_bar;
+ GtkWidget *dialog, *progress_bar, *textlabel;
gchar *progtext = NULL;
gboolean result = TRUE;
+ gint n, count;
gint w, h;
+ time_t start;
TransferData *transfer_data;
ExtraiTunesDBData *eitdb;
GThread *thread = NULL;
@@ -1488,11 +1510,13 @@
transfer_data = transfer_data_new ();
- dialog = create_file_dialog (&progress_bar, NULL, transfer_data);
- progtext = g_strdup (_("deleting..."));
- gtk_progress_bar_set_text(GTK_PROGRESS_BAR (progress_bar), progtext);
- while (widgets_blocked && gtk_events_pending ()) gtk_main_iteration ();
- g_free (progtext);
+ dialog = create_file_dialog (&progress_bar, &textlabel, NULL, transfer_data);
+
+ gtk_label_set_text (GTK_LABEL (textlabel), _("Status: Deleting File"));
+
+ n = g_list_length (eitdb->pending_deletion);
+ count = 0; /* number of tracks removed */
+ start = time (NULL); /* start time for progress bar */
/* lets clean up those pending deletions */
while (!transfer_data->abort && eitdb->pending_deletion)
@@ -1515,6 +1539,16 @@
if(filename)
{
guint rmres;
+
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR (progress_bar),
+ (gdouble) count/n);
+
+ progtext = flush_tracks_get_progtext (start, n, count);
+
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR (progress_bar),
+ progtext);
+ g_free (progtext);
+
mutex_data = FALSE;
thread = g_thread_create (th_remove, filename, TRUE, NULL);
if (thread)
@@ -1543,13 +1577,15 @@
}
g_free(filename);
}
+ ++count;
itdb_track_free (track);
eitdb->pending_deletion = g_list_delete_link (
eitdb->pending_deletion, eitdb->pending_deletion);
- while (widgets_blocked && gtk_events_pending ())
- gtk_main_iteration ();
}
+ while (widgets_blocked && gtk_events_pending ())
+ gtk_main_iteration ();
+
/* Save size of file dialog */
gtk_window_get_size (GTK_WINDOW(dialog), &w, &h);
prefs_set_int("size_file_dialog.x", w);
@@ -1564,6 +1600,8 @@
+
+
/* Flushes all non-transferred tracks to the iPod filesystem
Returns TRUE on success, FALSE if some error occurred or not all
tracks were written. */
@@ -1573,7 +1611,7 @@
gint count, n, w, h, trackserrnum, tracksleftnum;
gboolean result = TRUE;
TransferData *transfer_data;
- GtkWidget *dialog, *progress_bar;
+ GtkWidget *dialog, *progress_bar, *textlabel;
time_t start;
gchar *progtext = NULL;
ExtraiTunesDBData *eitdb;
@@ -1595,7 +1633,8 @@
/* create the dialog window */
dialog = create_file_dialog (&progress_bar,
- (GtkWidget**)&details_log,
+ &textlabel,
+ NULL,
transfer_data);
transfer_data->abort = FALSE;
@@ -1608,8 +1647,6 @@
do
{
- time_t diff, fullsecs, hrs, mins, secs;
-
trackserrnum = 0;
for (gl=itdb->tracks; gl && !transfer_data->abort; gl=gl->next)
{
@@ -1635,6 +1672,12 @@
file_to_transfer = etr->converted_file;
/* Remove from conversion list */
file_convert_cancel_track (track);
+ /* Verify if file is still present */
+ if (!g_file_test (file_to_transfer, G_FILE_TEST_IS_REGULAR))
+ { /* no -- someone deleted it :-/ convert again */
+ file_convert_add_track (track);
+ file_to_transfer = NULL;
+ }
break;
case FILE_CONVERT_FAILED:
/* Conversion of this track has failed. */
@@ -1677,27 +1720,16 @@
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR (progress_bar),
(gdouble) count/n);
- if (count == 0)
- {
- progtext = g_strdup (_("0% (Copying first track)"));
- }
- else
- {
- diff = time(NULL) - start;
- fullsecs = (diff*n/count)-diff+5;
- hrs = fullsecs / 3600;
- mins = (fullsecs % 3600) / 60;
- secs = ((fullsecs % 60) / 5) * 5;
- /* don't bounce up too quickly (>10% change only) */
- /* left = ((mins < left) || (100*mins >= 110*left)) ?
mins : left;*/
- progtext = g_strdup_printf (
- _("%d%% (%d:%02d:%02d left)"),
- count*100/n, (int)hrs, (int)mins, (int)secs);
- }
+
+ progtext = flush_tracks_get_progtext (start, n, count);
+
gtk_progress_bar_set_text(GTK_PROGRESS_BAR (progress_bar),
progtext);
g_free (progtext);
+ gtk_label_set_text (GTK_LABEL(textlabel),
+ _("Status: Copying track"));
+
while (widgets_blocked && gtk_events_pending ())
gtk_main_iteration ();
@@ -1754,16 +1786,18 @@
tracksleftnum = itdb_tracks_number_nontransferred (itdb);
if (tracksleftnum > trackserrnum)
{ /* waiting for files to finish conversion */
- progtext = g_strdup_printf (
- _("%d%% (Waiting for file conversion to complete)"), count*100/n);
- gtk_progress_bar_set_text(GTK_PROGRESS_BAR (progress_bar),
- progtext);
- g_free (progtext);
-
do
{
+ progtext = flush_tracks_get_progtext (start, n, count);
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR (progress_bar),
progtext);
+ g_free (progtext);
+
+ gtk_label_set_text (GTK_LABEL(textlabel),
+ _("Status: Waiting for conversion to
complete"));
+
while (widgets_blocked && gtk_events_pending ())
gtk_main_iteration ();
+
} while (!transfer_data->abort &&
!file_convert_timed_wait (itdb, 20));
}
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2