[gthumb/ext: 15/79] started work on cut/copy/paste commands



commit 1bd5646102506ef33d7a902732dd2a8be2465cd2
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Wed Jun 17 21:38:45 2009 +0200

    started work on cut/copy/paste commands

 extensions/file_manager/actions.c   |    5 +-
 extensions/file_manager/callbacks.c |  112 +++++++++++++++++++---
 extensions/file_manager/callbacks.h |    2 +
 extensions/file_manager/main.c      |    2 +
 gthumb/glib-utils.h                 |    1 +
 gthumb/gth-browser.c                |  186 ++++++++++++++++++++++++++++++++++-
 gthumb/gth-browser.h                |    3 +
 gthumb/gth-main-default-hooks.c     |   14 +++
 8 files changed, 309 insertions(+), 16 deletions(-)
---
diff --git a/extensions/file_manager/actions.c b/extensions/file_manager/actions.c
index bcc7e21..9704d85 100644
--- a/extensions/file_manager/actions.c
+++ b/extensions/file_manager/actions.c
@@ -45,6 +45,7 @@ void
 gth_browser_activate_action_edit_cut_files (GtkAction  *action,
 					    GthBrowser *browser)
 {
+	gth_browser_clipboard_cut (browser);
 }
 
 
@@ -52,6 +53,7 @@ void
 gth_browser_activate_action_edit_copy_files (GtkAction  *action,
 					     GthBrowser *browser)
 {
+	gth_browser_clipboard_copy (browser);
 }
 
 
@@ -59,6 +61,7 @@ void
 gth_browser_activate_action_edit_paste_in_folder (GtkAction  *action,
 						  GthBrowser *browser)
 {
+	gth_browser_clipboard_paste (browser);
 }
 
 
@@ -67,7 +70,7 @@ gth_browser_activate_action_edit_duplicate (GtkAction  *action,
 					    GthBrowser *browser)
 {
 	GList   *items;
-	GList   *file_list = NULL;
+	GList   *file_list;
 	GthTask *task;
 
 	items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
diff --git a/extensions/file_manager/callbacks.c b/extensions/file_manager/callbacks.c
index 1703239..a1c4024 100644
--- a/extensions/file_manager/callbacks.c
+++ b/extensions/file_manager/callbacks.c
@@ -146,6 +146,18 @@ browser_data_free (BrowserData *data)
 }
 
 
+static void
+set_action_sensitive (BrowserData *data,
+		      const char  *action_name,
+		      gboolean     sensitive)
+{
+	GtkAction *action;
+
+	action = gtk_action_group_get_action (data->action_group, action_name);
+	g_object_set (action, "sensitive", sensitive, NULL);
+}
+
+
 void
 fm__gth_browser_construct_cb (GthBrowser *browser)
 {
@@ -162,6 +174,7 @@ fm__gth_browser_construct_cb (GthBrowser *browser)
 				      G_N_ELEMENTS (action_entries),
 				      browser);
 	gtk_ui_manager_insert_action_group (gth_browser_get_ui_manager (browser), data->action_group, 0);
+	set_action_sensitive (data, "Edit_PasteInFolder", FALSE);
 
 	g_object_set_data_full (G_OBJECT (browser), BROWSER_DATA_KEY, data, (GDestroyNotify) browser_data_free);
 }
@@ -285,11 +298,53 @@ fm__gth_browser_folder_tree_popup_before_cb (GthBrowser    *browser,
 }
 
 
