[gthumb/ext: 21/79] implemented the paste command
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb/ext: 21/79] implemented the paste command
- Date: Sun, 2 Aug 2009 20:25:39 +0000 (UTC)
commit f9adcaa5fbb00937e910b07d593287a2b6600dd4
Author: Paolo Bacchilega <paobac src gnome org>
Date: Tue Jun 23 23:59:00 2009 +0200
implemented the paste command
extensions/catalogs/callbacks.c | 4 +-
extensions/catalogs/dlg-add-to-catalog.c | 166 +++++++---------
extensions/catalogs/gth-catalog.c | 87 +++++----
extensions/catalogs/gth-catalog.h | 43 ++--
extensions/catalogs/gth-file-source-catalogs.c | 132 ++++++++++++
extensions/file_manager/actions.c | 256 +++++++++++++++++++++++-
extensions/file_manager/actions.h | 2 +-
extensions/file_manager/callbacks.c | 18 +-
extensions/search/gth-search-task.c | 2 +-
gthumb/gio-utils.c | 127 +------------
gthumb/gio-utils.h | 7 +-
gthumb/gth-browser.c | 158 +---------------
gthumb/gth-browser.h | 5 +-
gthumb/gth-file-data.c | 14 +-
gthumb/gth-file-source-vfs.c | 184 +++++++++++++++++
gthumb/gth-file-source.c | 74 +++++++-
gthumb/gth-file-source.h | 12 +
gthumb/gth-thumb-loader.c | 14 +-
18 files changed, 837 insertions(+), 468 deletions(-)
---
diff --git a/extensions/catalogs/callbacks.c b/extensions/catalogs/callbacks.c
index 7591b43..e9d63bc 100644
--- a/extensions/catalogs/callbacks.c
+++ b/extensions/catalogs/callbacks.c
@@ -160,7 +160,7 @@ catalogs__gth_browser_update_sensitivity_cb (GthBrowser *browser)
g_object_set (action, "sensitive", sensitive, NULL);
action = gtk_action_group_get_action (data->actions, "Edit_RemoveFromCatalog");
- sensitive = (n_selected > 0) && GTH_IS_FILE_SOURCE_CATALOGS (gth_browser_get_file_source (browser));
+ sensitive = (n_selected > 0) && GTH_IS_FILE_SOURCE_CATALOGS (gth_browser_get_location_source (browser));
g_object_set (action, "sensitive", sensitive, NULL);
}
@@ -232,7 +232,7 @@ catalogs__gth_browser_load_location_after_cb (GthBrowser *browser,
data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
- if (GTH_IS_FILE_SOURCE_CATALOGS (gth_browser_get_file_source (browser))) {
+ if (GTH_IS_FILE_SOURCE_CATALOGS (gth_browser_get_location_source (browser))) {
if (data->vfs_merge_id == 0) {
GError *error = NULL;
diff --git a/extensions/catalogs/dlg-add-to-catalog.c b/extensions/catalogs/dlg-add-to-catalog.c
index 05e5952..54108eb 100644
--- a/extensions/catalogs/dlg-add-to-catalog.c
+++ b/extensions/catalogs/dlg-add-to-catalog.c
@@ -45,14 +45,12 @@ typedef struct {
static void
-destroy_cb (GtkWidget *widget,
+destroy_cb (GtkWidget *widget,
DialogData *data)
{
g_free (data->buffer);
- if (data->catalog != NULL)
- g_object_unref (data->catalog);
- if (data->gio_file != NULL)
- g_object_unref (data->gio_file);
+ _g_object_unref (data->catalog);
+ _g_object_unref (data->gio_file);
_g_object_list_unref (data->files);
_g_object_unref (data->selected_catalog);
g_object_unref (data->builder);
@@ -66,80 +64,72 @@ get_selected_catalog (DialogData *data)
{
GthFileData *file_data = NULL;
GFile *file;
-
+
file = gth_folder_tree_get_selected_or_parent (GTH_FOLDER_TREE (data->source_tree));
if (file != NULL) {
GthFileSource *file_source;
GFileInfo *info;
-
+
file_source = gth_main_get_file_source (file);
info = gth_file_source_get_file_info (file_source, file);
- if (g_file_info_get_attribute_boolean (info, "gthumb::no-child"))
+ if (g_file_info_get_attribute_boolean (info, "gthumb::no-child"))
file_data = gth_file_data_new (file, info);
-
+
g_object_unref (info);
g_object_unref (file);
}
-
+
return file_data;
}
-static void
+static void
catalog_save_done_cb (void *buffer,
gsize count,
GError *error,
gpointer user_data)
{
DialogData *data = user_data;
-
+
if (error != NULL) {
_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog), _("Could not add the files to the catalog"), &error);
return;
}
-
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("view_destination_checkbutton"))))
+
+ gth_monitor_folder_changed (gth_main_get_default_monitor (),
+ data->selected_catalog->file,
+ data->files,
+ GTH_MONITOR_EVENT_CREATED);
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("view_destination_checkbutton"))))
gth_browser_go_to (data->browser, data->selected_catalog->file);
-
+
gtk_widget_destroy (data->dialog);
}
-static void
-catalog_buffer_ready_cb (void *buffer,
- gsize count,
- GError *error,
- gpointer user_data)
+static void
+catalog_ready_cb (GObject *catalog,
+ GError *error,
+ gpointer user_data)
{
DialogData *data = user_data;
GList *scan;
-
- if (error != NULL) {
- _gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog), _("Could not add the files to the catalog"), &error);
- return;
- }
-
- data->catalog = gth_hook_invoke_get ("gth-catalog-load-from-data", buffer);
- if (data->catalog == NULL) {
- error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED, _("Invalid file format"));
- _gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog), _("Could not add the files to the catalog"), &error);
- return;
- }
-
- gth_catalog_load_from_data (data->catalog, buffer, count, &error);
+
if (error != NULL) {
_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog), _("Could not add the files to the catalog"), &error);
return;
}
+ data->catalog = (GthCatalog *) catalog;
+
for (scan = data->files; scan; scan = scan->next) {
GthFileData *file_to_add = scan->data;
-
gth_catalog_insert_file (data->catalog, -1, file_to_add->file);
}
-
+
data->buffer = gth_catalog_to_data (data->catalog, &data->length);
- g_write_file_async (data->gio_file,
+ g_write_file_async (data->gio_file,
data->buffer,
data->length,
G_PRIORITY_DEFAULT,
@@ -153,21 +143,13 @@ static void
add_button_clicked_cb (GtkWidget *widget,
DialogData *data)
{
- GthFileSource *catalog_source;
-
data->selected_catalog = get_selected_catalog (data);
- if (data->selected_catalog == NULL)
+ if (data->selected_catalog == NULL)
return;
-
- catalog_source = g_object_new (GTH_TYPE_FILE_SOURCE_CATALOGS, NULL);
- data->gio_file = gth_file_source_to_gio_file (catalog_source, data->selected_catalog->file);
- g_load_file_async (data->gio_file,
- G_PRIORITY_DEFAULT,
- NULL,
- catalog_buffer_ready_cb,
- data);
-
- g_object_unref (catalog_source);
+
+ gth_catalog_load_from_file (data->selected_catalog->file,
+ catalog_ready_cb,
+ data);
}
@@ -182,12 +164,12 @@ source_tree_open_cb (GthFolderTree *folder_tree,
static void
source_tree_selection_changed_cb (GtkTreeSelection *treeselection,
- gpointer user_data)
+ gpointer user_data)
{
DialogData *data = user_data;
GthFileData *file_data;
-
- file_data = get_selected_catalog (data);
+
+ file_data = get_selected_catalog (data);
gtk_widget_set_sensitive (GTK_WIDGET (GET_WIDGET ("add_button")), file_data != NULL);
_g_object_unref (file_data);
}
@@ -197,27 +179,27 @@ static GFile *
get_catalog_parent (GFile *selected_parent)
{
GFile *parent = NULL;
-
+
if (selected_parent != NULL) {
GthFileSource *file_source;
GFileInfo *info;
-
+
file_source = gth_main_get_file_source (selected_parent);
info = gth_file_source_get_file_info (file_source, selected_parent);
- if ((g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) &&
+ if ((g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) &&
! g_file_info_get_attribute_boolean (info, "gthumb::no-child"))
- {
+ {
parent = g_file_dup (selected_parent);
}
else
parent = g_file_get_parent (selected_parent);
-
+
g_object_unref (info);
g_object_unref (file_source);
}
else
parent = g_file_new_for_uri ("catalog:///");
-
+
return parent;
}
@@ -232,57 +214,57 @@ new_catalog_button_clicked_cb (GtkWidget *widget,
GFile *gio_parent;
GError *error;
GFile *gio_file;
-
+
selected_parent = gth_folder_tree_get_selected_or_parent (GTH_FOLDER_TREE (data->source_tree));
if (selected_parent != NULL) {
GthFileSource *file_source;
GFileInfo *info;
-
+
file_source = gth_main_get_file_source (selected_parent);
info = gth_file_source_get_file_info (file_source, selected_parent);
if (g_file_info_get_attribute_boolean (info, "gthumb::no-child"))
parent = g_file_get_parent (selected_parent);
else
parent = g_file_dup (selected_parent);
-
+
g_object_unref (info);
g_object_unref (file_source);
}
else
parent = g_file_new_for_uri ("catalog:///");
-
+
file_source = gth_main_get_file_source (parent);
gio_parent = gth_file_source_to_gio_file (file_source, parent);
gio_file = _g_file_create_unique (gio_parent, _("New Catalog"), ".catalog", &error);
if (gio_file != NULL) {
- GFile *file;
+ GFile *file;
GList *list;
GFileInfo *info;
GthFileData *file_data;
GList *file_data_list;
- file = gth_catalog_file_from_gio_file (gio_file, NULL);
+ file = gth_catalog_file_from_gio_file (gio_file, NULL);
info = gth_file_source_get_file_info (file_source, file);
file_data = gth_file_data_new (file, info);
file_data_list = g_list_prepend (NULL, file_data);
gth_folder_tree_add_children (GTH_FOLDER_TREE (data->source_tree), parent, file_data_list);
gth_folder_tree_start_editing (GTH_FOLDER_TREE (data->source_tree), file);
-
- list = g_list_prepend (NULL, g_object_ref (file));
+
+ list = g_list_prepend (NULL, g_object_ref (file));
gth_monitor_folder_changed (gth_main_get_default_monitor (),
parent,
list,
GTH_MONITOR_EVENT_CREATED);
-
- _g_object_list_unref (list);
+
+ _g_object_list_unref (list);
g_list_free (file_data_list);
g_object_unref (file_data);
- g_object_unref (info);
+ g_object_unref (info);
g_object_unref (file);
}
else
_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog), _("Could not create the catalog"), &error);
-
+
g_object_unref (gio_file);
g_object_unref (gio_parent);
g_object_unref (file_source);
@@ -298,7 +280,7 @@ new_library_button_clicked_cb (GtkWidget *widget,
GFile *parent;
GFile *new_library;
GError *error = NULL;
-
+
display_name = _gtk_request_dialog_run (GTK_WINDOW (data->dialog),
GTK_DIALOG_MODAL,
_("Enter the library name: "),
@@ -308,29 +290,29 @@ new_library_button_clicked_cb (GtkWidget *widget,
_("C_reate"));
if (display_name == NULL)
return;
-
+
selected_catalog = gth_folder_tree_get_selected (GTH_FOLDER_TREE (data->source_tree));
- parent = get_catalog_parent (selected_catalog);
+ parent = get_catalog_parent (selected_catalog);
new_library = g_file_get_child_for_display_name (parent, display_name, &error);
-
+
if ((new_library != NULL) && (strchr (display_name, '/') != NULL)) {
error = g_error_new (G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, _("The name \"%s\" is not valid because it contains the character \"/\". " "Please use a different name."), display_name);
g_object_unref (new_library);
new_library = NULL;
}
-
- if (error == NULL) {
+
+ if (error == NULL) {
GFile *gio_file;
-
+
gio_file = gth_file_source_to_gio_file (data->file_source, new_library);
g_file_make_directory (new_library, NULL, &error);
-
+
g_object_unref (gio_file);
}
-
+
if (error != NULL)
_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog), _("Could not create a new library"), &error);
-
+
if (new_library != NULL)
g_object_unref (new_library);
g_object_unref (parent);
@@ -346,25 +328,25 @@ dlg_add_to_catalog (GthBrowser *browser,
DialogData *data;
GFile *base;
GtkTreeSelection *selection;
-
+
data = g_new0 (DialogData, 1);
data->browser = browser;
- data->builder = _gtk_builder_new_from_file ("add-to-catalog.ui", "catalogs");
+ data->builder = _gtk_builder_new_from_file ("add-to-catalog.ui", "catalogs");
data->files = _g_object_list_ref (list);
data->file_source = g_object_new (GTH_TYPE_FILE_SOURCE_CATALOGS, NULL);
-
+
data->dialog = _gtk_builder_get_widget (data->builder, "add_to_catalog_dialog");
-
- base = g_file_new_for_uri ("catalog:///");
+
+ base = g_file_new_for_uri ("catalog:///");
data->source_tree = gth_source_tree_new (base);
g_object_unref (base);
-
+
gtk_widget_show (data->source_tree);
- gtk_container_add (GTK_CONTAINER (GET_WIDGET ("catalog_list_scrolled_window")), data->source_tree);
+ gtk_container_add (GTK_CONTAINER (GET_WIDGET ("catalog_list_scrolled_window")), data->source_tree);
- gtk_label_set_mnemonic_widget (GTK_LABEL (GET_WIDGET ("catalogs_label")), data->source_tree);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (GET_WIDGET ("catalogs_label")), data->source_tree);
gtk_widget_set_sensitive (GTK_WIDGET (GET_WIDGET ("add_button")), FALSE);
-
+
/* Set the signals handlers. */
g_signal_connect (G_OBJECT (data->dialog),
@@ -391,13 +373,13 @@ dlg_add_to_catalog (GthBrowser *browser,
"clicked",
G_CALLBACK (new_library_button_clicked_cb),
data);
-
+
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->source_tree));
g_signal_connect (selection,
"changed",
G_CALLBACK (source_tree_selection_changed_cb),
data);
-
+
/* run dialog. */
gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (browser));
diff --git a/extensions/catalogs/gth-catalog.c b/extensions/catalogs/gth-catalog.c
index 8db743f..1d78b1a 100644
--- a/extensions/catalogs/gth-catalog.c
+++ b/extensions/catalogs/gth-catalog.c
@@ -411,10 +411,10 @@ catalog_file_info_ready_cb (GObject *source_object,
static void
-catalog_buffer_ready_cb (void *buffer,
- gsize count,
- GError *error,
- gpointer user_data)
+list__catalog_buffer_ready_cb (void *buffer,
+ gsize count,
+ GError *error,
+ gpointer user_data)
{
ListData *list_data = user_data;
GthCatalog *catalog = list_data->catalog;
@@ -473,7 +473,7 @@ gth_catalog_list_async (GthCatalog *catalog,
g_load_file_async (catalog->priv->file,
G_PRIORITY_DEFAULT,
catalog->priv->cancellable,
- catalog_buffer_ready_cb,
+ list__catalog_buffer_ready_cb,
list_data);
}
@@ -671,43 +671,54 @@ gth_catalog_get_display_name (GFile *file)
}
-#if 0
-GthCatalogType
-gth_catalog_data_get_type (const void *buffer,
- gsize count)
-{
- GthCatalogType type = GTH_CATALOG_TYPE_INVALID;
- char *text_buffer;
+/* -- gth_catalog_load_from_file --*/
- text_buffer = (char*) buffer;
- if (strncmp (text_buffer, "<?xml ", 6) == 0) {
- DomDocument *doc;
- GError *error = NULL;
- DomElement *root;
-
- doc = dom_document_new ();
- if (! dom_document_load (doc, text_buffer, count, &error)) {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- }
- root = DOM_ELEMENT (doc)->first_child;
- if (g_strcmp0 (root->tag_name, "catalog") == 0)
- type = GTH_CATALOG_TYPE_CATALOG;
- else if (g_strcmp0 (root->tag_name, "search") == 0)
- type = GTH_CATALOG_TYPE_SEARCH;
+typedef struct {
+ ReadyCallback ready_func;
+ gpointer user_data;
+} LoadData;
- g_object_unref (doc);
- }
- else {
- /* Old catalog format */
- if (strncmp (text_buffer, "# Search", 8) == 0)
- type = GTH_CATALOG_TYPE_SEARCH;
- else
- type = GTH_CATALOG_TYPE_CATALOG;
+static void
+load__catalog_buffer_ready_cb (void *buffer,
+ gsize count,
+ GError *error,
+ gpointer user_data)
+{
+ LoadData *load_data = user_data;
+ GthCatalog *catalog = NULL;
+
+ if (error == NULL) {
+ catalog = gth_hook_invoke_get ("gth-catalog-load-from-data", buffer);
+ if (catalog != NULL)
+ gth_catalog_load_from_data (catalog, buffer, count, &error);
}
- return type;
+ load_data->ready_func (G_OBJECT (catalog), error, load_data->user_data);
+
+ g_free (load_data);
+}
+
+
+void
+gth_catalog_load_from_file (GFile *file,
+ ReadyCallback ready_func,
+ gpointer user_data)
+{
+ LoadData *load_data;
+ GFile *gio_file;
+
+ load_data = g_new0 (LoadData, 1);
+ load_data->ready_func = ready_func;
+ load_data->user_data = user_data;
+
+ gio_file = gth_catalog_file_to_gio_file (file);
+ g_load_file_async (gio_file,
+ G_PRIORITY_DEFAULT,
+ NULL,
+ load__catalog_buffer_ready_cb,
+ load_data);
+
+ g_object_unref (gio_file);
}
-#endif
diff --git a/extensions/catalogs/gth-catalog.h b/extensions/catalogs/gth-catalog.h
index b8cb2f2..8120579 100644
--- a/extensions/catalogs/gth-catalog.h
+++ b/extensions/catalogs/gth-catalog.h
@@ -19,7 +19,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
*/
-
+
#ifndef GTH_CATALOG_H
#define GTH_CATALOG_H
@@ -54,14 +54,14 @@ struct _GthCatalog
struct _GthCatalogClass
{
GObjectClass __parent_class;
-
+
/*< virtual functions >*/
-
+
void (*load_from_data) (GthCatalog *catalog,
const void *buffer,
gsize count,
- GError **error);
- char * (*to_data) (GthCatalog *catalog,
+ GError **error);
+ char * (*to_data) (GthCatalog *catalog,
gsize *length);
};
@@ -73,14 +73,14 @@ typedef void (*CatalogReadyCallback) (GthCatalog *catalog,
GType gth_catalog_get_type (void) G_GNUC_CONST;
GthCatalog * gth_catalog_new (void);
void gth_catalog_set_file (GthCatalog *catalog,
- GFile *file);
-GFile * gth_catalog_get_file (GthCatalog *catalog);
+ GFile *file);
+GFile * gth_catalog_get_file (GthCatalog *catalog);
void gth_catalog_load_from_data (GthCatalog *catalog,
const void *buffer,
gsize count,
- GError **error);
-char * gth_catalog_to_data (GthCatalog *catalog,
- gsize *length);
+ GError **error);
+char * gth_catalog_to_data (GthCatalog *catalog,
+ gsize *length);
void gth_catalog_set_file_list (GthCatalog *catalog,
GList *file_list);
GList * gth_catalog_get_file_list (GthCatalog *catalog);
@@ -94,18 +94,21 @@ void gth_catalog_list_async (GthCatalog *catalog,
GCancellable *cancellable,
CatalogReadyCallback ready_func,
gpointer user_data);
-void gth_catalog_cancel (GthCatalog *catalog);
+void gth_catalog_cancel (GthCatalog *catalog);
/* utils */
GFile * gth_catalog_get_base (void);
-GFile * gth_catalog_file_to_gio_file (GFile *file);
-GFile * gth_catalog_file_from_gio_file (GFile *file,
- GFile *catalog);
-GFile * gth_catalog_file_from_relative_path (const char *name,
- const char *file_extension);
-char * gth_catalog_get_relative_path (GFile *file);
-GIcon * gth_catalog_get_icon (GFile *file);
-char * gth_catalog_get_display_name (GFile *file);
-
+GFile * gth_catalog_file_to_gio_file (GFile *file);
+GFile * gth_catalog_file_from_gio_file (GFile *file,
+ GFile *catalog);
+GFile * gth_catalog_file_from_relative_path (const char *name,
+ const char *file_extension);
+char * gth_catalog_get_relative_path (GFile *file);
+GIcon * gth_catalog_get_icon (GFile *file);
+char * gth_catalog_get_display_name (GFile *file);
+void gth_catalog_load_from_file (GFile *file,
+ ReadyCallback ready_func,
+ gpointer user_data);
+
#endif /*GTH_CATALOG_H*/
diff --git a/extensions/catalogs/gth-file-source-catalogs.c b/extensions/catalogs/gth-file-source-catalogs.c
index 6c0be92..8e739d0 100644
--- a/extensions/catalogs/gth-file-source-catalogs.c
+++ b/extensions/catalogs/gth-file-source-catalogs.c
@@ -379,6 +379,137 @@ gth_file_source_catalogs_read_attributes (GthFileSource *file_source,
}
+/* -- gth_file_source_vfs_copy -- */
+
+
+typedef struct {
+ GthFileSourceVfs *file_source;
+ GFile *destination;
+ GList *file_list;
+ ReadyCallback callback;
+ gpointer user_data;
+ GList *files;
+ GthCatalog *catalog;
+ char *buffer;
+ gsize length;
+} CopyOpData;
+
+
+static void
+copy_op_data_free (CopyOpData *cod)
+{
+ g_free (cod->buffer);
+ _g_object_unref (cod->catalog);
+ _g_object_list_unref (cod->files);
+ _g_object_list_unref (cod->file_list);
+ g_object_unref (cod->destination);
+ g_object_unref (cod->file_source);
+ g_free (cod);
+}
+
+
+static void
+catalog_save_done_cb (void *buffer,
+ gsize count,
+ GError *error,
+ gpointer user_data)
+{
+ CopyOpData *cod = user_data;
+
+ if (error == NULL)
+ gth_monitor_folder_changed (gth_main_get_default_monitor (),
+ cod->destination,
+ cod->files,
+ GTH_MONITOR_EVENT_CREATED);
+
+ cod->callback (G_OBJECT (cod->file_source), error, cod->user_data);
+ copy_op_data_free (cod);
+}
+
+
+static void
+catalog_ready_cb (GObject *catalog,
+ GError *error,
+ gpointer user_data)
+{
+ CopyOpData *cod = user_data;
+ GList *scan;
+ GFile *gio_file;
+
+ if (error != NULL) {
+ cod->callback (G_OBJECT (cod->file_source), error, cod->user_data);
+ copy_op_data_free (cod);
+ return;
+ }
+
+ cod->catalog = (GthCatalog *) catalog;
+
+ for (scan = cod->files; scan; scan = scan->next)
+ 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);
+ g_write_file_async (gio_file,
+ cod->buffer,
+ cod->length,
+ G_PRIORITY_DEFAULT,
+ NULL,
+ catalog_save_done_cb,
+ cod);
+
+ g_object_unref (gio_file);
+}
+
+
+static void
+copy__file_list_info_ready_cb (GList *files,
+ GError *error,
+ gpointer user_data)
+{
+ CopyOpData *cod = user_data;
+ GList *scan;
+
+ for (scan = files; scan; scan = scan->next) {
+ GthFileData *file_data = scan->data;
+
+ switch (g_file_info_get_file_type (file_data->info)) {
+ case G_FILE_TYPE_REGULAR:
+ case G_FILE_TYPE_SYMBOLIC_LINK:
+ cod->files = g_list_prepend (cod->files, g_object_ref (file_data->file));
+ break;
+ default:
+ break;
+ }
+ }
+ cod->files = g_list_reverse (cod->files);
+
+ gth_catalog_load_from_file (cod->destination, 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)
+{
+ CopyOpData *cod;
+
+ cod = g_new0 (CopyOpData, 1);
+ 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->user_data = data;
+
+ g_query_info_async (cod->file_list,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ GTH_FILE_SOURCE_CATALOGS (file_source)->priv->cancellable,
+ copy__file_list_info_ready_cb,
+ cod);
+}
+
static void
gth_file_source_catalogs_cancel (GthFileSource *file_source)
{
@@ -423,6 +554,7 @@ gth_file_source_catalogs_class_init (GthFileSourceCatalogsClass *class)
file_source_class->get_file_info = gth_file_source_catalogs_get_file_info;
file_source_class->list = gth_file_source_catalogs_list;
file_source_class->read_attributes = gth_file_source_catalogs_read_attributes;
+ file_source_class->copy = gth_file_source_catalogs_copy;
file_source_class->cancel = gth_file_source_catalogs_cancel;
}
diff --git a/extensions/file_manager/actions.c b/extensions/file_manager/actions.c
index 9704d85..46f187e 100644
--- a/extensions/file_manager/actions.c
+++ b/extensions/file_manager/actions.c
@@ -41,11 +41,147 @@ gth_browser_action_rename_folder (GtkAction *action,
}
+/* -- gth_browser_clipboard_copy / gth_browser_clipboard_cut -- */
+
+
+typedef struct {
+ char **uris;
+ int n_uris;
+ gboolean cut;
+} ClipboardData;
+
+
+static char *
+clipboard_data_convert_to_text (ClipboardData *clipboard_data,
+ gboolean formatted,
+ gsize *len)
+{
+ GString *uris;
+ int i;
+
+ if (formatted)
+ uris = g_string_new (clipboard_data->cut ? "cut" : "copy");
+ else
+ uris = g_string_new (NULL);
+
+ for (i = 0; i < clipboard_data->n_uris; i++) {
+ if (formatted) {
+ g_string_append_c (uris, '\n');
+ g_string_append (uris, clipboard_data->uris[i]);
+ }
+ else {
+ GFile *file;
+ char *name;
+
+ if (i > 0)
+ g_string_append_c (uris, '\n');
+ file = g_file_new_for_uri (clipboard_data->uris[i]);
+ name = g_file_get_parse_name (file);
+ g_string_append (uris, name);
+
+ g_free (name);
+ g_object_unref (file);
+ }
+ }
+
+ if (len != NULL)
+ *len = uris->len;
+
+ return g_string_free (uris, FALSE);
+}
+
+
+static void
+clipboard_get_cb (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ guint info,
+ gpointer user_data_or_owner)
+{
+ ClipboardData *clipboard_data = user_data_or_owner;
+
+ if (gtk_targets_include_uri (&selection_data->target, 1)) {
+ gtk_selection_data_set_uris (selection_data, clipboard_data->uris);
+ }
+ else if (gtk_targets_include_text (&selection_data->target, 1)) {
+ char *str;
+ gsize len;
+
+ str = clipboard_data_convert_to_text (clipboard_data, FALSE, &len);
+ gtk_selection_data_set_text (selection_data, str, len);
+ g_free (str);
+ }
+ else if (selection_data->target == GNOME_COPIED_FILES) {
+ char *str;
+ gsize len;
+
+ str = clipboard_data_convert_to_text (clipboard_data, TRUE, &len);
+ gtk_selection_data_set (selection_data, GNOME_COPIED_FILES, 8, (guchar *) str, len);
+ g_free (str);
+ }
+}
+
+
+static void
+clipboard_clear_cb (GtkClipboard *clipboard,
+ gpointer user_data_or_owner)
+{
+ ClipboardData *data = user_data_or_owner;
+
+ g_strfreev (data->uris);
+ g_free (data);
+}
+
+
+static void
+_gth_browser_clipboard_copy_or_cut (GthBrowser *browser,
+ gboolean cut)
+{
+ ClipboardData *data;
+ GList *items;
+ GList *file_list;
+ GtkTargetList *target_list;
+ GtkTargetEntry *targets;
+ int n_targets;
+ GList *scan;
+ int i;
+
+ items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
+ file_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
+
+ data = g_new0 (ClipboardData, 1);
+ data->cut = cut;
+ data->n_uris = g_list_length (file_list);
+ data->uris = g_new (char *, data->n_uris + 1);
+ for (scan = file_list, i = 0; scan; scan = scan->next, i++) {
+ GthFileData *file_data = scan->data;
+ data->uris[i] = g_file_get_uri (file_data->file);
+ }
+ data->uris[data->n_uris] = NULL;
+
+ target_list = gtk_target_list_new (NULL, 0);
+ gtk_target_list_add (target_list, GNOME_COPIED_FILES, 0, 0);
+ gtk_target_list_add_uri_targets (target_list, 0);
+ gtk_target_list_add_text_targets (target_list, 0);
+ targets = gtk_target_table_new_from_list (target_list, &n_targets);
+ gtk_clipboard_set_with_data (gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (browser)), GDK_SELECTION_CLIPBOARD),
+ targets,
+ n_targets,
+ clipboard_get_cb,
+ clipboard_clear_cb,
+ data);
+
+ gtk_target_list_unref (target_list);
+ gtk_target_table_free (targets, n_targets);
+ _g_object_list_unref (file_list);
+ _gtk_tree_path_list_free (items);
+}
+
+
void
gth_browser_activate_action_edit_cut_files (GtkAction *action,
GthBrowser *browser)
{
- gth_browser_clipboard_cut (browser);
+ _gth_browser_clipboard_copy_or_cut (browser, TRUE);
}
@@ -53,15 +189,125 @@ void
gth_browser_activate_action_edit_copy_files (GtkAction *action,
GthBrowser *browser)
{
- gth_browser_clipboard_copy (browser);
+ _gth_browser_clipboard_copy_or_cut (browser, FALSE);
+}
+
+
+/* -- gth_browser_clipboard_paste -- */
+
+
+typedef struct {
+ GthBrowser *browser;
+ GFile *destination;
+ GthFileSource *file_source;
+ GList *files;
+ gboolean cut;
+} PasteData;
+
+
+static void
+paste_data_free (PasteData *paste_data)
+{
+ _g_object_list_unref (paste_data->files);
+ _g_object_unref (paste_data->file_source);
+ g_object_unref (paste_data->destination);
+ g_object_unref (paste_data->browser);
+ g_free (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;
+ char **clipboard_data;
+ PasteData *paste_data;
+ int i;
+
+
+ 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);
+ 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));
+
+ if (paste_data->cut && ! gth_file_source_can_cut (paste_data->file_source)) {
+ GtkWidget *dialog;
+ int response;
+
+ dialog = _gtk_message_dialog_new (GTK_WINDOW (browser),
+ GTK_DIALOG_MODAL,
+ GTK_STOCK_DIALOG_QUESTION,
+ _("Could not move the files"),
+ _("Files cannot be moved to the current location, as alternative you can choose to copy them."),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_COPY, GTK_RESPONSE_OK,
+ NULL);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ if (response == GTK_RESPONSE_CANCEL) {
+ paste_data_free (paste_data);
+ return;
+ }
+
+ paste_data->cut = FALSE;
+ }
+
+ gth_file_source_copy (paste_data->file_source,
+ paste_data->destination,
+ paste_data->files,
+ paste_done_cb,
+ paste_data);
}
void
-gth_browser_activate_action_edit_paste_in_folder (GtkAction *action,
- GthBrowser *browser)
+gth_browser_activate_action_edit_paste (GtkAction *action,
+ GthBrowser *browser)
{
- gth_browser_clipboard_paste (browser);
+ gtk_clipboard_request_contents (gtk_widget_get_clipboard (GTK_WIDGET (browser), GDK_SELECTION_CLIPBOARD),
+ GNOME_COPIED_FILES,
+ clipboard_received_cb,
+ browser);
}
diff --git a/extensions/file_manager/actions.h b/extensions/file_manager/actions.h
index 89327c2..06ce4fd 100644
--- a/extensions/file_manager/actions.h
+++ b/extensions/file_manager/actions.h
@@ -31,7 +31,7 @@ DEFINE_ACTION(gth_browser_action_new_folder)
DEFINE_ACTION(gth_browser_action_rename_folder)
DEFINE_ACTION(gth_browser_activate_action_edit_cut_files)
DEFINE_ACTION(gth_browser_activate_action_edit_copy_files)
-DEFINE_ACTION(gth_browser_activate_action_edit_paste_in_folder)
+DEFINE_ACTION(gth_browser_activate_action_edit_paste)
DEFINE_ACTION(gth_browser_activate_action_edit_duplicate)
DEFINE_ACTION(gth_browser_activate_action_edit_rename)
DEFINE_ACTION(gth_browser_activate_action_edit_trash)
diff --git a/extensions/file_manager/callbacks.c b/extensions/file_manager/callbacks.c
index 7b1c1c5..0a1ae3c 100644
--- a/extensions/file_manager/callbacks.c
+++ b/extensions/file_manager/callbacks.c
@@ -110,7 +110,7 @@ static GtkActionEntry action_entries[] = {
{ "Edit_PasteInFolder", GTK_STOCK_PASTE,
NULL, NULL,
NULL,
- G_CALLBACK (gth_browser_activate_action_edit_paste_in_folder) },
+ G_CALLBACK (gth_browser_activate_action_edit_paste) },
{ "Edit_Duplicate", NULL,
N_("D_uplicate"), "<control><shift>D",
N_("Duplicate the selected files"),
@@ -184,7 +184,7 @@ static void
file_manager_update_ui (BrowserData *data,
GthBrowser *browser)
{
- if (GTH_IS_FILE_SOURCE_VFS (gth_browser_get_file_source (browser))) {
+ if (GTH_IS_FILE_SOURCE_VFS (gth_browser_get_location_source (browser))) {
if (data->vfs_merge_id == 0) {
GError *local_error = NULL;
@@ -216,7 +216,7 @@ file_manager_update_ui (BrowserData *data,
data->browser_merge_id = 0;
}
- if (GTH_IS_FILE_SOURCE_VFS (gth_browser_get_file_source (browser))
+ if (GTH_IS_FILE_SOURCE_VFS (gth_browser_get_location_source (browser))
&& (gth_window_get_current_page (GTH_WINDOW (browser)) == GTH_BROWSER_PAGE_BROWSER))
{
if (data->browser_vfs_merge_id == 0) {
@@ -344,17 +344,21 @@ _gth_browser_update_paste_command_sensitivity (GthBrowser *browser,
void
fm__gth_browser_update_sensitivity_cb (GthBrowser *browser)
{
- BrowserData *data;
- int n_selected;
- gboolean sensitive;
+ BrowserData *data;
+ GthFileSource *file_source;
+ int n_selected;
+ gboolean sensitive;
data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
g_return_if_fail (data != NULL);
+ file_source = gth_browser_get_location_source (browser);
n_selected = gth_file_selection_get_n_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
- sensitive = n_selected > 0;
+ sensitive = (n_selected > 0) && (file_source != NULL) && gth_file_source_can_cut (file_source);
set_action_sensitive (data, "Edit_CutFiles", sensitive);
+
+ sensitive = (n_selected > 0) && (file_source != NULL);
set_action_sensitive (data, "Edit_CopyFiles", sensitive);
set_action_sensitive (data, "Edit_Trash", sensitive);
set_action_sensitive (data, "Edit_Delete", sensitive);
diff --git a/extensions/search/gth-search-task.c b/extensions/search/gth-search-task.c
index e7544bf..addd18a 100644
--- a/extensions/search/gth-search-task.c
+++ b/extensions/search/gth-search-task.c
@@ -173,7 +173,7 @@ done_func (GError *error,
search_result_real_file = gth_catalog_file_to_gio_file (task->priv->search_catalog);
g_write_file_async (search_result_real_file,
data,
- size,
+ size,
G_PRIORITY_DEFAULT,
task->priv->cancellable,
save_search_result_copy_done_cb,
diff --git a/gthumb/gio-utils.c b/gthumb/gio-utils.c
index 7813c07..834c31c 100644
--- a/gthumb/gio-utils.c
+++ b/gthumb/gio-utils.c
@@ -781,129 +781,6 @@ g_directory_list_async (GFile *directory,
}
-/* -- g_list_items_async -- */
-
-
-static void get_items_for_current_dir (GetFileListData *gfl);
-
-
-static gboolean
-get_items_for_next_dir_idle_cb (gpointer data)
-{
- GetFileListData *gfl = data;
-
- g_source_remove (gfl->visit_timeout);
- gfl->visit_timeout = 0;
-
- gfl->current_dir = g_list_next (gfl->current_dir);
- get_items_for_current_dir (gfl);
-
- return FALSE;
-}
-
-
-static void
-get_items_for_current_dir_done (GList *files,
- GList *dirs,
- GError *error,
- gpointer data)
-{
- GetFileListData *gfl = data;
-
- if (error != NULL) {
- if (gfl->done_func)
- gfl->done_func (NULL, NULL, error, gfl->done_data);
- _g_string_list_free (files);
- _g_string_list_free (dirs);
- get_file_list_data_free (gfl);
- return;
- }
-
- gfl->files = g_list_concat (gfl->files, files);
- gfl->dirs = g_list_concat (gfl->dirs, dirs);
-
- gfl->visit_timeout = g_idle_add (get_items_for_next_dir_idle_cb, gfl);
-}
-
-
-static void
-get_items_for_current_dir (GetFileListData *gfl)
-{
- const char *directory_name;
- char *directory_uri;
- GFile *directory;
-
- if (gfl->current_dir == NULL) {
- if (gfl->done_func) {
- /* gfl->files/gfl->dirs must be deallocated in gfl->done_func */
- gfl->done_func (gfl->files, gfl->dirs, NULL, gfl->done_data);
- gfl->files = NULL;
- gfl->dirs = NULL;
- }
- get_file_list_data_free (gfl);
- return;
- }
-
- directory_name = _g_uri_get_basename ((char*) gfl->current_dir->data);
- if (strcmp (gfl->base_dir, "/") == 0)
- directory_uri = g_strconcat (gfl->base_dir, directory_name, NULL);
- else
- directory_uri = g_strconcat (gfl->base_dir, "/", directory_name, NULL);
-
- directory = g_file_new_for_uri (directory_uri);
- g_directory_list_all_async (directory,
- gfl->base_dir,
- TRUE,
- gfl->cancellable,
- get_items_for_current_dir_done,
- gfl);
-
- g_object_unref (directory);
- g_free (directory_uri);
-}
-
-
-void
-g_list_items_async (GList *items,
- const char *base_dir,
- GCancellable *cancellable,
- ListReadyCallback done_func,
- gpointer done_data)
-{
- GetFileListData *gfl;
- int base_len;
- GList *scan;
-
- g_return_if_fail (base_dir != NULL);
-
- gfl = g_new0 (GetFileListData, 1);
- gfl->base_dir = g_strdup (base_dir);
- gfl->cancellable = cancellable;
- gfl->done_func = done_func;
- gfl->done_data = done_data;
-
- base_len = 0;
- if (strcmp (base_dir, "/") != 0)
- base_len = strlen (base_dir);
-
- for (scan = items; scan; scan = scan->next) {
- char *path = scan->data;
-
- /* FIXME: this is not async */
- if (_g_uri_is_dir (path)) {
- gfl->to_visit = g_list_prepend (gfl->to_visit, g_strdup (path));
- }
- else {
- char *rel_path = g_strdup (path + base_len + 1);
- gfl->files = g_list_prepend (gfl->files, rel_path);
- }
- }
-
- gfl->current_dir = gfl->to_visit;
- get_items_for_current_dir (gfl);
-}
-
-
/* -- g_query_info_async -- */
@@ -1204,8 +1081,8 @@ g_copy_files_async (GList *sources,
/* add the metadata sidecars if requested */
if (flags && G_FILE_COPY_ALL_METADATA) {
- GList *source_sidecars = NULL;
- GList *destination_sidecars = NULL;
+ GList *source_sidecars = NULL;
+ GList *destination_sidecars = NULL;
gth_hook_invoke ("add-sidecars", sources, &source_sidecars);
diff --git a/gthumb/gio-utils.h b/gthumb/gio-utils.h
index cd42ff9..0bcf4e1 100644
--- a/gthumb/gio-utils.h
+++ b/gthumb/gio-utils.h
@@ -90,12 +90,7 @@ void g_directory_list_async (GFile *directory,
GCancellable *cancellable,
ListReadyCallback done_func,
gpointer done_data);
-void g_list_items_async (GList *items,
- const char *base_dir,
- GCancellable *cancellable,
- ListReadyCallback done_func,
- gpointer done_data);
-void g_query_info_async (GList *files,
+void g_query_info_async (GList *files, /* GFile * list */
const char *attributes,
GCancellable *cancellable,
InfoReadyCallback ready_func,
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index eb8555f..a25a77c 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -3074,7 +3074,7 @@ gth_browser_get_file_list_view (GthBrowser *browser)
GthFileSource *
-gth_browser_get_file_source (GthBrowser *browser)
+gth_browser_get_location_source (GthBrowser *browser)
{
return browser->priv->location_source;
}
@@ -3941,159 +3941,3 @@ gth_browser_unfullscreen (GthBrowser *browser)
if (browser->priv->motion_signal != 0)
g_signal_handler_disconnect (browser, browser->priv->motion_signal);
}
-
-
-/* -- clipboard -- */
-
-
-typedef struct {
- char **uris;
- int n_uris;
- gboolean cut;
-} ClipboardData;
-
-
-static char *
-clipboard_data_convert_to_text (ClipboardData *clipboard_data,
- gboolean formatted,
- gsize *len)
-{
- GString *uris;
- int i;
-
- if (formatted)
- uris = g_string_new (clipboard_data->cut ? "cut" : "copy");
- else
- uris = g_string_new (NULL);
-
- for (i = 0; i < clipboard_data->n_uris; i++) {
- if (formatted) {
- g_string_append_c (uris, '\n');
- g_string_append (uris, clipboard_data->uris[i]);
- }
- else {
- GFile *file;
- char *name;
-
- if (i > 0)
- g_string_append_c (uris, '\n');
- file = g_file_new_for_uri (clipboard_data->uris[i]);
- name = g_file_get_parse_name (file);
- g_string_append (uris, name);
-
- g_free (name);
- g_object_unref (file);
- }
- }
-
- if (len != NULL)
- *len = uris->len;
-
- return g_string_free (uris, FALSE);
-}
-
-
-static void
-clipboard_get_cb (GtkClipboard *clipboard,
- GtkSelectionData *selection_data,
- guint info,
- gpointer user_data_or_owner)
-{
- ClipboardData *clipboard_data = user_data_or_owner;
-
- if (gtk_targets_include_uri (&selection_data->target, 1)) {
- gtk_selection_data_set_uris (selection_data, clipboard_data->uris);
- }
- else if (gtk_targets_include_text (&selection_data->target, 1)) {
- char *str;
- gsize len;
-
- str = clipboard_data_convert_to_text (clipboard_data, FALSE, &len);
- gtk_selection_data_set_text (selection_data, str, len);
- g_free (str);
- }
- else if (selection_data->target == GNOME_COPIED_FILES) {
- char *str;
- gsize len;
-
- str = clipboard_data_convert_to_text (clipboard_data, TRUE, &len);
- gtk_selection_data_set (selection_data, GNOME_COPIED_FILES, 8, (guchar *) str, len);
- g_free (str);
- }
-}
-
-
-static void
-clipboard_clear_cb (GtkClipboard *clipboard,
- gpointer user_data_or_owner)
-{
- ClipboardData *data = user_data_or_owner;
-
- g_strfreev (data->uris);
- g_free (data);
-}
-
-
-static void
-_gth_browser_clipboard_copy_or_cut (GthBrowser *browser,
- gboolean cut)
-{
- ClipboardData *data;
- GList *items;
- GList *file_list;
- GtkTargetList *target_list;
- GtkTargetEntry *targets;
- int n_targets;
- GList *scan;
- int i;
-
- items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
- file_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
-
- data = g_new0 (ClipboardData, 1);
- data->cut = cut;
- data->n_uris = g_list_length (file_list);
- data->uris = g_new (char *, data->n_uris + 1);
- for (scan = file_list, i = 0; scan; scan = scan->next, i++) {
- GthFileData *file_data = scan->data;
- data->uris[i] = g_file_get_uri (file_data->file);
- }
- data->uris[data->n_uris] = NULL;
-
- target_list = gtk_target_list_new (NULL, 0);
- gtk_target_list_add (target_list, GNOME_COPIED_FILES, 0, 0);
- gtk_target_list_add_uri_targets (target_list, 0);
- gtk_target_list_add_text_targets (target_list, 0);
- targets = gtk_target_table_new_from_list (target_list, &n_targets);
- gtk_clipboard_set_with_data (gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (browser)), GDK_SELECTION_CLIPBOARD),
- targets,
- n_targets,
- clipboard_get_cb,
- clipboard_clear_cb,
- data);
-
- gtk_target_list_unref (target_list);
- gtk_target_table_free (targets, n_targets);
- _g_object_list_unref (file_list);
- _gtk_tree_path_list_free (items);
-}
-
-
-void
-gth_browser_clipboard_copy (GthBrowser *browser)
-{
- _gth_browser_clipboard_copy_or_cut (browser, FALSE);
-}
-
-
-void
-gth_browser_clipboard_cut (GthBrowser *browser)
-{
- _gth_browser_clipboard_copy_or_cut (browser, TRUE);
-}
-
-
-void
-gth_browser_clipboard_paste (GthBrowser *browser)
-{
-}
diff --git a/gthumb/gth-browser.h b/gthumb/gth-browser.h
index 322271e..5f817be 100644
--- a/gthumb/gth-browser.h
+++ b/gthumb/gth-browser.h
@@ -90,7 +90,7 @@ GtkUIManager * gth_browser_get_ui_manager (GthBrowser *browser);
GtkWidget * gth_browser_get_statusbar (GthBrowser *browser);
GtkWidget * gth_browser_get_file_list (GthBrowser *browser);
GtkWidget * gth_browser_get_file_list_view (GthBrowser *browser);
-GthFileSource * gth_browser_get_file_source (GthBrowser *browser);
+GthFileSource * gth_browser_get_location_source (GthBrowser *browser);
GthFileStore * gth_browser_get_file_store (GthBrowser *browser);
GtkWidget * gth_browser_get_folder_tree (GthBrowser *browser);
void gth_browser_get_sort_order (GthBrowser *browser,
@@ -144,9 +144,6 @@ void gth_browser_show_filterbar (GthBrowser *browser,
gpointer gth_browser_get_image_preloader (GthBrowser *browser);
void gth_browser_fullscreen (GthBrowser *browser);
void gth_browser_unfullscreen (GthBrowser *browser);
-void gth_browser_clipboard_copy (GthBrowser *browser);
-void gth_browser_clipboard_cut (GthBrowser *browser);
-void gth_browser_clipboard_paste (GthBrowser *browser);
G_END_DECLS
diff --git a/gthumb/gth-file-data.c b/gthumb/gth-file-data.c
index 03ff5b4..697cebf 100644
--- a/gthumb/gth-file-data.c
+++ b/gthumb/gth-file-data.c
@@ -168,13 +168,16 @@ void
gth_file_data_set_file (GthFileData *self,
GFile *file)
{
+ if (file != NULL)
+ g_object_ref (file);
+
if (self->file != NULL) {
g_object_unref (self->file);
self->file = NULL;
}
if (file != NULL)
- self->file = g_object_ref (file);
+ self->file = file;
}
@@ -182,13 +185,14 @@ void
gth_file_data_set_info (GthFileData *self,
GFileInfo *info)
{
- if (self->info != NULL) {
+ if (info != NULL)
+ g_object_ref (info);
+
+ if (self->info != NULL)
g_object_unref (self->info);
- self->info = NULL;
- }
if (info != NULL)
- self->info = g_object_ref (info);
+ self->info = info;
else
self->info = g_file_info_new ();
}
diff --git a/gthumb/gth-file-source-vfs.c b/gthumb/gth-file-source-vfs.c
index deaaae1..f9352ad 100644
--- a/gthumb/gth-file-source-vfs.c
+++ b/gthumb/gth-file-source-vfs.c
@@ -292,6 +292,188 @@ cancel (GthFileSource *file_source)
}
+/* -- gth_file_source_vfs_copy -- */
+
+
+typedef struct {
+ GthFileSourceVfs *file_source;
+ GFile *destination;
+ GList *file_list;
+ ReadyCallback callback;
+ gpointer user_data;
+ GList *files;
+ GList *dirs;
+ GList *current_dir;
+} CopyOpData;
+
+
+static void
+copy_op_data_free (CopyOpData *cod)
+{
+ g_object_unref (cod->file_source);
+ g_object_unref (cod->destination);
+ _g_object_list_unref (cod->file_list);
+ _g_object_list_unref (cod->files);
+ _g_object_list_unref (cod->dirs);
+ g_free (cod);
+}
+
+
+static void
+copy__copy_files_done (GError *error,
+ gpointer user_data)
+{
+ CopyOpData *cod = user_data;
+
+ cod->callback (G_OBJECT (cod->file_source), error, cod->user_data);
+ copy_op_data_free (cod);
+}
+
+
+static void
+copy__copy_files (CopyOpData *cod)
+{
+ GList *destinations;
+ GList *scan;
+
+ destinations = NULL;
+ for (scan = cod->files; scan; scan = scan->next) {
+ GFile *source = scan->data;
+ char *source_basename;
+
+ source_basename = g_file_get_basename (source);
+ destinations = g_list_prepend (destinations, g_file_get_child (cod->destination, source_basename));
+
+ g_free (source_basename);
+ }
+
+ g_copy_files_async (cod->files,
+ destinations,
+ G_FILE_COPY_NONE,
+ G_PRIORITY_DEFAULT,
+ cod->file_source->priv->cancellable,
+ NULL,
+ NULL,
+ copy__copy_files_done,
+ cod);
+
+ _g_object_list_unref (destinations);
+}
+
+
+static void copy__copy_current_dir (CopyOpData *cod);
+
+
+static void
+copy__copy_current_dir_done (GError *error,
+ gpointer user_data)
+{
+ CopyOpData *cod = user_data;
+
+ if (error != NULL) {
+ cod->callback (G_OBJECT (cod->file_source), error, cod->user_data);
+ copy_op_data_free (cod);
+ return;
+ }
+
+ cod->current_dir = cod->current_dir->next;
+ copy__copy_current_dir (cod);
+}
+
+
+static void
+copy__copy_current_dir (CopyOpData *cod)
+{
+ GFile *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);
+
+ g_directory_copy_async (source,
+ destination,
+ G_FILE_COPY_NONE,
+ G_PRIORITY_DEFAULT,
+ cod->file_source->priv->cancellable,
+ NULL,
+ NULL,
+ copy__copy_current_dir_done,
+ cod);
+
+ g_object_unref (destination);
+ g_free (source_basename);
+}
+
+
+static void
+copy__file_list_info_ready_cb (GList *files,
+ GError *error,
+ gpointer user_data)
+{
+ CopyOpData *cod = user_data;
+ GList *scan;
+
+ for (scan = files; scan; scan = scan->next) {
+ GthFileData *file_data = scan->data;
+
+ 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));
+ break;
+ case G_FILE_TYPE_REGULAR:
+ case G_FILE_TYPE_SYMBOLIC_LINK:
+ cod->files = g_list_prepend (cod->files, g_object_ref (file_data->file));
+ break;
+ default:
+ break;
+ }
+ }
+ cod->files = g_list_reverse (cod->files);
+ cod->dirs = g_list_reverse (cod->dirs);
+
+ cod->current_dir = cod->dirs;
+ copy__copy_current_dir (cod);
+}
+
+
+static void
+gth_file_source_vfs_copy (GthFileSource *file_source,
+ GFile *destination,
+ GList *file_list, /* GFile * list */
+ ReadyCallback callback,
+ gpointer data)
+{
+ CopyOpData *cod;
+
+ cod = g_new0 (CopyOpData, 1);
+ 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->user_data = data;
+
+ g_query_info_async (cod->file_list,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ cod->file_source->priv->cancellable,
+ copy__file_list_info_ready_cb,
+ cod);
+}
+
+
+static gboolean
+gth_file_source_vfs_can_cut (GthFileSource *file_source)
+{
+ return TRUE;
+}
+
+
static void
mount_monitor_mountpoints_changed_cb (GUnixMountMonitor *monitor,
gpointer user_data)
@@ -534,6 +716,8 @@ gth_file_source_vfs_class_init (GthFileSourceVfsClass *class)
file_source_class->list = list;
file_source_class->read_attributes = read_attributes;
file_source_class->cancel = cancel;
+ file_source_class->copy = gth_file_source_vfs_copy;
+ file_source_class->can_cut = gth_file_source_vfs_can_cut;
file_source_class->monitor_entry_points = monitor_entry_points;
file_source_class->monitor_directory = monitor_directory;
}
diff --git a/gthumb/gth-file-source.c b/gthumb/gth-file-source.c
index 6e08f2a..12d946a 100644
--- a/gthumb/gth-file-source.c
+++ b/gthumb/gth-file-source.c
@@ -48,7 +48,8 @@ static GObjectClass *parent_class = NULL;
typedef enum {
FILE_SOURCE_OP_LIST,
FILE_SOURCE_OP_READ_ATTRIBUTES,
- FILE_SOURCE_OP_RENAME
+ FILE_SOURCE_OP_RENAME,
+ FILE_SOURCE_OP_COPY
} FileSourceOp;
@@ -77,12 +78,21 @@ typedef struct {
typedef struct {
+ GFile *destination;
+ GList *file_list;
+ ReadyCallback callback;
+ gpointer data;
+} CopyData;
+
+
+typedef struct {
GthFileSource *file_source;
FileSourceOp op;
union {
ListData list;
ReadAttributesData read_attributes;
RenameData rename;
+ CopyData copy;
} data;
} FileSourceAsyncOp;
@@ -101,6 +111,10 @@ file_source_async_op_free (FileSourceAsyncOp *async_op)
g_object_unref (async_op->data.rename.file);
g_object_unref (async_op->data.rename.new_file);
break;
+ case FILE_SOURCE_OP_COPY:
+ g_object_unref (async_op->data.copy.destination);
+ _g_object_list_unref (async_op->data.copy.file_list);
+ break;
}
g_free (async_op);
@@ -171,6 +185,27 @@ 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)
+{
+ 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.file_list = _g_file_list_dup (file_list);
+ async_op->data.copy.callback = callback;
+ async_op->data.copy.data = data;
+
+ file_source->priv->queue = g_list_append (file_source->priv->queue, async_op);
+}
+
+
+static void
gth_file_source_exec_next_in_queue (GthFileSource *file_source)
{
GList *head;
@@ -205,6 +240,13 @@ gth_file_source_exec_next_in_queue (GthFileSource *file_source)
async_op->data.rename.callback,
async_op->data.rename.data);
break;
+ case FILE_SOURCE_OP_COPY:
+ 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.data);
+ break;
}
file_source_async_op_free (async_op);
@@ -327,6 +369,13 @@ base_rename (GthFileSource *file_source,
}
+static gboolean
+base_can_cut (GthFileSource *file_source)
+{
+ return FALSE;
+}
+
+
static void
base_monitor_entry_points (GthFileSource *file_source)
{
@@ -377,6 +426,7 @@ gth_file_source_class_init (GthFileSourceClass *class)
class->read_attributes = base_read_attributes;
class->cancel = base_cancel;
class->rename = base_rename;
+ class->can_cut = base_can_cut;
class->monitor_entry_points = base_monitor_entry_points;
class->monitor_directory = base_monitor_directory;
}
@@ -561,6 +611,28 @@ 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)
+{
+ if (gth_file_source_is_active (file_source)) {
+ gth_file_source_queue_copy (file_source, destination, file_list, callback, data);
+ return;
+ }
+ GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->copy (file_source, destination, file_list, callback, data);
+}
+
+
+gboolean
+gth_file_source_can_cut (GthFileSource *file_source)
+{
+ return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->can_cut (file_source);
+}
+
+
+void
gth_file_source_monitor_entry_points (GthFileSource *file_source)
{
GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->monitor_entry_points (file_source);
diff --git a/gthumb/gth-file-source.h b/gthumb/gth-file-source.h
index f3270d1..a026912 100644
--- a/gthumb/gth-file-source.h
+++ b/gthumb/gth-file-source.h
@@ -88,6 +88,12 @@ struct _GthFileSourceClass
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,
@@ -133,6 +139,12 @@ void gth_file_source_rename (GthFileSource *file_source,
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,
diff --git a/gthumb/gth-thumb-loader.c b/gthumb/gth-thumb-loader.c
index 1c080bf..164c3f5 100644
--- a/gthumb/gth-thumb-loader.c
+++ b/gthumb/gth-thumb-loader.c
@@ -522,15 +522,21 @@ gth_thumb_loader_set_file (GthThumbLoader *tloader,
tloader->priv->file = NULL;
if (fd != NULL) {
- GFile *real_file = NULL;
+ GFile *real_file = NULL;
+ GError *error = NULL;
tloader->priv->file = gth_file_data_dup (fd);
- real_file = _g_file_resolve_all_symlinks (tloader->priv->file->file, NULL);
+ real_file = _g_file_resolve_all_symlinks (tloader->priv->file->file, &error);
+ if (real_file == NULL) {
+ g_warning ("%s", error->message);
+ g_clear_error (&error);
+ return;
+ }
+
gth_file_data_set_file (tloader->priv->file, real_file);
- if (real_file != NULL)
- g_object_unref (real_file);
+ g_object_unref (real_file);
}
gth_image_loader_set_file_data (tloader->priv->iloader, tloader->priv->file);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]