[gthumb/ext: 52/79] Execute the gth_file_source_copy operation as a task; Implemented
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb/ext: 52/79] Execute the gth_file_source_copy operation as a task; Implemented
- Date: Sun, 2 Aug 2009 20:30:28 +0000 (UTC)
commit 5b1660bfdaaeb7d2764ef7e0bc6704c33cb3893c
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Jul 18 15:26:57 2009 +0200
Execute the gth_file_source_copy operation as a task; Implemented
"past into folder" command; Show an error dialog if a background
task fails; Added a progress callback to the gth_file_source_copy
function.
extensions/catalogs/gth-file-source-catalogs.c | 38 ++++--
extensions/comments/main.c | 4 +-
extensions/file_manager/Makefile.am | 2 +
extensions/file_manager/actions.c | 79 ++++++------
extensions/file_manager/gth-copy-task.c | 170 ++++++++++++++++++++++++
extensions/file_manager/gth-copy-task.h | 59 ++++++++
gthumb/Makefile.am | 2 +-
gthumb/gio-utils.c | 72 ++++++++--
gthumb/gth-browser.c | 91 +++++++++++--
gthumb/gth-file-source-vfs.c | 75 ++++++++---
gthumb/gth-file-source.c | 43 ++++---
gthumb/gth-file-source.h | 164 ++++++++++++-----------
gthumb/typedefs.h | 26 +++--
13 files changed, 611 insertions(+), 214 deletions(-)
---
diff --git a/extensions/catalogs/gth-file-source-catalogs.c b/extensions/catalogs/gth-file-source-catalogs.c
index 561a010..3119747 100644
--- a/extensions/catalogs/gth-file-source-catalogs.c
+++ b/extensions/catalogs/gth-file-source-catalogs.c
@@ -309,9 +309,10 @@ gth_file_source_catalogs_list (GthFileSource *file_source,
typedef struct {
GthFileSourceVfs *file_source;
- GFile *destination;
+ GthFileData *destination;
GList *file_list;
- ReadyCallback callback;
+ ProgressCallback progress_callback;
+ ReadyCallback ready_callback;
gpointer user_data;
GList *files;
GthCatalog *catalog;
@@ -343,11 +344,11 @@ catalog_save_done_cb (void *buffer,
if (error == NULL)
gth_monitor_folder_changed (gth_main_get_default_monitor (),
- cod->destination,
+ cod->destination->file,
cod->files,
GTH_MONITOR_EVENT_CREATED);
- cod->callback (G_OBJECT (cod->file_source), error, cod->user_data);
+ cod->ready_callback (G_OBJECT (cod->file_source), error, cod->user_data);
copy_op_data_free (cod);
}
@@ -362,7 +363,7 @@ catalog_ready_cb (GObject *catalog,
GFile *gio_file;
if (error != NULL) {
- cod->callback (G_OBJECT (cod->file_source), error, cod->user_data);
+ cod->ready_callback (G_OBJECT (cod->file_source), error, cod->user_data);
copy_op_data_free (cod);
return;
}
@@ -373,7 +374,7 @@ catalog_ready_cb (GObject *catalog,
gth_catalog_insert_file (cod->catalog, -1, (GFile *) scan->data);
cod->buffer = gth_catalog_to_data (cod->catalog, &cod->length);
- gio_file = gth_catalog_file_to_gio_file (cod->destination);
+ gio_file = gth_catalog_file_to_gio_file (cod->destination->file);
g_write_file_async (gio_file,
cod->buffer,
cod->length,
@@ -408,16 +409,17 @@ copy__file_list_info_ready_cb (GList *files,
}
cod->files = g_list_reverse (cod->files);
- gth_catalog_load_from_file (cod->destination, catalog_ready_cb, cod);
+ gth_catalog_load_from_file (cod->destination->file, catalog_ready_cb, cod);
}
static void
-gth_file_source_catalogs_copy (GthFileSource *file_source,
- GFile *destination,
- GList *file_list, /* GFile * list */
- ReadyCallback callback,
- gpointer data)
+gth_file_source_catalogs_copy (GthFileSource *file_source,
+ GthFileData *destination,
+ GList *file_list, /* GFile * list */
+ ProgressCallback progress_callback,
+ ReadyCallback ready_callback,
+ gpointer data)
{
CopyOpData *cod;
@@ -425,9 +427,19 @@ gth_file_source_catalogs_copy (GthFileSource *file_source,
cod->file_source = g_object_ref (file_source);
cod->destination = g_object_ref (destination);
cod->file_list = _g_object_list_ref (file_list);
- cod->callback = callback;
+ cod->progress_callback = progress_callback;
+ cod->ready_callback = ready_callback;
cod->user_data = data;
+ if (cod->progress_callback != NULL) {
+ char *message;
+
+ message = g_strdup_printf (_("Copying files to '%s'"), g_file_info_get_display_name (destination->info));
+ (cod->progress_callback) (G_OBJECT (file_source), message, NULL, TRUE, 0.0, cod->user_data);
+
+ g_free (message);
+ }
+
g_query_info_async (cod->file_list,
G_FILE_ATTRIBUTE_STANDARD_TYPE,
gth_file_source_get_cancellable (file_source),
diff --git a/extensions/comments/main.c b/extensions/comments/main.c
index e910b06..26832dc 100644
--- a/extensions/comments/main.c
+++ b/extensions/comments/main.c
@@ -40,7 +40,7 @@ GthMetadataInfo comments_metadata_info[] = {
{ "comment::note", N_("Comment"), "comment", 1, GTH_METADATA_ALLOW_NOWHERE },
{ "comment::place", N_("Place"), "comment", 2, GTH_METADATA_ALLOW_EVERYWHERE },
{ "comment::time", N_("Date"), "comment", 3, GTH_METADATA_ALLOW_EVERYWHERE },
- { "comment::categories", N_("Categories"), "comment", 4, GTH_METADATA_ALLOW_IN_PROPERTIES_VIEW },
+ { "comment::categories", N_("Tags"), "comment", 4, GTH_METADATA_ALLOW_IN_PROPERTIES_VIEW },
{ "comment::rating", N_("Rating"), "comment", 5, GTH_METADATA_ALLOW_EVERYWHERE },
{ NULL, NULL, NULL, 0, 0 }
};
@@ -100,7 +100,7 @@ gthumb_extension_activate (void)
NULL);
gth_main_register_test ("comment::category",
GTH_TYPE_TEST_CATEGORY,
- "display-name", _("Category"),
+ "display-name", _("Tag"),
NULL);
gth_hook_add_callback ("add-sidecars", 10, G_CALLBACK (comments__add_sidecars_cb), NULL);
}
diff --git a/extensions/file_manager/Makefile.am b/extensions/file_manager/Makefile.am
index 5d4bce8..dc81cec 100644
--- a/extensions/file_manager/Makefile.am
+++ b/extensions/file_manager/Makefile.am
@@ -6,6 +6,8 @@ libfile_manager_la_SOURCES = \
actions.h \
callbacks.c \
callbacks.h \
+ gth-copy-task.c \
+ gth-copy-task.h \
gth-duplicate-task.c \
gth-duplicate-task.h \
main.c
diff --git a/extensions/file_manager/actions.c b/extensions/file_manager/actions.c
index 81bf525..cad0793 100644
--- a/extensions/file_manager/actions.c
+++ b/extensions/file_manager/actions.c
@@ -24,6 +24,7 @@
#include <config.h>
#include <glib/gi18n.h>
#include <gthumb.h>
+#include "gth-copy-task.h"
#include "gth-duplicate-task.h"
@@ -246,7 +247,7 @@ gth_browser_activate_action_edit_copy_files (GtkAction *action,
typedef struct {
GthBrowser *browser;
- GFile *destination;
+ GthFileData *destination;
GthFileSource *file_source;
GList *files;
gboolean cut;
@@ -265,57 +266,30 @@ paste_data_free (PasteData *paste_data)
static void
-paste_done_cb (GObject *object,
- GError *error,
- gpointer user_data)
-{
- PasteData *paste_data = user_data;
- GthBrowser *browser = paste_data->browser;
-
- if (error != NULL) {
- _gtk_error_dialog_from_gerror_show (GTK_WINDOW (browser), _("Could not copy the files"), &error);
- paste_data_free (paste_data);
- return;
- }
-
- if (paste_data->cut) {
- if (! _g_delete_files (paste_data->files, TRUE, &error))
- _gtk_error_dialog_from_gerror_show (GTK_WINDOW (browser), _("Could not delete the files"), &error);
- }
-
- paste_data_free (paste_data);
-}
-
-
-static void
clipboard_received_cb (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
gpointer user_data)
{
- GthBrowser *browser = user_data;
+ PasteData *paste_data = user_data;
+ GthBrowser *browser = paste_data->browser;
char **clipboard_data;
- PasteData *paste_data;
int i;
-
+ GthTask *task;
clipboard_data = g_strsplit_set ((const char *) gtk_selection_data_get_data (selection_data), "\n\r", -1);
if (clipboard_data[0] == NULL) {
g_strfreev (clipboard_data);
+ paste_data_free (paste_data);
return;
}
- paste_data = g_new0 (PasteData, 1);
- paste_data->browser = g_object_ref (browser);
- paste_data->destination = g_object_ref (gth_browser_get_location (browser));
paste_data->cut = strcmp (clipboard_data[0], "cut") == 0;
-
paste_data->files = NULL;
for (i = 1; clipboard_data[i] != NULL; i++)
if (strcmp (clipboard_data[i], "") != 0)
paste_data->files = g_list_prepend (paste_data->files, g_file_new_for_uri (clipboard_data[i]));
paste_data->files = g_list_reverse (paste_data->files);
-
- paste_data->file_source = gth_main_get_file_source (gth_browser_get_location (browser));
+ paste_data->file_source = gth_main_get_file_source (paste_data->destination->file);
if (paste_data->cut && ! gth_file_source_can_cut (paste_data->file_source)) {
GtkWidget *dialog;
@@ -340,11 +314,14 @@ clipboard_received_cb (GtkClipboard *clipboard,
paste_data->cut = FALSE;
}
- gth_file_source_copy (paste_data->file_source,
- paste_data->destination,
- paste_data->files,
- paste_done_cb,
- paste_data);
+ task = gth_copy_task_new (paste_data->file_source,
+ paste_data->destination,
+ paste_data->cut,
+ paste_data->files);
+ gth_browser_exec_task (browser, task, FALSE);
+
+ g_object_unref (task);
+ paste_data_free (paste_data);
}
@@ -352,10 +329,16 @@ void
gth_browser_activate_action_edit_paste (GtkAction *action,
GthBrowser *browser)
{
+ PasteData *paste_data;
+
+ paste_data = g_new0 (PasteData, 1);
+ paste_data->browser = g_object_ref (browser);
+ paste_data->destination = g_object_ref (gth_browser_get_location (browser));
+
gtk_clipboard_request_contents (gtk_widget_get_clipboard (GTK_WIDGET (browser), GDK_SELECTION_CLIPBOARD),
GNOME_COPIED_FILES,
clipboard_received_cb,
- browser);
+ paste_data);
}
@@ -576,7 +559,7 @@ gth_browser_activate_action_folder_copy (GtkAction *action,
file_list = g_list_prepend (NULL, file_data);
_gth_browser_clipboard_copy_or_cut (browser, file_list, FALSE);
- g_list_free (file_list);
+ _g_object_list_unref (file_list);
}
@@ -584,7 +567,23 @@ void
gth_browser_activate_action_folder_paste (GtkAction *action,
GthBrowser *browser)
{
+ GthFileData *file_data;
+ PasteData *paste_data;
+ file_data = gth_folder_tree_get_selected (GTH_FOLDER_TREE (gth_browser_get_folder_tree (browser)));
+ if (file_data == NULL)
+ return;
+
+ paste_data = g_new0 (PasteData, 1);
+ paste_data->browser = g_object_ref (browser);
+ paste_data->destination = gth_file_data_dup (file_data);
+
+ gtk_clipboard_request_contents (gtk_widget_get_clipboard (GTK_WIDGET (browser), GDK_SELECTION_CLIPBOARD),
+ GNOME_COPIED_FILES,
+ clipboard_received_cb,
+ paste_data);
+
+ g_object_unref (file_data);
}
diff --git a/extensions/file_manager/gth-copy-task.c b/extensions/file_manager/gth-copy-task.c
new file mode 100644
index 0000000..61a1251
--- /dev/null
+++ b/extensions/file_manager/gth-copy-task.c
@@ -0,0 +1,170 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "gth-copy-task.h"
+
+
+struct _GthCopyTaskPrivate {
+ GthFileData *destination;
+ GthFileSource *file_source;
+ GList *files;
+ gboolean move;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+gth_copy_task_finalize (GObject *object)
+{
+ GthCopyTask *self;
+
+ self = GTH_COPY_TASK (object);
+
+ _g_object_list_unref (self->priv->files);
+ _g_object_unref (self->priv->file_source);
+ _g_object_unref (self->priv->destination);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+copy_done_cb (GObject *object,
+ GError *error,
+ gpointer user_data)
+{
+ gth_task_completed (GTH_TASK (user_data), error);
+}
+
+
+static void
+copy_progress_cb (GObject *object,
+ const char *description,
+ const char *details,
+ gboolean pulse,
+ double fraction,
+ gpointer user_data)
+{
+ GthCopyTask *self = user_data;
+
+ gth_task_progress (GTH_TASK (self), description, details, pulse, fraction);
+}
+
+
+static void
+gth_copy_task_exec (GthTask *task)
+{
+ GthCopyTask *self;
+
+ g_return_if_fail (GTH_IS_COPY_TASK (task));
+
+ self = GTH_COPY_TASK (task);
+
+ gth_file_source_copy (self->priv->file_source,
+ self->priv->destination,
+ self->priv->files,
+ copy_progress_cb,
+ copy_done_cb,
+ self);
+}
+
+
+static void
+gth_copy_task_cancel (GthTask *task)
+{
+ gth_file_source_cancel (GTH_COPY_TASK (task)->priv->file_source);
+}
+
+
+static void
+gth_copy_task_class_init (GthCopyTaskClass *klass)
+{
+ GObjectClass *object_class;
+ GthTaskClass *task_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GthCopyTaskPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gth_copy_task_finalize;
+
+ task_class = GTH_TASK_CLASS (klass);
+ task_class->exec = gth_copy_task_exec;
+ task_class->cancel = gth_copy_task_cancel;
+}
+
+
+static void
+gth_copy_task_init (GthCopyTask *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_COPY_TASK, GthCopyTaskPrivate);
+}
+
+
+GType
+gth_copy_task_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthCopyTaskClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_copy_task_class_init,
+ NULL,
+ NULL,
+ sizeof (GthCopyTask),
+ 0,
+ (GInstanceInitFunc) gth_copy_task_init
+ };
+
+ type = g_type_register_static (GTH_TYPE_TASK,
+ "GthCopyTask",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+GthTask *
+gth_copy_task_new (GthFileSource *file_source,
+ GthFileData *destination,
+ gboolean move,
+ GList *files)
+{
+ GthCopyTask *self;
+
+ self = GTH_COPY_TASK (g_object_new (GTH_TYPE_COPY_TASK, NULL));
+
+ self->priv->file_source = g_object_ref (file_source);
+ self->priv->destination = g_object_ref (destination);
+ self->priv->move = move;
+ self->priv->files = _g_object_list_ref (files);
+
+ return (GthTask *) self;
+}
diff --git a/extensions/file_manager/gth-copy-task.h b/extensions/file_manager/gth-copy-task.h
new file mode 100644
index 0000000..5836ef1
--- /dev/null
+++ b/extensions/file_manager/gth-copy-task.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_COPY_TASK_H
+#define GTH_COPY_TASK_H
+
+#include <glib.h>
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_COPY_TASK (gth_copy_task_get_type ())
+#define GTH_COPY_TASK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_COPY_TASK, GthCopyTask))
+#define GTH_COPY_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_COPY_TASK, GthCopyTaskClass))
+#define GTH_IS_COPY_TASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_COPY_TASK))
+#define GTH_IS_COPY_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_COPY_TASK))
+#define GTH_COPY_TASK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_COPY_TASK, GthCopyTaskClass))
+
+typedef struct _GthCopyTask GthCopyTask;
+typedef struct _GthCopyTaskClass GthCopyTaskClass;
+typedef struct _GthCopyTaskPrivate GthCopyTaskPrivate;
+
+struct _GthCopyTask {
+ GthTask __parent;
+ GthCopyTaskPrivate *priv;
+};
+
+struct _GthCopyTaskClass {
+ GthTaskClass __parent;
+};
+
+GType gth_copy_task_get_type (void);
+GthTask * gth_copy_task_new (GthFileSource *file_source,
+ GthFileData *destination,
+ gboolean move,
+ GList *file_list);
+
+G_END_DECLS
+
+#endif /* GTH_COPY_TASK_H */
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index e884c6d..f415f7f 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -272,7 +272,7 @@ gth-marshal.h: gth-marshal.list $(GLIB_GENMARSHAL)
gth-marshal.c: gth-marshal.h gth-marshal.list $(GLIB_GENMARSHAL)
echo "#include \"gth-marshal.h\"" > $@ \
- && $(GLIB_GENMARSHAL) $(srcdir)/gth-marshal.list --body --prefix=gth_marshal >> $@
+ && $(GLIB_GENMARSHAL) $(srcdir)/gth-marshal.list --body --prefix=gth_marshal >> $@
gthumb.h: make-header.sh gthumb.h.template Makefile.am
$(srcdir)/make-header.sh $(srcdir)/gthumb.h.template $(PUBLIC_HEADER_FILES) > xgen-$(@F) \
diff --git a/gthumb/gio-utils.c b/gthumb/gio-utils.c
index 71cf240..a2998b7 100644
--- a/gthumb/gio-utils.c
+++ b/gthumb/gio-utils.c
@@ -1218,12 +1218,11 @@ g_directory_copy_done (gpointer user_data)
{
DirectoryCopyData *dcd = user_data;
- g_source_remove (dcd->source_id);
+ if (dcd->source_id != 0)
+ g_source_remove (dcd->source_id);
if (dcd->callback)
dcd->callback (dcd->error, dcd->user_data);
- if (dcd->error != NULL)
- g_clear_error (&(dcd->error));
directory_copy_data_free (dcd);
return FALSE;
@@ -1250,7 +1249,6 @@ get_destination_for_file (DirectoryCopyData *dcd,
destination_file = _g_file_append_path (dcd->destination, path);
g_free (path);
- g_free (partial_uri);
g_free (source_uri);
g_free (uri);
@@ -1279,7 +1277,7 @@ g_directory_copy_next_child (gpointer user_data)
static void
g_directory_copy_child_done_cb (GObject *source_object,
GAsyncResult *result,
- gpointer user_data)
+ gpointer user_data)
{
DirectoryCopyData *dcd = user_data;
@@ -1457,6 +1455,52 @@ g_directory_copy_start_dir (GFile *directory,
}
+static void
+g_directory_copy_qdestination_info_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ DirectoryCopyData *dcd = user_data;
+ GFileInfo *info;
+
+ info = g_file_query_info_finish (G_FILE (source_object), result, &dcd->error);
+ if (info == NULL) {
+ if (! g_error_matches (dcd->error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+ g_directory_copy_done (dcd);
+ return;
+ }
+ }
+
+ g_clear_error (&dcd->error);
+
+ if ((info != NULL) && (g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY)) {
+ dcd->error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY, "");
+ g_directory_copy_done (dcd);
+ return;
+ }
+
+ if (! g_file_make_directory (dcd->destination,
+ dcd->cancellable,
+ &dcd->error))
+ {
+ g_directory_copy_done (dcd);
+ return;
+ }
+
+ g_clear_error (&dcd->error);
+
+ g_directory_foreach_child (dcd->source,
+ TRUE,
+ TRUE,
+ "standard::name,standard::type",
+ dcd->cancellable,
+ g_directory_copy_start_dir,
+ g_directory_copy_for_each_file,
+ g_directory_copy_list_ready,
+ dcd);
+}
+
+
void
g_directory_copy_async (GFile *source,
GFile *destination,
@@ -1475,21 +1519,19 @@ g_directory_copy_async (GFile *source,
dcd->destination = g_file_dup (destination);
dcd->flags = flags;
dcd->io_priority = io_priority;
- dcd->cancellable = cancellable;
+ dcd->cancellable = g_object_ref (cancellable);
dcd->progress_callback = progress_callback;
dcd->progress_callback_data = progress_callback_data;
dcd->callback = callback;
dcd->user_data = user_data;
- g_directory_foreach_child (dcd->source,
- TRUE,
- TRUE,
- "standard::name,standard::type",
- dcd->cancellable,
- g_directory_copy_start_dir,
- g_directory_copy_for_each_file,
- g_directory_copy_list_ready,
- dcd);
+ g_file_query_info_async (dcd->destination,
+ "standard::name,standard::type",
+ 0,
+ G_PRIORITY_DEFAULT,
+ dcd->cancellable,
+ g_directory_copy_qdestination_info_ready_cb,
+ dcd);
}
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 630a1c8..afd03a5 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -144,6 +144,7 @@ struct _GthBrowserPrivateData {
GthTask *task;
gulong task_completed;
gulong task_progress;
+ GList *background_tasks;
GList *load_data_queue;
guint load_file_timeout;
char *list_attributes;
@@ -1654,6 +1655,9 @@ _gth_browser_close (GthWindow *window)
{
GthBrowser *browser = (GthBrowser *) window;
+ if (browser->priv->background_tasks != NULL)
+ return;
+
if (gth_browser_get_file_modified (browser))
_gth_browser_ask_whether_to_save (browser,
close__file_saved_cb,
@@ -3312,10 +3316,67 @@ gth_browser_reload (GthBrowser *browser)
}
+typedef struct {
+ GthBrowser *browser;
+ GthTask *task;
+ gulong completed_event;
+} TaskData;
+
+
+static void
+task_data_free (TaskData *task_data)
+{
+ g_object_unref (task_data->task);
+ g_object_unref (task_data->browser);
+ g_free (task_data);
+}
+
+
+static void
+background_task_completed_cb (GthTask *task,
+ GError *error,
+ gpointer user_data)
+{
+ TaskData *task_data = user_data;
+ GthBrowser *browser = task_data->browser;
+
+ browser->priv->background_tasks = g_list_remove (browser->priv->background_tasks, task_data);
+ task_data_free (task_data);
+
+ if (browser->priv->closing)
+ return;
+
+ if (error == NULL)
+ return;
+
+ if (! g_error_matches (error, GTH_TASK_ERROR, GTH_TASK_ERROR_CANCELLED))
+ _gtk_error_dialog_from_gerror_show (GTK_WINDOW (browser), _("Could not perform the operation"), &error);
+ else
+ g_error_free (error);
+}
+
+
+static TaskData *
+task_data_new (GthBrowser *browser,
+ GthTask *task)
+{
+ TaskData *task_data;
+
+ task_data = g_new0 (TaskData, 1);
+ task_data->browser = g_object_ref (browser);
+ task_data->task = g_object_ref (task);
+ task_data->completed_event = g_signal_connect (task_data->task,
+ "completed",
+ G_CALLBACK (background_task_completed_cb),
+ task_data);
+ return task_data;
+}
+
+
static void
-task_completed_cb (GthTask *task,
- GError *error,
- GthBrowser *browser)
+foreground_task_completed_cb (GthTask *task,
+ GError *error,
+ GthBrowser *browser)
{
browser->priv->activity_ref--;
@@ -3327,7 +3388,7 @@ task_completed_cb (GthTask *task,
gth_browser_update_sensitivity (browser);
if (error != NULL) {
if (! g_error_matches (error, GTH_TASK_ERROR, GTH_TASK_ERROR_CANCELLED))
- _gtk_error_dialog_from_gerror_show (GTK_WINDOW (browser), _("Could not perfom the operation"), &error);
+ _gtk_error_dialog_from_gerror_show (GTK_WINDOW (browser), _("Could not perform the operation"), &error);
else
g_error_free (error);
}
@@ -3342,12 +3403,12 @@ task_completed_cb (GthTask *task,
static void
-task_progress_cb (GthTask *task,
- const char *description,
- const char *details,
- gboolean pulse,
- double fraction,
- GthBrowser *browser)
+foreground_task_progress_cb (GthTask *task,
+ const char *description,
+ const char *details,
+ gboolean pulse,
+ double fraction,
+ GthBrowser *browser)
{
gth_statusbar_set_progress (GTH_STATUSBAR (browser->priv->statusbar), description, pulse, fraction);
}
@@ -3361,11 +3422,17 @@ gth_browser_exec_task (GthBrowser *browser,
g_return_if_fail (task != NULL);
if (! foreground) {
+ TaskData *task_data;
+
+ task_data = task_data_new (browser, task);
+ browser->priv->background_tasks = g_list_prepend (browser->priv->background_tasks, task_data);
+
if (browser->priv->progress_dialog == NULL) {
browser->priv->progress_dialog = gth_progress_dialog_new (GTK_WINDOW (browser));
g_object_add_weak_pointer (G_OBJECT (browser->priv->progress_dialog), (gpointer*) &(browser->priv->progress_dialog));
}
gth_progress_dialog_add_task (GTH_PROGRESS_DIALOG (browser->priv->progress_dialog), task);
+
return;
}
@@ -3377,11 +3444,11 @@ gth_browser_exec_task (GthBrowser *browser,
browser->priv->task = g_object_ref (task);
browser->priv->task_completed = g_signal_connect (task,
"completed",
- G_CALLBACK (task_completed_cb),
+ G_CALLBACK (foreground_task_completed_cb),
browser);
browser->priv->task_progress = g_signal_connect (task,
"progress",
- G_CALLBACK (task_progress_cb),
+ G_CALLBACK (foreground_task_progress_cb),
browser);
browser->priv->activity_ref++;
gth_browser_update_sensitivity (browser);
diff --git a/gthumb/gth-file-source-vfs.c b/gthumb/gth-file-source-vfs.c
index 898968b..626cced 100644
--- a/gthumb/gth-file-source-vfs.c
+++ b/gthumb/gth-file-source-vfs.c
@@ -240,13 +240,15 @@ gth_file_source_vfs_list (GthFileSource *file_source,
typedef struct {
GthFileSourceVfs *file_source;
- GFile *destination;
+ GthFileData *destination;
GList *file_list;
- ReadyCallback callback;
+ ProgressCallback progress_callback;
+ ReadyCallback ready_callback;
gpointer user_data;
GList *files;
GList *dirs;
GList *current_dir;
+ char *message;
} CopyOpData;
@@ -258,6 +260,7 @@ copy_op_data_free (CopyOpData *cod)
_g_object_list_unref (cod->file_list);
_g_object_list_unref (cod->files);
_g_object_list_unref (cod->dirs);
+ g_free (cod->message);
g_free (cod);
}
@@ -268,7 +271,7 @@ copy__copy_files_done (GError *error,
{
CopyOpData *cod = user_data;
- cod->callback (G_OBJECT (cod->file_source), error, cod->user_data);
+ cod->ready_callback (G_OBJECT (cod->file_source), error, cod->user_data);
copy_op_data_free (cod);
}
@@ -285,7 +288,7 @@ copy__copy_files (CopyOpData *cod)
char *source_basename;
source_basename = g_file_get_basename (source);
- destinations = g_list_prepend (destinations, g_file_get_child (cod->destination, source_basename));
+ destinations = g_list_prepend (destinations, g_file_get_child (cod->destination->file, source_basename));
g_free (source_basename);
}
@@ -314,7 +317,7 @@ copy__copy_current_dir_done (GError *error,
CopyOpData *cod = user_data;
if (error != NULL) {
- cod->callback (G_OBJECT (cod->file_source), error, cod->user_data);
+ cod->ready_callback (G_OBJECT (cod->file_source), error, cod->user_data);
copy_op_data_free (cod);
return;
}
@@ -325,28 +328,52 @@ copy__copy_current_dir_done (GError *error,
static void
+copy__copy_current_dir_progress (goffset current_file,
+ goffset total_files,
+ GFile *source,
+ GFile *destination,
+ goffset current_num_bytes,
+ goffset total_num_bytes,
+ gpointer user_data)
+{
+ CopyOpData *cod = user_data;
+ GthFileData *source_file_data;
+ char *details;
+
+ if (cod->progress_callback == NULL)
+ return;
+
+ source_file_data = (GthFileData *) cod->current_dir->data;
+ details = g_strdup_printf (_("Copying files from '%s'"), g_file_info_get_display_name (source_file_data->info));
+ (cod->progress_callback) (G_OBJECT (cod->file_source), cod->message, details, FALSE, ((double) current_num_bytes) / total_num_bytes, cod->user_data);
+
+ g_free (details);
+}
+
+
+static void
copy__copy_current_dir (CopyOpData *cod)
{
- GFile *source;
- char *source_basename;
- GFile *destination;
+ GthFileData *source;
+ char *source_basename;
+ GFile *destination;
if (cod->current_dir == NULL) {
copy__copy_files (cod);
return;
}
- source = (GFile *) cod->current_dir->data;
- source_basename = g_file_get_basename (source);
- destination = g_file_get_child (cod->destination, source_basename);
+ source = (GthFileData *) cod->current_dir->data;
+ source_basename = g_file_get_basename (source->file);
+ destination = g_file_get_child (cod->destination->file, source_basename);
- g_directory_copy_async (source,
+ g_directory_copy_async (source->file,
destination,
G_FILE_COPY_NONE,
G_PRIORITY_DEFAULT,
gth_file_source_get_cancellable (GTH_FILE_SOURCE (cod->file_source)),
- NULL,
- NULL,
+ copy__copy_current_dir_progress,
+ cod,
copy__copy_current_dir_done,
cod);
@@ -368,7 +395,7 @@ copy__file_list_info_ready_cb (GList *files,
switch (g_file_info_get_file_type (file_data->info)) {
case G_FILE_TYPE_DIRECTORY:
- cod->dirs = g_list_prepend (cod->dirs, g_object_ref (file_data->file));
+ cod->dirs = g_list_prepend (cod->dirs, g_object_ref (file_data));
break;
case G_FILE_TYPE_REGULAR:
case G_FILE_TYPE_SYMBOLIC_LINK:
@@ -387,11 +414,12 @@ copy__file_list_info_ready_cb (GList *files,
static void
-gth_file_source_vfs_copy (GthFileSource *file_source,
- GFile *destination,
- GList *file_list, /* GFile * list */
- ReadyCallback callback,
- gpointer data)
+gth_file_source_vfs_copy (GthFileSource *file_source,
+ GthFileData *destination,
+ GList *file_list, /* GFile * list */
+ ProgressCallback progress_callback,
+ ReadyCallback ready_callback,
+ gpointer data)
{
CopyOpData *cod;
@@ -399,8 +427,13 @@ gth_file_source_vfs_copy (GthFileSource *file_source,
cod->file_source = g_object_ref (file_source);
cod->destination = g_object_ref (destination);
cod->file_list = _g_object_list_ref (file_list);
- cod->callback = callback;
+ cod->progress_callback = progress_callback;
+ cod->ready_callback = ready_callback;
cod->user_data = data;
+ cod->message = g_strdup_printf (_("Copying files to '%s'"), g_file_info_get_display_name (destination->info));
+
+ if (cod->progress_callback != NULL)
+ (cod->progress_callback) (G_OBJECT (file_source), cod->message, _("Getting files information"), TRUE, 0.0, cod->user_data);
g_query_info_async (cod->file_list,
G_FILE_ATTRIBUTE_STANDARD_TYPE,
diff --git a/gthumb/gth-file-source.c b/gthumb/gth-file-source.c
index 79be24d..92bcc59 100644
--- a/gthumb/gth-file-source.c
+++ b/gthumb/gth-file-source.c
@@ -79,10 +79,11 @@ typedef struct {
typedef struct {
- GFile *destination;
- GList *file_list;
- ReadyCallback callback;
- gpointer data;
+ GthFileData *destination;
+ GList *file_list;
+ ProgressCallback progress_callback;
+ ReadyCallback ready_callback;
+ gpointer data;
} CopyData;
@@ -186,20 +187,22 @@ gth_file_source_queue_rename (GthFileSource *file_source,
static void
-gth_file_source_queue_copy (GthFileSource *file_source,
- GFile *destination,
- GList *file_list,
- ReadyCallback callback,
- gpointer data)
+gth_file_source_queue_copy (GthFileSource *file_source,
+ GthFileData *destination,
+ GList *file_list,
+ ProgressCallback progress_callback,
+ ReadyCallback ready_callback,
+ gpointer data)
{
FileSourceAsyncOp *async_op;
async_op = g_new0 (FileSourceAsyncOp, 1);
async_op->file_source = file_source;
async_op->op = FILE_SOURCE_OP_COPY;
- async_op->data.copy.destination = g_file_dup (destination);
+ async_op->data.copy.destination = gth_file_data_dup (destination);
async_op->data.copy.file_list = _g_file_list_dup (file_list);
- async_op->data.copy.callback = callback;
+ async_op->data.copy.progress_callback = progress_callback;
+ async_op->data.copy.ready_callback = ready_callback;
async_op->data.copy.data = data;
file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
@@ -245,7 +248,8 @@ gth_file_source_exec_next_in_queue (GthFileSource *file_source)
gth_file_source_copy (file_source,
async_op->data.copy.destination,
async_op->data.copy.file_list,
- async_op->data.copy.callback,
+ async_op->data.copy.progress_callback,
+ async_op->data.copy.ready_callback,
async_op->data.copy.data);
break;
}
@@ -685,17 +689,18 @@ gth_file_source_rename (GthFileSource *file_source,
void
-gth_file_source_copy (GthFileSource *file_source,
- GFile *destination,
- GList *file_list, /* GFile * list */
- ReadyCallback callback,
- gpointer data)
+gth_file_source_copy (GthFileSource *file_source,
+ GthFileData *destination,
+ GList *file_list, /* GFile * list */
+ ProgressCallback progress_callback,
+ ReadyCallback ready_callback,
+ gpointer data)
{
if (gth_file_source_is_active (file_source)) {
- gth_file_source_queue_copy (file_source, destination, file_list, callback, data);
+ gth_file_source_queue_copy (file_source, destination, file_list, progress_callback, ready_callback, data);
return;
}
- GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->copy (file_source, destination, file_list, callback, data);
+ GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->copy (file_source, destination, file_list, progress_callback, ready_callback, data);
}
diff --git a/gthumb/gth-file-source.h b/gthumb/gth-file-source.h
index 3a9d7b1..55cf866 100644
--- a/gthumb/gth-file-source.h
+++ b/gthumb/gth-file-source.h
@@ -65,93 +65,95 @@ struct _GthFileSourceClass
/*< virtual functions >*/
- GList * (*get_entry_points) (GthFileSource *file_source);
- GList * (*get_current_list) (GthFileSource *file_source,
- GFile *file);
- GFile * (*to_gio_file) (GthFileSource *file_source,
- GFile *file);
- GFileInfo * (*get_file_info) (GthFileSource *file_source,
- GFile *file,
- const char *attributes);
- GthFileData *(*get_file_data) (GthFileSource *file_source,
- GFile *file,
- GFileInfo *info);
- void (*list) (GthFileSource *file_source,
- GFile *folder,
- const char *attributes,
- ListReady func,
- gpointer data);
- void (*rename) (GthFileSource *file_source,
- GFile *file,
- GFile *new_file,
- ReadyCallback callback,
- gpointer data);
- void (*copy) (GthFileSource *file_source,
- GFile *destination,
- GList *file_list, /* GFile * list */
- ReadyCallback callback,
- gpointer data);
- gboolean (*can_cut) (GthFileSource *file_source);
- void (*monitor_entry_points) (GthFileSource *file_source);
- void (*monitor_directory) (GthFileSource *file_source,
- GFile *file,
- gboolean activate);
+ GList * (*get_entry_points) (GthFileSource *file_source);
+ GList * (*get_current_list) (GthFileSource *file_source,
+ GFile *file);
+ GFile * (*to_gio_file) (GthFileSource *file_source,
+ GFile *file);
+ GFileInfo * (*get_file_info) (GthFileSource *file_source,
+ GFile *file,
+ const char *attributes);
+ GthFileData *(*get_file_data) (GthFileSource *file_source,
+ GFile *file,
+ GFileInfo *info);
+ void (*list) (GthFileSource *file_source,
+ GFile *folder,
+ const char *attributes,
+ ListReady func,
+ gpointer data);
+ void (*rename) (GthFileSource *file_source,
+ GFile *file,
+ GFile *new_file,
+ ReadyCallback callback,
+ gpointer data);
+ void (*copy) (GthFileSource *file_source,
+ GthFileData *destination,
+ GList *file_list, /* GFile * list */
+ ProgressCallback progress_callback,
+ ReadyCallback callback,
+ gpointer data);
+ gboolean (*can_cut) (GthFileSource *file_source);
+ void (*monitor_entry_points) (GthFileSource *file_source);
+ void (*monitor_directory) (GthFileSource *file_source,
+ GFile *file,
+ gboolean activate);
};
-GType gth_file_source_get_type (void) G_GNUC_CONST;
+GType gth_file_source_get_type (void) G_GNUC_CONST;
-/*< protected >*/
+/*< public >*/
-void gth_file_source_add_scheme (GthFileSource *file_source,
- const char *scheme);
-gboolean gth_file_source_supports_scheme (GthFileSource *file_source,
- const char *uri);
-void gth_file_source_set_active (GthFileSource *file_source,
- gboolean pending);
+GList * gth_file_source_get_entry_points (GthFileSource *file_source); /* GthFileData list */
+GList * gth_file_source_get_current_list (GthFileSource *file_source, /* GFile list */
+ GFile *file);
+GFile * gth_file_source_to_gio_file (GthFileSource *file_source,
+ GFile *file);
+GList * gth_file_source_to_gio_file_list (GthFileSource *file_source,
+ GList *files);
+GFileInfo * gth_file_source_get_file_info (GthFileSource *file_source,
+ GFile *file,
+ const char *attributes);
+GthFileData * gth_file_source_get_file_data (GthFileSource *file_source,
+ GFile *file,
+ GFileInfo *info);
+gboolean gth_file_source_is_active (GthFileSource *file_source);
+void gth_file_source_cancel (GthFileSource *file_source);
+void gth_file_source_list (GthFileSource *file_source,
+ GFile *folder,
+ const char *attributes,
+ ListReady func,
+ gpointer data);
+void gth_file_source_read_attributes (GthFileSource *file_source,
+ GList *files,
+ const char *attributes,
+ ListReady func,
+ gpointer data);
+void gth_file_source_rename (GthFileSource *file_source,
+ GFile *file,
+ GFile *new_file,
+ ReadyCallback ready_cb,
+ gpointer data);
+void gth_file_source_copy (GthFileSource *file_source,
+ GthFileData *destination,
+ GList *file_list, /* GFile list */
+ ProgressCallback progress_callback,
+ ReadyCallback ready_callback,
+ gpointer data);
+gboolean gth_file_source_can_cut (GthFileSource *file_source);
+void gth_file_source_monitor_entry_points (GthFileSource *file_source);
+void gth_file_source_monitor_directory (GthFileSource *file_source,
+ GFile *file,
+ gboolean activate);
-/*< public >*/
+/*< protected >*/
-GList * gth_file_source_get_entry_points (GthFileSource *file_source); /* GthFileData list */
-GList * gth_file_source_get_current_list (GthFileSource *file_source, /* GFile list */
- GFile *file);
-GFile * gth_file_source_to_gio_file (GthFileSource *file_source,
- GFile *file);
-GList * gth_file_source_to_gio_file_list (GthFileSource *file_source,
- GList *files);
-GFileInfo * gth_file_source_get_file_info (GthFileSource *file_source,
- GFile *file,
- const char *attributes);
-GthFileData *gth_file_source_get_file_data (GthFileSource *file_source,
- GFile *file,
- GFileInfo *info);
-gboolean gth_file_source_is_active (GthFileSource *file_source);
-GCancellable *gth_file_source_get_cancellable (GthFileSource *file_source);
-void gth_file_source_cancel (GthFileSource *file_source);
-void gth_file_source_list (GthFileSource *file_source,
- GFile *folder,
- const char *attributes,
- ListReady func,
- gpointer data);
-void gth_file_source_read_attributes (GthFileSource *file_source,
- GList *files,
- const char *attributes,
- ListReady func,
- gpointer data);
-void gth_file_source_rename (GthFileSource *file_source,
- GFile *file,
- GFile *new_file,
- ReadyCallback callback,
- gpointer data);
-void gth_file_source_copy (GthFileSource *file_source,
- GFile *destination,
- GList *file_list, /* GFile list */
- ReadyCallback callback,
- gpointer data);
-gboolean gth_file_source_can_cut (GthFileSource *file_source);
-void gth_file_source_monitor_entry_points (GthFileSource *file_source);
-void gth_file_source_monitor_directory (GthFileSource *file_source,
- GFile *file,
- gboolean activate);
+void gth_file_source_add_scheme (GthFileSource *file_source,
+ const char *scheme);
+gboolean gth_file_source_supports_scheme (GthFileSource *file_source,
+ const char *uri);
+void gth_file_source_set_active (GthFileSource *file_source,
+ gboolean pending);
+GCancellable * gth_file_source_get_cancellable (GthFileSource *file_source);
G_END_DECLS
diff --git a/gthumb/typedefs.h b/gthumb/typedefs.h
index 3f297e7..1ef0975 100644
--- a/gthumb/typedefs.h
+++ b/gthumb/typedefs.h
@@ -37,9 +37,9 @@ G_BEGIN_DECLS
#define RC_REMOTE_CACHE_DIR ".gnome2/gthumb/remote_cache"
*/
-#define BOOKMARKS_FILE "bookmarks.xbel"
-#define FILTERS_FILE "filters.xml"
-#define FILE_CACHE "cache"
+#define BOOKMARKS_FILE "bookmarks.xbel"
+#define FILTERS_FILE "filters.xml"
+#define FILE_CACHE "cache"
typedef enum {
@@ -86,13 +86,19 @@ typedef enum {
} GthTransform;
-typedef void (*ErrorFunc) (gpointer user_data);
-typedef void (*DoneFunc) (gpointer user_data);
-typedef void (*ReadyFunc) (GError *error,
- gpointer user_data);
-typedef void (*ReadyCallback) (GObject *object,
- GError *error,
- gpointer user_data);
+typedef void (*ErrorFunc) (gpointer user_data);
+typedef void (*DoneFunc) (gpointer user_data);
+typedef void (*ReadyFunc) (GError *error,
+ gpointer user_data);
+typedef void (*ReadyCallback) (GObject *object,
+ GError *error,
+ gpointer user_data);
+typedef void (*ProgressCallback) (GObject *object,
+ const char *description,
+ const char *details,
+ gboolean pulse,
+ double fraction,
+ gpointer user_data);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]