+static void
+clipboard_targets_received_cb (GtkClipboard *clipboard,
+			       GdkAtom      *atoms,
+                               int           n_atoms,
+                               gpointer      user_data)
+{
+	GthBrowser  *browser = user_data;
+	BrowserData *data;
+	gboolean     can_paste;
+	int          i;
+
+	data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
+
+	can_paste = FALSE;
+	for (i = 0; ! can_paste && (i < n_atoms); i++)
+		if (atoms[i] == GNOME_COPIED_FILES)
+			can_paste = TRUE;
+
+	set_action_sensitive (data, "Edit_PasteInFolder", can_paste);
+
+	g_object_unref (browser);
+}
+
+
+static void
+_gth_browser_update_paste_command_sensitivity (GthBrowser   *browser,
+                                               GtkClipboard *clipboard)
+{
+	BrowserData *data;
+
+	data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
+	g_return_if_fail (data != NULL);
+
+        set_action_sensitive (data, "Edit_PasteInFolder", FALSE);
+
+	if (clipboard == NULL)
+		clipboard = gtk_widget_get_clipboard (GTK_WIDGET (browser), GDK_SELECTION_CLIPBOARD);
+	gtk_clipboard_request_targets (clipboard,
+				       clipboard_targets_received_cb,
+				       g_object_ref (browser));
+}
+
+
 void
 fm__gth_browser_update_sensitivity_cb (GthBrowser *browser)
 {
 	BrowserData *data;
-	GtkAction   *action;
 	int          n_selected;
 	gboolean     sensitive;
 
@@ -299,16 +354,47 @@ fm__gth_browser_update_sensitivity_cb (GthBrowser *browser)
 	n_selected = gth_file_selection_get_n_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
 
 	sensitive = n_selected > 0;
-	action = gtk_action_group_get_action (data->action_group, "Edit_CutFiles");
-	g_object_set (action, "sensitive", sensitive, NULL);
-	action = gtk_action_group_get_action (data->action_group, "Edit_CopyFiles");
-	g_object_set (action, "sensitive", sensitive, NULL);
-	action = gtk_action_group_get_action (data->action_group, "Edit_Trash");
-	g_object_set (action, "sensitive", sensitive, NULL);
-	action = gtk_action_group_get_action (data->action_group, "Edit_Delete");
-	g_object_set (action, "sensitive", sensitive, NULL);
-	action = gtk_action_group_get_action (data->action_group, "Edit_Duplicate");
-	g_object_set (action, "sensitive", sensitive, NULL);
-	action = gtk_action_group_get_action (data->action_group, "Edit_Rename");
-	g_object_set (action, "sensitive", sensitive, NULL);
+	set_action_sensitive (data, "Edit_CutFiles", sensitive);
+	set_action_sensitive (data, "Edit_CopyFiles", sensitive);
+	set_action_sensitive (data, "Edit_Trash", sensitive);
+	set_action_sensitive (data, "Edit_Delete", sensitive);
+	set_action_sensitive (data, "Edit_Duplicate", sensitive);
+	set_action_sensitive (data, "Edit_Rename", sensitive);
+
+	_gth_browser_update_paste_command_sensitivity (browser, NULL);
+}
+
+
+static void
+clipboard_owner_change_cb (GtkClipboard *clipboard,
+                           GdkEvent     *event,
+                           gpointer      user_data)
+{
+	_gth_browser_update_paste_command_sensitivity ((GthBrowser *) user_data, clipboard);
 }
+
+
+void
+fm__gth_browser_realize_cb (GthBrowser *browser)
+{
+	GtkClipboard *clipboard;
+
+	clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+	g_signal_connect (clipboard,
+	                  "owner_change",
+	                  G_CALLBACK (clipboard_owner_change_cb),
+	                  browser);
+}
+
+
+void
+fm__gth_browser_unrealize_cb (GthBrowser *browser)
+{
+	GtkClipboard *clipboard;
+
+	clipboard = gtk_widget_get_clipboard (GTK_WIDGET (browser), GDK_SELECTION_CLIPBOARD);
+	g_signal_handlers_disconnect_by_func (clipboard,
+	                                      G_CALLBACK (clipboard_owner_change_cb),
+	                                      browser);
+}
+
diff --git a/extensions/file_manager/callbacks.h b/extensions/file_manager/callbacks.h
index 2dd42ad..2c5f71d 100644
--- a/extensions/file_manager/callbacks.h
+++ b/extensions/file_manager/callbacks.h
@@ -35,5 +35,7 @@ void fm__gth_browser_folder_tree_popup_before_cb (GthBrowser    *browser,
 						  GthFileSource *file_source,
 					          GFile         *folder);
 void fm__gth_browser_update_sensitivity_cb       (GthBrowser    *browser);
+void fm__gth_browser_realize_cb                  (GthBrowser    *browser);
+void fm__gth_browser_unrealize_cb                (GthBrowser    *browser);
 
 #endif /* CALLBACKS_H */
