aboutsummaryrefslogtreecommitdiffstats
path: root/mail/folder-browser.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/folder-browser.c')
-rw-r--r--mail/folder-browser.c162
1 files changed, 108 insertions, 54 deletions
diff --git a/mail/folder-browser.c b/mail/folder-browser.c
index db3a008f65..d1bf206ffa 100644
--- a/mail/folder-browser.c
+++ b/mail/folder-browser.c
@@ -58,17 +58,18 @@
#define PARENT_TYPE (gtk_table_get_type ())
+#define X_EVOLUTION_MESSAGE_TYPE "x-evolution-message"
+#define MESSAGE_RFC822_TYPE "message/rfc822"
+#define TEXT_URI_LIST_TYPE "text/uri-list"
+#define TEXT_PLAIN_TYPE "text/plain"
+/* Drag & Drop types */
enum DndTargetType {
DND_TARGET_TYPE_X_EVOLUTION_MESSAGE,
DND_TARGET_TYPE_MESSAGE_RFC822,
DND_TARGET_TYPE_TEXT_URI_LIST,
};
-#define X_EVOLUTION_MESSAGE_TYPE "x-evolution-message"
-#define MESSAGE_RFC822_TYPE "message/rfc822"
-#define TEXT_URI_LIST_TYPE "text/uri-list"
-
static GtkTargetEntry drag_types[] = {
{ X_EVOLUTION_MESSAGE_TYPE, 0, DND_TARGET_TYPE_X_EVOLUTION_MESSAGE },
{ MESSAGE_RFC822_TYPE, 0, DND_TARGET_TYPE_MESSAGE_RFC822 },
@@ -77,6 +78,18 @@ static GtkTargetEntry drag_types[] = {
static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
+enum PasteTargetType {
+ PASTE_TARGET_TYPE_X_EVOLUTION_MESSAGE,
+ PASTE_TARGET_TYPE_TEXT_PLAIN,
+};
+
+static GtkTargetPair paste_types[] = {
+ { 0, 0, PASTE_TARGET_TYPE_X_EVOLUTION_MESSAGE },
+ { GDK_SELECTION_TYPE_STRING, 0, PASTE_TARGET_TYPE_TEXT_PLAIN },
+};
+
+static const int num_paste_types = sizeof (paste_types) / sizeof (paste_types[0]);
+
static GdkAtom clipboard_atom = GDK_NONE;
static GtkObjectClass *folder_browser_parent_class;
@@ -168,6 +181,9 @@ folder_browser_class_init (GtkObjectClass *object_class)
/* clipboard atom */
if (!clipboard_atom)
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
+
+ if (!paste_types[0].target)
+ paste_types[0].target = gdk_atom_intern (X_EVOLUTION_MESSAGE_TYPE, FALSE);
}
static void
@@ -298,21 +314,12 @@ message_list_drag_data_get (ETree *tree, int row, ETreePath path, int col,
case DND_TARGET_TYPE_X_EVOLUTION_MESSAGE:
{
GByteArray *array;
- char *url;
- /* format: "url folder_name uid1\0uid2\0uid3\0...\0uidn" */
+ /* format: "uri uid1\0uid2\0uid3\0...\0uidn" */
- url = camel_url_to_string (CAMEL_SERVICE (camel_folder_get_parent_store (fb->folder))->url,
- CAMEL_URL_HIDE_PASSWORD | CAMEL_URL_HIDE_AUTH | CAMEL_URL_HIDE_AUTH);
-
- /* write the url portion */
+ /* write the uri portion */
array = g_byte_array_new ();
- g_byte_array_append (array, url, strlen (url));
- g_byte_array_append (array, " ", 1);
- g_free (url);
-
- /* write the folder_name portion */
- g_byte_array_append (array, fb->folder->name, strlen (fb->folder->name));
+ g_byte_array_append (array, fb->uri, strlen (fb->uri));
g_byte_array_append (array, " ", 1);
/* write the uids */
@@ -378,22 +385,20 @@ message_rfc822_dnd (CamelFolder *dest, CamelStream *stream, CamelException *ex)
static CamelFolder *
x_evolution_message_parse (char *in, unsigned int inlen, GPtrArray **uids)
{
- /* format: "url folder_name uid1\0uid2\0uid3\0...\0uidn" */
- char *inptr, *inend, *name, *url;
+ /* format: "uri uid1\0uid2\0uid3\0...\0uidn" */
+ char *inptr, *inend, *uri;
CamelFolder *folder;
+ if (in == NULL)
+ return NULL;
+
inend = in + inlen;
inptr = strchr (in, ' ');
- url = g_strndup (in, inptr - in);
+ uri = g_strndup (in, inptr - in);
- name = inptr + 1;
- inptr = strchr (name, ' ');
- name = g_strndup (name, inptr - name);
-
- folder = mail_tool_get_folder_from_urlname (url, name, 0, NULL);
- g_free (name);
- g_free (url);
+ folder = mail_tool_uri_to_folder (uri, NULL);
+ g_free (uri);
if (!folder)
return NULL;
@@ -501,12 +506,66 @@ static void
selection_get (GtkWidget *widget, GtkSelectionData *selection_data,
guint info, guint time_stamp, FolderBrowser *fb)
{
- if (fb->clipboard_selection != NULL) {
+ if (fb->clipboard_selection == NULL)
+ return;
+
+ switch (info) {
+ default:
+ case PASTE_TARGET_TYPE_TEXT_PLAIN:
+ {
+ /* FIXME: this'll be fucking slow for the user... pthread this? */
+ CamelFolder *source;
+ CamelStream *stream;
+ GByteArray *bytes;
+ GPtrArray *uids;
+ int i;
+
+ bytes = fb->clipboard_selection;
+
+ /* Note: source should == fb->folder, but we might as well use `source' instead of fb->folder */
+ source = x_evolution_message_parse (bytes->data, bytes->len, &uids);
+ if (source == NULL)
+ return;
+
+ if (uids == NULL) {
+ camel_object_unref (CAMEL_OBJECT (source));
+ return;
+ }
+
+ bytes = g_byte_array_new ();
+ stream = camel_stream_mem_new ();
+ camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (stream), bytes);
+
+ for (i = 0; i < uids->len; i++) {
+ CamelMimeMessage *message;
+
+ message = camel_folder_get_message (source, uids->pdata[i], NULL);
+ g_free (uids->pdata[i]);
+
+ if (message) {
+ camel_stream_write (stream, "From - \n", 8);
+ camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), stream);
+ camel_object_unref (CAMEL_OBJECT (message));
+ }
+ }
+
+ g_ptr_array_free (uids, TRUE);
+ camel_object_unref (CAMEL_OBJECT (stream));
+ camel_object_unref (CAMEL_OBJECT (source));
+
+ gtk_selection_data_set (selection_data, selection_data->target, 8,
+ bytes->data, bytes->len);
+
+ g_byte_array_free (bytes, FALSE);
+ }
+ break;
+ case PASTE_TARGET_TYPE_X_EVOLUTION_MESSAGE:
+ /* we already have our data in the correct form */
gtk_selection_data_set (selection_data,
- GDK_SELECTION_TYPE_STRING,
- 8,
+ selection_data->target, 8,
fb->clipboard_selection->data,
fb->clipboard_selection->len);
+ break;
}
}
@@ -526,6 +585,9 @@ selection_received (GtkWidget *widget, GtkSelectionData *selection_data,
CamelFolder *source = NULL;
GPtrArray *uids = NULL;
+ if (selection_data == NULL)
+ return;
+
source = x_evolution_message_parse (selection_data->data, selection_data->length, &uids);
if (source == NULL)
return;
@@ -546,7 +608,6 @@ folder_browser_copy (GtkWidget *menuitem, FolderBrowser *fb)
GPtrArray *uids = NULL;
GByteArray *bytes;
gboolean cut;
- char *url;
int i;
cut = menuitem == NULL;
@@ -559,27 +620,19 @@ folder_browser_copy (GtkWidget *menuitem, FolderBrowser *fb)
uids = g_ptr_array_new ();
message_list_foreach (fb->message_list, add_uid, uids);
- /* format: "url folder_name uid1\0uid2\0uid3\0...\0uidn" */
+ /* format: "uri uid1\0uid2\0uid3\0...\0uidn" */
- url = camel_url_to_string (CAMEL_SERVICE (camel_folder_get_parent_store (fb->folder))->url,
- CAMEL_URL_HIDE_PASSWORD | CAMEL_URL_HIDE_AUTH | CAMEL_URL_HIDE_PARAMS);
-
- /* write the url portion */
+ /* write the uri 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, fb->uri, strlen (fb->uri));
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);
+ CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED,
+ CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED);
}
g_byte_array_append (bytes, uids->pdata[i], strlen (uids->pdata[i]));
g_free (uids->pdata[i]);
@@ -604,9 +657,8 @@ folder_browser_cut (GtkWidget *menuitem, FolderBrowser *fb)
void
folder_browser_paste (GtkWidget *menuitem, FolderBrowser *fb)
{
- gtk_selection_convert (fb->invisible,
- clipboard_atom,
- GDK_SELECTION_TYPE_STRING,
+ gtk_selection_convert (fb->invisible, clipboard_atom,
+ paste_types[0].target,
GDK_CURRENT_TIME);
}
@@ -1611,7 +1663,8 @@ do_mark_seen (gpointer data)
/* callback when we have the message to display, after async loading it (see below) */
/* if we have pending uid's, it means another was selected before we finished displaying
the last one - so we cycle through and start loading the pending one immediately now */
-static void done_message_selected(CamelFolder *folder, char *uid, CamelMimeMessage *msg, void *data)
+static void
+done_message_selected (CamelFolder *folder, char *uid, CamelMimeMessage *msg, void *data)
{
FolderBrowser *fb = data;
int timeout = mail_config_get_mark_as_seen_timeout ();
@@ -1651,7 +1704,7 @@ static void done_message_selected(CamelFolder *folder, char *uid, CamelMimeMessa
/* ok we waited enough, display it anyway (see below) */
static gboolean
-do_message_selected(FolderBrowser *fb)
+do_message_selected (FolderBrowser *fb)
{
d(printf ("selecting uid %s (delayed)\n", fb->new_uid ? fb->new_uid : "NONE"));
@@ -1707,6 +1760,7 @@ static void
my_folder_browser_init (GtkObject *object)
{
FolderBrowser *fb = FOLDER_BROWSER (object);
+ int i;
fb->view_collection = NULL;
fb->view_menus = NULL;
@@ -1722,9 +1776,9 @@ my_folder_browser_init (GtkObject *object)
*/
fb->message_list = (MessageList *)message_list_new ();
fb->mail_display = (MailDisplay *)mail_display_new ();
-
+
fb->preview_shown = TRUE;
-
+
e_scroll_frame_set_policy(E_SCROLL_FRAME(fb->message_list),
GTK_POLICY_NEVER,
GTK_POLICY_ALWAYS);
@@ -1760,10 +1814,10 @@ my_folder_browser_init (GtkObject *object)
/* cut, copy & paste */
fb->invisible = gtk_invisible_new ();
- gtk_selection_add_target (fb->invisible,
- clipboard_atom,
- GDK_SELECTION_TYPE_STRING,
- 0);
+ for (i = 0; i < num_paste_types; i++)
+ gtk_selection_add_target (fb->invisible, clipboard_atom,
+ paste_types[i].target,
+ paste_types[i].info);
gtk_signal_connect (GTK_OBJECT (fb->invisible),
"selection_get",