aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2001-06-26 03:48:02 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2001-06-26 03:48:02 +0800
commitb655dc216eaab23a6f2d2e9a278b4f5dd4fdfa3a (patch)
treec750eabb31336ca6a4b13767c06888173993c2df
parent628e96b122048504a5680c75afe59d1a56789419 (diff)
downloadgsoc2013-evolution-b655dc216eaab23a6f2d2e9a278b4f5dd4fdfa3a.tar
gsoc2013-evolution-b655dc216eaab23a6f2d2e9a278b4f5dd4fdfa3a.tar.gz
gsoc2013-evolution-b655dc216eaab23a6f2d2e9a278b4f5dd4fdfa3a.tar.bz2
gsoc2013-evolution-b655dc216eaab23a6f2d2e9a278b4f5dd4fdfa3a.tar.lz
gsoc2013-evolution-b655dc216eaab23a6f2d2e9a278b4f5dd4fdfa3a.tar.xz
gsoc2013-evolution-b655dc216eaab23a6f2d2e9a278b4f5dd4fdfa3a.tar.zst
gsoc2013-evolution-b655dc216eaab23a6f2d2e9a278b4f5dd4fdfa3a.zip
Unref the invisible window that we use for slections.
2001-06-25 Jeffrey Stedfast <fejj@ximian.com> * folder-browser.c (folder_browser_destroy): Unref the invisible window that we use for slections. (folder_browser_class_init): Init the clipboard_atam type. (selection_get): New (selection_clear_event): New (selection_received): New (folder_browser_copy): New function to copy the message-list selection. (folder_browser_cut): New function to cut the message-list selection. (folder_browser_paste): New function to paste the message-list selection. (my_folder_browser_init): Initialize `invisible` if it's NULL else ref it - also set some signals on it. * folder-browser-factory.c: Added verbs for cut/copy/paste. svn path=/trunk/; revision=10489
-rw-r--r--mail/ChangeLog19
-rw-r--r--mail/folder-browser-factory.c3
-rw-r--r--mail/folder-browser.c214
-rw-r--r--mail/folder-browser.h4
4 files changed, 224 insertions, 16 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 2e47d22e4d..05ef8d82cf 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,22 @@
+2001-06-25 Jeffrey Stedfast <fejj@ximian.com>
+
+ * folder-browser.c (folder_browser_destroy): Unref the invisible
+ window that we use for slections.
+ (folder_browser_class_init): Init the clipboard_atam type.
+ (selection_get): New
+ (selection_clear_event): New
+ (selection_received): New
+ (folder_browser_copy): New function to copy the message-list
+ selection.
+ (folder_browser_cut): New function to cut the message-list
+ selection.
+ (folder_browser_paste): New function to paste the message-list
+ selection.
+ (my_folder_browser_init): Initialize `invisible` if it's NULL else
+ ref it - also set some signals on it.
+
+ * folder-browser-factory.c: Added verbs for cut/copy/paste.
+
2001-06-23 Jason Leach <jleach@ximian.com>
* mail-local.c (local_storage_removed_folder_cb): Fixes here for
diff --git a/mail/folder-browser-factory.c b/mail/folder-browser-factory.c
index 68e783e665..5f959cdc50 100644
--- a/mail/folder-browser-factory.c
+++ b/mail/folder-browser-factory.c
@@ -47,6 +47,9 @@ static EList *control_list = NULL;
* Add with 'folder_browser'
*/
BonoboUIVerb verbs [] = {
+ BONOBO_UI_UNSAFE_VERB ("EditCut", folder_browser_cut),
+ BONOBO_UI_UNSAFE_VERB ("EditCopy", folder_browser_copy),
+ BONOBO_UI_UNSAFE_VERB ("EditPaste", folder_browser_paste),
BONOBO_UI_UNSAFE_VERB ("EditInvertSelection", invert_selection),
BONOBO_UI_UNSAFE_VERB ("EditSelectAll", select_all),
/* BONOBO_UI_UNSAFE_VERB ("EditSelectThread", select_thread), */
diff --git a/mail/folder-browser.c b/mail/folder-browser.c
index a796063540..b50fae4a5d 100644
--- a/mail/folder-browser.c
+++ b/mail/folder-browser.c
@@ -15,6 +15,7 @@
#include <ctype.h>
#include <gdk/gdkkeysyms.h>
+#include <gtk/gtkinvisible.h>
#include <gal/e-paned/e-vpaned.h>
#include <gal/e-table/e-table.h>
#include <gal/util/e-util.h>
@@ -72,6 +73,10 @@ static GtkTargetEntry drag_types[] = {
static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
+static GdkAtom clipboard_atom = GDK_NONE;
+static GByteArray *clipboard_selection = NULL;
+static GtkWidget *invisible = NULL;
+
static void fb_resize_cb (GtkWidget *w, GtkAllocation *a);
static void update_unread_count (CamelObject *, gpointer, gpointer);
@@ -86,6 +91,13 @@ enum {
static guint folder_browser_signals [LAST_SIGNAL] = {0, };
static void
+invisible_destroyed (GtkObject *invisible)
+{
+ g_byte_array_free (clipboard_selection, TRUE);
+ clipboard_selection = NULL;
+}
+
+static void
folder_browser_destroy (GtkObject *object)
{
FolderBrowser *folder_browser;
@@ -106,7 +118,7 @@ folder_browser_destroy (GtkObject *object)
if (folder_browser->folder) {
CamelObject *folder = CAMEL_OBJECT (folder_browser->folder);
EvolutionStorage *storage;
-
+
if ((storage = mail_lookup_storage (folder_browser->folder->parent_store))) {
gtk_object_unref (GTK_OBJECT (storage));
camel_object_unhook_event (folder, "message_changed",
@@ -116,7 +128,7 @@ folder_browser_destroy (GtkObject *object)
update_unread_count,
folder_browser);
}
-
+
mail_sync_folder (folder_browser->folder, NULL, NULL);
camel_object_unref (folder);
}
@@ -133,12 +145,14 @@ folder_browser_destroy (GtkObject *object)
gtk_object_unref (GTK_OBJECT (folder_browser->view_collection));
folder_browser->view_collection = NULL;
}
-
+
if (folder_browser->view_menus) {
gtk_object_unref (GTK_OBJECT (folder_browser->view_menus));
folder_browser->view_menus = NULL;
}
-
+
+ gtk_object_unref (GTK_OBJECT (invisible));
+
folder_browser_parent_class->destroy (object);
}
@@ -166,6 +180,10 @@ folder_browser_class_init (GtkObjectClass *object_class)
GTK_TYPE_NONE, 1, GTK_TYPE_STRING);
gtk_object_class_add_signals (object_class, folder_browser_signals, LAST_SIGNAL);
+
+ /* clipboard atom */
+ if (!clipboard_atom)
+ clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
}
static void
@@ -175,14 +193,14 @@ update_unread_count_main(CamelObject *object, gpointer event_data, gpointer user
FolderBrowser *fb = user_data;
EvolutionStorage *storage;
char *name;
-
+
storage = mail_lookup_storage (folder->parent_store);
-
+
if (fb->unread_count == 0)
name = g_strdup (camel_folder_get_name (folder));
else
name = g_strdup_printf ("%s (%d)", camel_folder_get_name (folder), fb->unread_count);
-
+
evolution_storage_update_folder_by_uri (storage, fb->uri, name, fb->unread_count != 0);
g_free (name);
gtk_object_unref (GTK_OBJECT (storage));
@@ -194,7 +212,7 @@ update_unread_count (CamelObject *object, gpointer event_data, gpointer user_dat
CamelFolder *folder = (CamelFolder *)object;
FolderBrowser *fb = user_data;
int unread;
-
+
unread = camel_folder_get_unread_message_count (folder);
if (unread == fb->unread_count)
return;
@@ -362,6 +380,142 @@ message_list_drag_data_get (ETree *tree, int row, ETreePath path, int col,
}
static void
+selection_get (GtkWidget *widget, GtkSelectionData *selection_data,
+ guint info, guint time_stamp, FolderBrowser *fb)
+{
+ if (clipboard_selection != NULL) {
+ gtk_selection_data_set (selection_data,
+ GDK_SELECTION_TYPE_STRING,
+ 8,
+ clipboard_selection->data,
+ clipboard_selection->len);
+ }
+}
+
+static void
+selection_clear_event (GtkWidget *widget, GdkEventSelection *event, FolderBrowser *fb)
+{
+ if (clipboard_selection != NULL) {
+ g_byte_array_free (clipboard_selection, TRUE);
+ clipboard_selection = NULL;
+ }
+}
+
+static void
+selection_received (GtkWidget *widget, GtkSelectionData *selection_data,
+ guint time, FolderBrowser *fb)
+{
+ char *url, *name, *in, *inptr, *inend;
+ CamelFolder *source;
+ GPtrArray *uids;
+
+ /* format: "url folder_name uid1\0uid2\0uid3\0...\0uidn" */
+
+ in = selection_data->data;
+ inend = in + selection_data->length;
+
+ inptr = strchr (in, ' ');
+ url = g_strndup (in, inptr - in);
+
+ name = inptr + 1;
+ inptr = strchr (name, ' ');
+ name = g_strndup (name, inptr - name);
+
+ source = mail_tool_get_folder_from_urlname (url, name, 0, NULL);
+ g_free (name);
+ g_free (url);
+
+ if (!source)
+ return;
+
+ /* split the uids */
+ inptr++;
+ uids = g_ptr_array_new ();
+ while (inptr < inend) {
+ char *start = inptr;
+
+ while (inptr < inend && *inptr)
+ inptr++;
+
+ g_ptr_array_add (uids, g_strndup (start, inptr - start));
+ inptr++;
+ }
+
+ mail_do_transfer_messages (source, uids, FALSE, fb->uri);
+
+ camel_object_unref (CAMEL_OBJECT (source));
+}
+
+void
+folder_browser_copy (GtkWidget *menuitem, FolderBrowser *fb)
+{
+ GPtrArray *uids = NULL;
+ GByteArray *bytes;
+ gboolean cut;
+ char *url;
+ int i;
+
+ cut = menuitem == NULL;
+
+ if (clipboard_selection) {
+ g_byte_array_free (clipboard_selection, TRUE);
+ clipboard_selection = NULL;
+ }
+
+ uids = g_ptr_array_new ();
+ message_list_foreach (fb->message_list, add_uid, uids);
+
+ /* format: "url folder_name uid1\0uid2\0uid3\0...\0uidn" */
+
+ url = camel_url_to_string (CAMEL_SERVICE (camel_folder_get_parent_store (fb->folder))->url, 0);
+
+ /* write the url portion */
+ bytes = g_byte_array_new ();
+ g_byte_array_append (bytes, url, strlen (url));
+ g_byte_array_append (bytes, " ", 1);
+ g_free (url);
+
+ /* write the folder_name portion */
+ g_byte_array_append (bytes, fb->folder->name, strlen (fb->folder->name));
+ g_byte_array_append (bytes, " ", 1);
+
+ /* write the uids */
+ for (i = 0; i < uids->len; i++) {
+ if (cut) {
+ camel_folder_set_message_flags (fb->folder, uids->pdata[i],
+ CAMEL_MESSAGE_DELETED,
+ CAMEL_MESSAGE_DELETED);
+ }
+ g_byte_array_append (bytes, uids->pdata[i], strlen (uids->pdata[i]));
+ g_free (uids->pdata[i]);
+
+ if (i + 1 < uids->len)
+ g_byte_array_append (bytes, "", 1);
+ }
+
+ g_ptr_array_free (uids, TRUE);
+
+ clipboard_selection = bytes;
+
+ gtk_selection_owner_set (invisible, clipboard_atom, GDK_CURRENT_TIME);
+}
+
+void
+folder_browser_cut (GtkWidget *menuitem, FolderBrowser *fb)
+{
+ folder_browser_copy (NULL, fb);
+}
+
+void
+folder_browser_paste (GtkWidget *menuitem, FolderBrowser *fb)
+{
+ gtk_selection_convert (invisible,
+ clipboard_atom,
+ GDK_SELECTION_TYPE_STRING,
+ GDK_CURRENT_TIME);
+}
+
+static void
got_folder(char *uri, CamelFolder *folder, void *data)
{
FolderBrowser *fb = data;
@@ -1346,35 +1500,35 @@ static void
my_folder_browser_init (GtkObject *object)
{
FolderBrowser *fb = FOLDER_BROWSER (object);
-
+
fb->view_collection = NULL;
fb->view_menus = NULL;
-
+
/*
* Setup parent class fields.
*/
GTK_TABLE (fb)->homogeneous = FALSE;
gtk_table_resize (GTK_TABLE (fb), 1, 2);
-
+
/*
* Our instance data
*/
fb->message_list = (MessageList *)message_list_new ();
fb->mail_display = (MailDisplay *)mail_display_new ();
-
+
e_scroll_frame_set_policy(E_SCROLL_FRAME(fb->message_list),
GTK_POLICY_NEVER,
GTK_POLICY_ALWAYS);
gtk_signal_connect (GTK_OBJECT (fb->mail_display->html),
"key_press_event", GTK_SIGNAL_FUNC (on_key_press), fb);
-
+
gtk_signal_connect (GTK_OBJECT (fb->message_list->tree),
"key_press", GTK_SIGNAL_FUNC (etree_key), fb);
-
+
gtk_signal_connect (GTK_OBJECT (fb->message_list->tree),
"right_click", GTK_SIGNAL_FUNC (on_right_click), fb);
-
+
gtk_signal_connect (GTK_OBJECT (fb->message_list->tree),
"double_click", GTK_SIGNAL_FUNC (on_double_click), fb);
@@ -1388,6 +1542,34 @@ my_folder_browser_init (GtkObject *object)
gtk_signal_connect (GTK_OBJECT (fb->message_list->tree), "tree_drag_data_get",
GTK_SIGNAL_FUNC (message_list_drag_data_get), fb);
+ /* cut, copy & paste */
+ if (!invisible) {
+ invisible = gtk_invisible_new ();
+
+ gtk_signal_connect (GTK_OBJECT (invisible), "destroy",
+ GTK_SIGNAL_FUNC (invisible_destroyed),
+ NULL);
+
+ gtk_selection_add_target (invisible,
+ clipboard_atom,
+ GDK_SELECTION_TYPE_STRING,
+ 0);
+ } else
+ gtk_object_ref (GTK_OBJECT (invisible));
+
+ gtk_signal_connect (GTK_OBJECT (invisible),
+ "selection_get",
+ GTK_SIGNAL_FUNC (selection_get),
+ (gpointer) fb);
+ gtk_signal_connect (GTK_OBJECT (invisible),
+ "selection_clear_event",
+ GTK_SIGNAL_FUNC (selection_clear_event),
+ (gpointer) fb);
+ gtk_signal_connect (GTK_OBJECT (invisible),
+ "selection_received",
+ GTK_SIGNAL_FUNC (selection_received),
+ (gpointer) fb);
+
folder_browser_gui_init (fb);
}
@@ -1396,7 +1578,7 @@ folder_browser_new (const GNOME_Evolution_Shell shell)
{
CORBA_Environment ev;
FolderBrowser *folder_browser;
-
+
CORBA_exception_init (&ev);
folder_browser = gtk_type_new (folder_browser_get_type ());
diff --git a/mail/folder-browser.h b/mail/folder-browser.h
index ac6aef90f9..4372d8cc22 100644
--- a/mail/folder-browser.h
+++ b/mail/folder-browser.h
@@ -91,6 +91,10 @@ void folder_browser_set_message_preview (FolderBrowser *folder_br
gboolean show_message_preview);
void folder_browser_clear_search (FolderBrowser *fb);
+void folder_browser_cut (GtkWidget *widget, FolderBrowser *fb);
+void folder_browser_copy (GtkWidget *widget, FolderBrowser *fb);
+void folder_browser_paste (GtkWidget *widget, FolderBrowser *fb);
+
/* callbacks for functions on the folder-browser */
void vfolder_subject (GtkWidget *w, FolderBrowser *fb);
void vfolder_sender (GtkWidget *w, FolderBrowser *fb);