diff options
-rw-r--r-- | mail/ChangeLog | 20 | ||||
-rw-r--r-- | mail/component-factory.c | 11 | ||||
-rw-r--r-- | mail/folder-browser.c | 162 | ||||
-rw-r--r-- | mail/message-list.c | 176 |
4 files changed, 220 insertions, 149 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index 40b7feeecf..19768f4c59 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,23 @@ +2001-07-06 Jeffrey Stedfast <fejj@ximian.com> + + * folder-browser.c (folder_browser_copy): Mark the messages as + Seen also. + (folder_browser_class_init): Create an atom type for + X-Evolution-Message selection type. + (my_folder_browser_init): Add our multiple selection types, one of + which is the default string type. + + * component-factory.c (destination_folder_handle_drop): Update to + use the new X-Evolution-Message type format. + + * folder-browser.c (selection_get): Convert the + X-Evolution-Message clipboard type to whatever format the target + wants. + (message_list_drag_data_get): Update because the + X-Evolution-Message type changed. + (folder_browser_copy): Same. + (x_evolution_message_parse): And here too. + 2001-07-06 Peter Williams <peterw@ximian.com> * mail-callbacks.c (composer_postpone_cb): Don't free the psd here -- diff --git a/mail/component-factory.c b/mail/component-factory.c index 66420e01fd..8e958d6443 100644 --- a/mail/component-factory.c +++ b/mail/component-factory.c @@ -368,7 +368,7 @@ destination_folder_handle_drop (EvolutionShellComponentDndDestinationFolder *fol const GNOME_Evolution_ShellComponentDnd_Data *data, gpointer user_data) { - char *url, *name, *in, *inptr, *inend; + char *url, *in, *inptr, *inend; gboolean retval = FALSE; CamelFolder *source; CamelStream *stream; @@ -442,7 +442,7 @@ destination_folder_handle_drop (EvolutionShellComponentDndDestinationFolder *fol camel_object_unref (CAMEL_OBJECT (source)); break; case ACCEPTED_DND_TYPE_X_EVOLUTION_MESSAGE: - /* format: "url folder_name uid1\0uid2\0uid3\0...\0uidn" */ + /* format: "uri uid1\0uid2\0uid3\0...\0uidn" */ in = data->bytes._buffer; inend = in + data->bytes._length; @@ -450,12 +450,7 @@ destination_folder_handle_drop (EvolutionShellComponentDndDestinationFolder *fol 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, &ex); - g_free (name); + source = mail_tool_uri_to_folder (url, &ex); g_free (url); if (!source) { 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", diff --git a/mail/message-list.c b/mail/message-list.c index a680463698..f5fb85c34a 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -2076,11 +2076,11 @@ message_list_set_search(MessageList *ml, const char *search) if (search == NULL || search[0] == '\0') if (ml->search == NULL || ml->search[0]=='\0') return; - - if (search != NULL && ml->search !=NULL && strcmp(search, ml->search)==0) + + if (search != NULL && ml->search != NULL && strcmp (search, ml->search) == 0) return; - - mail_regen_list(ml, search, NULL, NULL); + + mail_regen_list (ml, search, NULL, NULL); } /* returns the number of messages displayable *after* expression hiding has taken place */ @@ -2270,88 +2270,89 @@ struct _regen_list_msg { use vfolder to implement searches ??? */ -static void regen_list_regen(struct _mail_msg *mm) +static void +regen_list_regen (struct _mail_msg *mm) { struct _regen_list_msg *m = (struct _regen_list_msg *)mm; - int i; GPtrArray *uids, *uidnew, *showuids; CamelMessageInfo *info; - + int i; + if (m->search) - uids = camel_folder_search_by_expression(m->folder, m->search, &mm->ex); + uids = camel_folder_search_by_expression (m->folder, m->search, &mm->ex); else - uids = camel_folder_get_uids(m->folder); - - if (camel_exception_is_set(&mm->ex)) + uids = camel_folder_get_uids (m->folder); + + if (camel_exception_is_set (&mm->ex)) return; - + /* perform hiding */ if (m->hideexpr) { - uidnew = camel_folder_search_by_expression(m->ml->folder, m->hideexpr, &mm->ex); + uidnew = camel_folder_search_by_expression (m->ml->folder, m->hideexpr, &mm->ex); /* well, lets not abort just because this faileld ... */ - camel_exception_clear(&mm->ex); - + camel_exception_clear (&mm->ex); + if (uidnew) { MESSAGE_LIST_LOCK(m->ml, hide_lock); - + if (m->ml->hidden == NULL) { - m->ml->hidden = g_hash_table_new(g_str_hash, g_str_equal); - m->ml->hidden_pool = e_mempool_new(512, 256, E_MEMPOOL_ALIGN_BYTE); + m->ml->hidden = g_hash_table_new (g_str_hash, g_str_equal); + m->ml->hidden_pool = e_mempool_new (512, 256, E_MEMPOOL_ALIGN_BYTE); } - for (i=0;i<uidnew->len;i++) { - if (g_hash_table_lookup(m->ml->hidden, uidnew->pdata[i]) == 0) { - char *uid = e_mempool_strdup(m->ml->hidden_pool, uidnew->pdata[i]); - g_hash_table_insert(m->ml->hidden, uid, uid); + for (i = 0; i < uidnew->len; i++) { + if (g_hash_table_lookup (m->ml->hidden, uidnew->pdata[i]) == 0) { + char *uid = e_mempool_strdup (m->ml->hidden_pool, uidnew->pdata[i]); + g_hash_table_insert (m->ml->hidden, uid, uid); } } - + MESSAGE_LIST_UNLOCK(m->ml, hide_lock); - - camel_folder_search_free(m->ml->folder, uidnew); + + camel_folder_search_free (m->ml->folder, uidnew); } } - + MESSAGE_LIST_LOCK(m->ml, hide_lock); - + m->ml->hide_unhidden = uids->len; - + /* what semantics do we want from hide_before, hide_after? probably <0 means measure from the end of the list */ - + /* perform uid hiding */ if (m->ml->hidden || m->ml->hide_before != ML_HIDE_NONE_START || m->ml->hide_after != ML_HIDE_NONE_END) { int start, end; - uidnew = g_ptr_array_new(); - + uidnew = g_ptr_array_new (); + /* first, hide matches */ if (m->ml->hidden) { - for (i=0;i<uids->len;i++) { - if (g_hash_table_lookup(m->ml->hidden, uids->pdata[i]) == 0) - g_ptr_array_add(uidnew, uids->pdata[i]); + for (i = 0; i < uids->len; i++) { + if (g_hash_table_lookup (m->ml->hidden, uids->pdata[i]) == 0) + g_ptr_array_add (uidnew, uids->pdata[i]); } } - + /* then calculate the subrange visible and chop it out */ m->ml->hide_unhidden = uidnew->len; - + if (m->ml->hide_before != ML_HIDE_NONE_START || m->ml->hide_after != ML_HIDE_NONE_END) { - GPtrArray *uid2 = g_ptr_array_new(); - + GPtrArray *uid2 = g_ptr_array_new (); + start = m->ml->hide_before; if (start < 0) start += m->ml->hide_unhidden; end = m->ml->hide_after; if (end < 0) end += m->ml->hide_unhidden; - + start = MAX(start, 0); end = MIN(end, uidnew->len); - for (i=start;i<end;i++) { - g_ptr_array_add(uid2, uidnew->pdata[i]); + for (i = start; i < end; i++) { + g_ptr_array_add (uid2, uidnew->pdata[i]); } - - g_ptr_array_free(uidnew, TRUE); + + g_ptr_array_free (uidnew, TRUE); uidnew = uid2; } showuids = uidnew; @@ -2359,31 +2360,31 @@ static void regen_list_regen(struct _mail_msg *mm) uidnew = NULL; showuids = uids; } - + MESSAGE_LIST_UNLOCK(m->ml, hide_lock); - - m->summary = g_ptr_array_new(); - for (i=0;i<showuids->len;i++) { - info = camel_folder_get_message_info(m->folder, showuids->pdata[i]); + + m->summary = g_ptr_array_new (); + for (i = 0; i < showuids->len; i++) { + info = camel_folder_get_message_info (m->folder, showuids->pdata[i]); if (info) { /* FIXME: should this be taken account of in above processing? */ if (m->hidedel && (info->flags & CAMEL_MESSAGE_DELETED) != 0) - camel_folder_free_message_info(m->folder, info); + camel_folder_free_message_info (m->folder, info); else - g_ptr_array_add(m->summary, info); + g_ptr_array_add (m->summary, info); } } - + if (uidnew) - g_ptr_array_free(uidnew, TRUE); - + g_ptr_array_free (uidnew, TRUE); + if (m->search) - camel_folder_search_free(m->folder, uids); + camel_folder_search_free (m->folder, uids); else - camel_folder_free_uids(m->folder, uids); - + camel_folder_free_uids (m->folder, uids); + if (m->dotree) - m->tree = camel_folder_thread_messages_new_summary(m->summary); + m->tree = camel_folder_thread_messages_new_summary (m->summary); else m->tree = NULL; } @@ -2397,39 +2398,40 @@ regen_list_regened (struct _mail_msg *mm) return; if (m->dotree) - build_tree(m->ml, m->tree, m->changes); + build_tree (m->ml, m->tree, m->changes); else - build_flat(m->ml, m->summary, m->changes); + build_flat (m->ml, m->summary, m->changes); gtk_signal_emit (GTK_OBJECT (m->ml), message_list_signals[MESSAGE_LIST_BUILT]); } -static void regen_list_free(struct _mail_msg *mm) +static void +regen_list_free (struct _mail_msg *mm) { struct _regen_list_msg *m = (struct _regen_list_msg *)mm; int i; - + if (m->summary) { - for (i=0;i<m->summary->len;i++) - camel_folder_free_message_info(m->folder, m->summary->pdata[i]); - g_ptr_array_free(m->summary, TRUE); + for (i = 0; i < m->summary->len; i++) + camel_folder_free_message_info (m->folder, m->summary->pdata[i]); + g_ptr_array_free (m->summary, TRUE); } - + if (m->tree) - camel_folder_thread_messages_destroy(m->tree); - + camel_folder_thread_messages_destroy (m->tree); + if (m->ml->search && m->ml->search != m->search) - g_free(m->ml->search); + g_free (m->ml->search); m->ml->search = m->search; - - g_free(m->hideexpr); - - camel_object_unref((CamelObject *)m->folder); - + + g_free (m->hideexpr); + + camel_object_unref (CAMEL_OBJECT (m->folder)); + if (m->changes) - camel_folder_change_info_free(m->changes); - - gtk_object_unref((GtkObject *)m->ml); + camel_folder_change_info_free (m->changes); + + gtk_object_unref (GTK_OBJECT (m->ml)); } static struct _mail_msg_op regen_list_op = { @@ -2440,13 +2442,13 @@ static struct _mail_msg_op regen_list_op = { }; static void -mail_regen_list(MessageList *ml, const char *search, const char *hideexpr, CamelFolderChangeInfo *changes) +mail_regen_list (MessageList *ml, const char *search, const char *hideexpr, CamelFolderChangeInfo *changes) { struct _regen_list_msg *m; - + if (ml->folder == NULL) return; - + #ifndef BROKEN_ETREE /* this can sometimes crash,so ... */ @@ -2458,17 +2460,17 @@ mail_regen_list(MessageList *ml, const char *search, const char *hideexpr, Camel return; } #endif - - m = mail_msg_new(®en_list_op, NULL, sizeof(*m)); + + m = mail_msg_new (®en_list_op, NULL, sizeof (*m)); m->ml = ml; - m->search = g_strdup(search); - m->hideexpr = g_strdup(hideexpr); + m->search = g_strdup (search); + m->hideexpr = g_strdup (hideexpr); m->changes = changes; m->dotree = ml->threaded; m->hidedel = ml->hidedeleted; - gtk_object_ref((GtkObject *)ml); + gtk_object_ref (GTK_OBJECT (ml)); m->folder = ml->folder; - camel_object_ref((CamelObject *)m->folder); - - e_thread_put(mail_thread_new, (EMsg *)m); + camel_object_ref (CAMEL_OBJECT (m->folder)); + + e_thread_put (mail_thread_new, (EMsg *)m); } |