diff --git a/extensions/file_manager/main.c b/extensions/file_manager/main.c
index 754abba..1a9dc06 100644
--- a/extensions/file_manager/main.c
+++ b/extensions/file_manager/main.c
@@ -35,6 +35,8 @@ gthumb_extension_activate (void)
 	gth_hook_add_callback ("gth-browser-set-current-page", 10, G_CALLBACK (fm__gth_browser_set_current_page_cb), NULL);
 	gth_hook_add_callback ("gth-browser-folder-tree-popup-before", 10, G_CALLBACK (fm__gth_browser_folder_tree_popup_before_cb), NULL);
 	gth_hook_add_callback ("gth-browser-update-sensitivity", 10, G_CALLBACK (fm__gth_browser_update_sensitivity_cb), NULL);
+	gth_hook_add_callback ("gth-browser-realize", 10, G_CALLBACK (fm__gth_browser_realize_cb), NULL);
+	gth_hook_add_callback ("gth-browser-unrealize", 10, G_CALLBACK (fm__gth_browser_unrealize_cb), NULL);
 }
 
 
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index 6fe0964..d45dd35 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -30,6 +30,7 @@
 
 G_BEGIN_DECLS
 
+#define GNOME_COPIED_FILES (gdk_atom_intern_static_string ("x-special/gnome-copied-files"))
 #define IROUND(x) ((int)floor(((double)x) + 0.5))
 #define FLOAT_EQUAL(a,b) (fabs (a - b) < 1e-6)
 #define ID_LENGTH 8
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 603891c..bd37b84 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -2522,6 +2522,26 @@ pref_thumbnail_size_changed (GConfClient *client,
 }
 
 
+static gboolean
+_gth_browser_realize (GtkWidget *browser,
+                      gpointer  *data)
+{
+	gth_hook_invoke ("gth-browser-realize", browser);
+
+	return FALSE;
+}
+
+
+static gboolean
+_gth_browser_unrealize (GtkWidget *browser,
+                        gpointer  *data)
+{
+	gth_hook_invoke ("gth-browser-unrealize", browser);
+
+	return FALSE;
+}
+
+
 static void
 _gth_browser_construct (GthBrowser *browser)
 {
@@ -2821,6 +2841,9 @@ _gth_browser_construct (GthBrowser *browser)
 
 	gth_hook_invoke ("gth-browser-construct", browser);
 
+        g_signal_connect (browser, "realize", G_CALLBACK (_gth_browser_realize), NULL);
+        g_signal_connect (browser, "unrealize", G_CALLBACK (_gth_browser_unrealize), NULL);
+
 	performance (DEBUG_INFO, "window initialized");
 
 	/* gconf notifications */
@@ -3108,10 +3131,9 @@ void
 gth_browser_stop (GthBrowser *browser)
 {
 	if (browser->priv->fullscreen)
-		gth_browser_fullscreen (browser);
+		gth_browser_unfullscreen (browser);
 
 	_gth_browser_cancel (browser);
-
 	gth_browser_update_sensitivity (browser);
 
 	if ((browser->priv->task != NULL) && gth_task_is_running (browser->priv->task))
@@ -3906,6 +3928,8 @@ gth_browser_fullscreen (GthBrowser *browser)
 void
 gth_browser_unfullscreen (GthBrowser *browser)
 {
+	browser->priv->fullscreen = FALSE;
+
 	gtk_widget_hide (browser->priv->fullscreen_toolbar);
 	gtk_window_unfullscreen (GTK_WINDOW (browser));
 	gth_window_show_only_content (GTH_WINDOW (browser), FALSE);
@@ -3917,3 +3941,161 @@ 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_target_list_unref (target_list);
+
+	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_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 5e93a03..322271e 100644
--- a/gthumb/gth-browser.h
+++ b/gthumb/gth-browser.h
@@ -144,6 +144,9 @@ 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-main-default-hooks.c b/gthumb/gth-main-default-hooks.c
index f0a4a83..61f0dbb 100644
--- a/gthumb/gth-main-default-hooks.c
+++ b/gthumb/gth-main-default-hooks.c
@@ -41,6 +41,20 @@ gth_main_register_default_hooks (void)
 	gth_hook_register ("gth-browser-construct", 1);
 
 	/**
+	 * Called when the window is realized.
+	 *
+	 * @browser (GthBrowser*): the window.
+	 **/
+	gth_hook_register ("gth-browser-realize", 1);
+
+	/**
+	 * Called when the window is unrealized.
+	 *
+	 * @browser (GthBrowser*): the window.
+	 **/
+	gth_hook_register ("gth-browser-unrealize", 1);
+
+	/**
 	 * Called before closing a window.
 	 *
 	 * @browser (GthBrowser*): the window to be closed.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]