From: Paul Mangan Date: Sat, 18 May 2002 15:22:17 +0000 (+0000) Subject: sync with 0.7.6cvs8 X-Git-Tag: rel_0_7_7~68 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=d9a1109e4192737d1dab244d1b90f7f624baaa56 sync with 0.7.6cvs8 --- diff --git a/ChangeLog b/ChangeLog index 8afc97668..5d8b7419c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +2002-05-17 + + * src/mainwindow.c: added 'Expand/Collapse all threads' menu. + * src/summaryview.[ch]: + summary_expand_threads(), summary_collapse_threads(): new. + +2002-05-17 + + * src/mainwindow.c: Fixed the behavior of + '/View/Show or hide/Folder tree' and + '/View/Show or hide/Message view' toggle menu. + Removed '/View/Toggle summary view' menu and integrated the + function into '/View/Show or hide/Message view'. + main_window_set_widgets(): change the state of toggle menu items. + * src/prefs_common.c: prefs_keybind_apply_clicked(): updated menurc + strings. + +2002-05-16 + + * src/mimeview.c: mimeview_set_multipart_tree(): show single part + MIME contents other than text as children of message/rfc822 part. + * src/procmime.c: + procmime_mimeinfo_next(): modified for message/rfc822 part which + content-type is single part MIME. + procmime_scan_multipart_message(): fix for nested message/rfc822 + part. Corrected the size of the contents of message/rfc822. + * src/textview.c: textview_show_part(): extract the contents of + multipart/* and message/rfc822. Some code cleanups. + textview_add_parts(): new. It adds the all parts under a part to + textview. + textview_clear(): reset body_pos and cur_pos. + +2002-05-16 + + * src/addr_compl.c: modified so that it behaves better. + get_address_from_edit(): ignore comma inside of brackets. + completion_window_apply_selection(): new. Only apply the current + clist selection. + completion_window_accept_selection(): removed. + address_completion_complete_address_in_entry(): minor code cleanup. + don't replace address in entry here. + completion_window_select_row(): always apply clist selection to + entry. + completion_window_key_press(): don't apply selection here. + 2002-05-15 * src/imap.c: imap_create_folder(): keep trailing directory separator diff --git a/ChangeLog.claws b/ChangeLog.claws index 0fb39430a..6e87ab1f6 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,8 @@ +2002-05-18 [paul] 0.7.6claws3 + + * sync with 0.7.6cvs8 + see ChangeLog 2002-05-16 and 2002-05-17 + 2002-05-18 [melvin] 0.7.6claws2 * README.claws diff --git a/ChangeLog.jp b/ChangeLog.jp index 5739a147b..87c43d388 100644 --- a/ChangeLog.jp +++ b/ChangeLog.jp @@ -1,3 +1,46 @@ +2002-05-17 + + * src/mainwindow.c: ¡Ö¤¹¤Ù¤Æ¤Î¥¹¥ì¥Ã¥É¤òŸ³«/ÊĤ¸¤ë¡×¥á¥Ë¥å¡¼¤òÄɲᣠ+ * src/summaryview.[ch]: + summary_expand_threads(), summary_collapse_threads(): ¿·µ¬¡£ + +2002-05-17 + + * src/mainwindow.c: ¡Ö/ɽ¼¨/ɽ¼¨¡¦Èóɽ¼¨/¥Õ¥©¥ë¥À¥Ä¥ê¡¼¡×¤È + ¡Ö/ɽ¼¨/ɽ¼¨¡¦Èóɽ¼¨/¥á¥Ã¥»¡¼¥¸¥Ó¥å¡¼¡×¥È¥°¥ë¥á¥Ë¥å¡¼¤ÎµóÆ°¤ò½¤Àµ¡£ + ¡Ö/ɽ¼¨/¥µ¥Þ¥ê¥Ó¥å¡¼¤òÀÚÂءץá¥Ë¥å¡¼¤òºï½ü¤·¡¢¤½¤Îµ¡Ç½¤ò + ¡Ö/ɽ¼¨/ɽ¼¨¡¦Èóɽ¼¨/¥á¥Ã¥»¡¼¥¸¥Ó¥å¡¼¡×¤ËÅý¹ç¡£ + main_window_set_widgets(): ¥È¥°¥ë¥á¥Ë¥å¡¼¹àÌܤξõÂÖ¤òÊѹ¹¡£ + * src/prefs_common.c: prefs_keybind_apply_clicked(): menurc ʸ»úÎó¤ò + ¹¹¿·¡£ + +2002-05-16 + + * src/mimeview.c: mimeview_set_multipart_tree(): ¥Æ¥­¥¹¥È°Ê³°¤Î + ¥·¥ó¥°¥ë¥Ñ¡¼¥È MIME ¤ÎÆâÍƤò message/rfc822 ¤Î¥Ñ¡¼¥È¤Î»Ò¤È¤·¤Æɽ¼¨¡£ + * src/procmime.c: + procmime_mimeinfo_next(): content-type ¤¬¥·¥ó¥°¥ë¥Ñ¡¼¥È MIME ¤Î + message/rfc822 ¥Ñ¡¼¥È¤Î¤¿¤á¤Î½¤Àµ¡£ + procmime_scan_multipart_message(): Æþ¤ì»Ò¤Ë¤Ê¤Ã¤¿ message/rfc822 + ¥Ñ¡¼¥È¤Î½¤Àµ¡£ message/rfc822 ¤ÎÆâÍƤΥµ¥¤¥º¤òÄûÀµ¡£ + * src/textview.c: textview_show_part(): multipart/* ¤È message/rfc822 + ¤ÎÆâÍƤòŸ³«¡£¥³¡¼¥É¤ÎÀ°Íý¡£ + textview_add_parts(): ¿·µ¬¡£¤¢¤ë¥Ñ¡¼¥È°Ê²¼¤ÎÁ´¤Æ¤Î¥Ñ¡¼¥È¤ò textview + ¤ËÄɲ乤롣 + textview_clear(): body_pos ¤È cur_pos ¤ò¥ê¥»¥Ã¥È¡£ + +2002-05-16 + + * src/addr_compl.c: µóÆ°¤ò¸þ¾å¤µ¤»¤ë¤¿¤á¤Ë½¤Àµ¡£ + get_address_from_edit(): îì³ç¸ÌÃæ¤Î¥«¥ó¥Þ¤ò̵»ë¡£ + completion_window_apply_selection(): ¿·µ¬¡£¸½ºß¤Î clist ¤ÎÁªÂò¹Ô + ¤ÎŬÍѤΤ߹Ԥ¦¡£ + completion_window_accept_selection(): ºï½ü¡£ + address_completion_complete_address_in_entry(): ¾¯¤·¥³¡¼¥É¤òÀ°Íý¡£ + ¤³¤³¤Ç¥¨¥ó¥È¥êÃæ¤Î¥¢¥É¥ì¥¹¤òÃÖ´¹¤·¤Ê¤¤¡£ + completion_window_select_row(): clist ¤ÎÁªÂò¤ò¾ï¤ËŬÍÑ¡£ + completion_window_key_press(): ÁªÂò¤ò¤³¤³¤Ç¤ÏŬÍѤ·¤Ê¤¤¡£ + 2002-05-15 * src/imap.c: imap_create_folder(): ¥µ¥Ö¥Õ¥©¥ë¥À¤ò´Þ¤à¥Õ¥©¥ë¥À¤ò diff --git a/configure.in b/configure.in index 20342e98a..6f89d0fc3 100644 --- a/configure.in +++ b/configure.in @@ -8,7 +8,7 @@ MINOR_VERSION=7 MICRO_VERSION=6 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=claws2 +EXTRA_VERSION=claws3 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION dnl set $target diff --git a/src/addr_compl.c b/src/addr_compl.c index ee1b6219d..00549890a 100644 --- a/src/addr_compl.c +++ b/src/addr_compl.c @@ -223,12 +223,15 @@ gchar *get_address_from_edit(GtkEntry *entry, gint *start_pos) wchar_t rfc_mail_sep; wchar_t quote; wchar_t lt; + wchar_t gt; gboolean in_quote = FALSE; + gboolean in_bracket = FALSE; gchar *str; if (mbtowc(&rfc_mail_sep, ",", 1) < 0) return NULL; if (mbtowc("e, "\"", 1) < 0) return NULL; if (mbtowc(<, "<", 1) < 0) return NULL; + if (mbtowc(>, ">", 1) < 0) return NULL; edit_text = gtk_entry_get_text(entry); if (edit_text == NULL) return NULL; @@ -240,10 +243,16 @@ gchar *get_address_from_edit(GtkEntry *entry, gint *start_pos) /* scan for a separator. doesn't matter if walk points at null byte. */ for (wp = wtext + cur_pos; wp > wtext; wp--) { - if (!in_quote && *wp == rfc_mail_sep) - break; if (*wp == quote) in_quote ^= TRUE; + else if (!in_quote) { + if (!in_bracket && *wp == rfc_mail_sep) + break; + else if (*wp == gt) + in_bracket = TRUE; + else if (*wp == lt) + in_bracket = FALSE; + } } /* have something valid */ @@ -516,6 +525,7 @@ static void completion_window_advance_selection(GtkCList *clist, gboolean forwar gtk_clist_thaw(clist); } +#if 0 /* completion_window_accept_selection() - accepts the current selection in the * clist, and destroys the window */ static void completion_window_accept_selection(GtkWidget **window, @@ -523,7 +533,7 @@ static void completion_window_accept_selection(GtkWidget **window, GtkEntry *entry) { gchar *address = NULL, *text = NULL; - gint cursor_pos, row, col; + gint cursor_pos, row; g_return_if_fail(window != NULL); g_return_if_fail(*window != NULL); @@ -531,21 +541,39 @@ static void completion_window_accept_selection(GtkWidget **window, g_return_if_fail(entry != NULL); g_return_if_fail(clist->selection != NULL); - col = 0; - /* FIXME: I believe it's acceptable to access the selection member directly */ row = GPOINTER_TO_INT(clist->selection->data); /* we just need the cursor position */ address = get_address_from_edit(entry, &cursor_pos); - gtk_clist_get_text(clist, row, col, &text); + g_free(address); + gtk_clist_get_text(clist, row, 0, &text); replace_address_in_edit(entry, text, cursor_pos); - g_free(address); clear_completion_cache(); gtk_widget_destroy(*window); *window = NULL; } +#endif + +/* completion_window_apply_selection() - apply the current selection in the + * clist */ +static void completion_window_apply_selection(GtkCList *clist, GtkEntry *entry) +{ + gchar *address = NULL, *text = NULL; + gint cursor_pos, row; + + g_return_if_fail(clist != NULL); + g_return_if_fail(entry != NULL); + g_return_if_fail(clist->selection != NULL); + + row = GPOINTER_TO_INT(clist->selection->data); + + address = get_address_from_edit(entry, &cursor_pos); + g_free(address); + gtk_clist_get_text(clist, row, 0, &text); + replace_address_in_edit(entry, text, cursor_pos); +} /* should be called when creating the main window containing address * completion entries */ @@ -674,25 +702,26 @@ static gboolean address_completion_complete_address_in_entry(GtkEntry *entry, if (!GTK_WIDGET_HAS_FOCUS(entry)) return FALSE; /* get an address component from the cursor */ - if (0 != (address = get_address_from_edit(entry, &cursor_pos))) { - /* still something in the cache */ - if (is_completion_pending()) { - new = next ? get_next_complete_address() : - get_prev_complete_address(); - } else { - if (0 < (ncount = complete_address(address))) - new = get_next_complete_address(); - } + address = get_address_from_edit(entry, &cursor_pos); + if (!address) return FALSE; - if (new) { - /* prevent "change" signal */ - replace_address_in_edit(entry, new, cursor_pos); - g_free(new); - completed = TRUE; - } + /* still something in the cache */ + if (is_completion_pending()) { + new = next ? get_next_complete_address() : + get_prev_complete_address(); + } else { + if (0 < (ncount = complete_address(address))) + new = get_next_complete_address(); + } + + if (new) { + /* prevent "change" signal */ + /* replace_address_in_edit(entry, new, cursor_pos); */ + g_free(new); + completed = TRUE; + } - g_free(address); - } + g_free(address); return completed; } @@ -787,23 +816,6 @@ static void completion_window_select_row(GtkCList *clist, gint row, gint col, { GtkEntry *entry; - /* first check if it's anything but a mouse event. Mouse events - * accept the completion. Anything else is accepted by the - * completion_window_key_press() */ - if (!event) { - /* event == NULL if key press did the selection or just - * event emitted with signal_emit_XXX(). This seems to - * be the case for the gtk versions I have seen */ - return; - } - - /* however, a future version of GTK might pass the event type - * that triggered the select_row. since this event handler - * only wants mouse clicks, we check for that. */ - if (event->type != GDK_BUTTON_RELEASE) { - return; - } - g_return_if_fail(completion_window != NULL); g_return_if_fail(*completion_window != NULL); @@ -811,7 +823,14 @@ static void completion_window_select_row(GtkCList *clist, gint row, gint col, WINDOW_DATA_COMPL_ENTRY)); g_return_if_fail(entry != NULL); - completion_window_accept_selection(completion_window, clist, entry); + completion_window_apply_selection(clist, entry); + + if (!event || event->type != GDK_BUTTON_RELEASE) + return; + + clear_completion_cache(); + gtk_widget_destroy(*completion_window); + *completion_window = NULL; } /* completion_window_button_press() - check is mouse click is anywhere @@ -852,10 +871,10 @@ static gboolean completion_window_button_press(GtkWidget *widget, replace_address_in_edit(GTK_ENTRY(entry), prefix, cursor_pos); } + clear_completion_cache(); gtk_widget_destroy(*completion_window); *completion_window = NULL; - clear_completion_cache(); return TRUE; } @@ -903,9 +922,9 @@ static gboolean completion_window_key_press(GtkWidget *widget, /* look for presses that accept the selection */ if (event->keyval == GDK_Return || event->keyval == GDK_space) { - completion_window_accept_selection(completion_window, - GTK_CLIST(clist), - GTK_ENTRY(entry)); + clear_completion_cache(); + gtk_widget_destroy(*completion_window); + *completion_window = NULL; return FALSE; } diff --git a/src/mainwindow.c b/src/mainwindow.c index e9dedbad7..f13fd52a7 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -180,9 +180,15 @@ static void ac_label_button_pressed (GtkWidget *widget, static void ac_menu_popup_closed (GtkMenuShell *menu_shell, gpointer data); -static gint main_window_close_cb (GtkWidget *widget, - GdkEventAny *event, - gpointer data); +static gint main_window_close_cb (GtkWidget *widget, + GdkEventAny *event, + gpointer data); +static gint folder_window_close_cb (GtkWidget *widget, + GdkEventAny *event, + gpointer data); +static gint message_window_close_cb (GtkWidget *widget, + GdkEventAny *event, + gpointer data); static void add_mailbox_cb (MainWindow *mainwin, guint action, @@ -343,6 +349,13 @@ static void hide_read_messages (MainWindow *mainwin, static void thread_cb (MainWindow *mainwin, guint action, GtkWidget *widget); +static void expand_threads_cb (MainWindow *mainwin, + guint action, + GtkWidget *widget); +static void collapse_threads_cb (MainWindow *mainwin, + guint action, + GtkWidget *widget); + static void set_display_item_cb (MainWindow *mainwin, guint action, GtkWidget *widget); @@ -525,21 +538,23 @@ static GtkItemFactoryEntry mainwin_entries[] = {N_("/_View/Ex_pand Message View"), "V", toggle_expand_messageview_cb, 0, ""}, {N_("/_View/---"), NULL, NULL, 0, ""}, {N_("/_View/_Sort"), NULL, NULL, 0, ""}, - {N_("/_View/_Sort/Sort by _number"), NULL, sort_summary_cb, SORT_BY_NUMBER, NULL}, - {N_("/_View/_Sort/Sort by s_ize"), NULL, sort_summary_cb, SORT_BY_SIZE, NULL}, - {N_("/_View/_Sort/Sort by _date"), NULL, sort_summary_cb, SORT_BY_DATE, NULL}, - {N_("/_View/_Sort/Sort by _from"), NULL, sort_summary_cb, SORT_BY_FROM, NULL}, - {N_("/_View/_Sort/Sort by _subject"), NULL, sort_summary_cb, SORT_BY_SUBJECT, NULL}, - {N_("/_View/_Sort/Sort by _color label"), + {N_("/_View/_Sort/by _number"), NULL, sort_summary_cb, SORT_BY_NUMBER, NULL}, + {N_("/_View/_Sort/by s_ize"), NULL, sort_summary_cb, SORT_BY_SIZE, NULL}, + {N_("/_View/_Sort/by _date"), NULL, sort_summary_cb, SORT_BY_DATE, NULL}, + {N_("/_View/_Sort/by _from"), NULL, sort_summary_cb, SORT_BY_FROM, NULL}, + {N_("/_View/_Sort/by _subject"), NULL, sort_summary_cb, SORT_BY_SUBJECT, NULL}, + {N_("/_View/_Sort/by _color label"), NULL, sort_summary_cb, SORT_BY_LABEL, NULL}, - {N_("/_View/_Sort/Sort by _mark"), NULL, sort_summary_cb, SORT_BY_MARK, NULL}, - {N_("/_View/_Sort/Sort by _unread"), NULL, sort_summary_cb, SORT_BY_UNREAD, NULL}, - {N_("/_View/_Sort/Sort by a_ttachment"), + {N_("/_View/_Sort/by _mark"), NULL, sort_summary_cb, SORT_BY_MARK, NULL}, + {N_("/_View/_Sort/by _unread"), NULL, sort_summary_cb, SORT_BY_UNREAD, NULL}, + {N_("/_View/_Sort/by a_ttachment"), NULL, sort_summary_cb, SORT_BY_MIME, NULL}, {N_("/_View/_Sort/---"), NULL, NULL, 0, ""}, {N_("/_View/_Sort/_Attract by subject"), NULL, attract_by_subject_cb, 0, NULL}, - {N_("/_View/Th_read view"), "T", thread_cb, 0, ""}, + {N_("/_View/Th_read view"), "T", thread_cb, 0, ""}, + {N_("/_View/E_xpand all threads"), NULL, expand_threads_cb, 0, NULL}, + {N_("/_View/Co_llapse all threads"), NULL, collapse_threads_cb, 0, NULL}, {N_("/_View/_Hide read messages"), NULL, hide_read_messages, 0, ""}, {N_("/_View/Set display _item..."), NULL, set_display_item_cb, 0, NULL}, @@ -651,7 +666,7 @@ static GtkItemFactoryEntry mainwin_entries[] = {N_("/_View/Mess_age source"), "U", view_source_cb, 0, NULL}, {N_("/_View/Show all _header"), "H", show_all_header_cb, 0, ""}, {N_("/_View/---"), NULL, NULL, 0, ""}, - {N_("/_View/_Update"), "U", update_summary_cb, 0, NULL}, + {N_("/_View/_Update summary"), "U", update_summary_cb, 0, NULL}, {N_("/_Message"), NULL, NULL, 0, ""}, {N_("/_Message/Get new ma_il"), "I", inc_mail_cb, 0, NULL}, @@ -1272,6 +1287,9 @@ void main_window_separation_change(MainWindow *mainwin, SeparateType type) GtkWidget *summary_wid = GTK_WIDGET_PTR(mainwin->summaryview); GtkWidget *message_wid = GTK_WIDGET_PTR(mainwin->messageview); + debug_print(_("Changing window separation type from %d to %d\n"), + mainwin->type, type); + if (mainwin->type == type) return; /* remove widgets from those containers */ @@ -1627,6 +1645,8 @@ void main_window_set_menu_sensitive(MainWindow *mainwin) {"/Edit/Select thread" , M_SINGLE_TARGET_EXIST}, {"/View/Sort" , M_MSG_EXIST}, {"/View/Thread view" , M_EXEC}, + {"/View/Expand all threads" , M_MSG_EXIST}, + {"/View/Collapse all threads" , M_MSG_EXIST}, {"/View/Hide read messages" , M_HIDE_READ_MSG}, {"/View/Go to/Prev message" , M_MSG_EXIST}, {"/View/Go to/Next message" , M_MSG_EXIST}, @@ -1768,8 +1788,8 @@ static void main_window_set_widgets(MainWindow *mainwin, SeparateType type) gtk_container_set_border_width(GTK_CONTAINER(folderwin), BORDER_WIDTH); gtk_signal_connect(GTK_OBJECT(folderwin), "delete_event", - GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete), - NULL); + GTK_SIGNAL_FUNC(folder_window_close_cb), + mainwin); } if (type & SEPARATE_MESSAGE) { messagewin = gtk_window_new(GTK_WINDOW_TOPLEVEL); @@ -1787,8 +1807,8 @@ static void main_window_set_widgets(MainWindow *mainwin, SeparateType type) gtk_container_set_border_width(GTK_CONTAINER(messagewin), BORDER_WIDTH); gtk_signal_connect(GTK_OBJECT(messagewin), "delete_event", - GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete), - NULL); + GTK_SIGNAL_FUNC(message_window_close_cb), + mainwin); } switch (type) { @@ -1925,6 +1945,24 @@ static void main_window_set_widgets(MainWindow *mainwin, SeparateType type) mainwin->type = type; + ifactory = gtk_item_factory_from_widget(mainwin->menubar); + + menuitem = gtk_item_factory_get_item + (ifactory, "/View/Show or hide/Folder tree"); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE); + menuitem = gtk_item_factory_get_item + (ifactory, "/View/Show or hide/Message view"); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE); + + menuitem = gtk_item_factory_get_item + (ifactory, "/View/Separate folder tree"); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), + ((type & SEPARATE_FOLDER) != 0)); + menuitem = gtk_item_factory_get_item + (ifactory, "/View/Separate message view"); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), + ((type & SEPARATE_MESSAGE) != 0)); + debug_print(_("done.\n")); } @@ -2421,6 +2459,36 @@ static gint main_window_close_cb(GtkWidget *widget, GdkEventAny *event, return TRUE; } +static gint folder_window_close_cb(GtkWidget *widget, GdkEventAny *event, + gpointer data) +{ + MainWindow *mainwin = (MainWindow *)data; + GtkItemFactory *ifactory; + GtkWidget *menuitem; + + ifactory = gtk_item_factory_from_widget(mainwin->menubar); + menuitem = gtk_item_factory_get_item + (ifactory, "/View/Expand Summary View"); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), FALSE); + + return TRUE; +} + +static gint message_window_close_cb(GtkWidget *widget, GdkEventAny *event, + gpointer data) +{ + MainWindow *mainwin = (MainWindow *)data; + GtkItemFactory *ifactory; + GtkWidget *menuitem; + + ifactory = gtk_item_factory_from_widget(mainwin->menubar); + menuitem = gtk_item_factory_get_item + (ifactory, "/View/Expand Message View"); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), FALSE); + + return TRUE; +} + static void add_mailbox_cb(MainWindow *mainwin, guint action, GtkWidget *widget) { @@ -2509,18 +2577,28 @@ static void search_cb(MainWindow *mainwin, guint action, GtkWidget *widget) static void toggle_folder_cb(MainWindow *mainwin, guint action, GtkWidget *widget) { + gboolean active; + + active = GTK_CHECK_MENU_ITEM(widget)->active; + switch (mainwin->type) { case SEPARATE_NONE: case SEPARATE_MESSAGE: +#if 0 + if (active) + gtk_widget_show(GTK_WIDGET_PTR(mainwin->folderview)); + else + gtk_widget_hide(GTK_WIDGET_PTR(mainwin->folderview)); +#endif break; case SEPARATE_FOLDER: - if (GTK_CHECK_MENU_ITEM(widget)->active) + if (active) gtk_widget_show(mainwin->win.sep_folder.folderwin); else gtk_widget_hide(mainwin->win.sep_folder.folderwin); break; case SEPARATE_BOTH: - if (GTK_CHECK_MENU_ITEM(widget)->active) + if (active) gtk_widget_show(mainwin->win.sep_both.folderwin); else gtk_widget_hide(mainwin->win.sep_both.folderwin); @@ -2531,18 +2609,22 @@ static void toggle_folder_cb(MainWindow *mainwin, guint action, static void toggle_message_cb(MainWindow *mainwin, guint action, GtkWidget *widget) { + gboolean active; + + active = GTK_CHECK_MENU_ITEM(widget)->active; + switch (mainwin->type) { case SEPARATE_NONE: case SEPARATE_FOLDER: break; case SEPARATE_MESSAGE: - if (GTK_CHECK_MENU_ITEM(widget)->active) + if (active) gtk_widget_show(mainwin->win.sep_message.messagewin); else gtk_widget_hide(mainwin->win.sep_message.messagewin); break; case SEPARATE_BOTH: - if (GTK_CHECK_MENU_ITEM(widget)->active) + if (active) gtk_widget_show(mainwin->win.sep_both.messagewin); else gtk_widget_hide(mainwin->win.sep_both.messagewin); @@ -2633,10 +2715,11 @@ static void separate_widget_cb(GtkCheckMenuItem *checkitem, guint action, GtkWid MainWindow *mainwin; SeparateType type; - mainwin = (MainWindow *) gtk_object_get_data(GTK_OBJECT(checkitem), "mainwindow"); - g_return_if_fail(mainwin != NULL); + if (GTK_CHECK_MENU_ITEM(widget)->active) + type = mainwin->type | action; + else + type = mainwin->type & ~action; - type = mainwin->type ^ action; main_window_separation_change(mainwin, type); prefs_common.sep_folder = (type & SEPARATE_FOLDER) != 0; @@ -2889,6 +2972,18 @@ static void thread_cb(MainWindow *mainwin, guint action, GtkWidget *widget) } } +static void expand_threads_cb(MainWindow *mainwin, guint action, + GtkWidget *widget) +{ + summary_expand_threads(mainwin->summaryview); +} + +static void collapse_threads_cb(MainWindow *mainwin, guint action, + GtkWidget *widget) +{ + summary_collapse_threads(mainwin->summaryview); +} + static void set_display_item_cb(MainWindow *mainwin, guint action, GtkWidget *widget) { diff --git a/src/mimeview.c b/src/mimeview.c index b10a4554c..d186a5396 100644 --- a/src/mimeview.c +++ b/src/mimeview.c @@ -361,6 +361,12 @@ static void mimeview_set_multipart_tree(MimeView *mimeview, if (!mimeinfo->sub && mimeinfo->parent) current = mimeview_append_part(mimeview, mimeinfo, parent); + if (mimeinfo->sub && !mimeinfo->sub->children && + mimeinfo->sub->mime_type != MIME_TEXT && + mimeinfo->sub->mime_type != MIME_TEXT_HTML) { + mimeview_append_part(mimeview, mimeinfo->sub, parent); + return; + } if (mimeinfo->sub) mimeview_set_multipart_tree(mimeview, mimeinfo->sub, current); diff --git a/src/procmime.c b/src/procmime.c index 186630393..503466a4a 100644 --- a/src/procmime.c +++ b/src/procmime.c @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 1999-2001 Hiroyuki Yamamoto + * Copyright (C) 1999-2002 Hiroyuki Yamamoto * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -168,6 +168,12 @@ MimeInfo *procmime_mimeinfo_next(MimeInfo *mimeinfo) if (mimeinfo->next) return mimeinfo->next; + if (mimeinfo->main) { + mimeinfo = mimeinfo->main; + if (mimeinfo->next) + return mimeinfo->next; + } + for (mimeinfo = mimeinfo->parent; mimeinfo != NULL; mimeinfo = mimeinfo->parent) { if (mimeinfo->next) @@ -244,12 +250,12 @@ void procmime_scan_multipart_message(MimeInfo *mimeinfo, FILE *fp) return; } - for (npart = 0;; npart++) { MimeInfo *partinfo; gboolean eom = FALSE; prev_fpos = fpos; + debug_print("prev_fpos: %ld\n", fpos); partinfo = procmime_scan_mime_header(fp); if (!partinfo) break; @@ -263,14 +269,20 @@ void procmime_scan_multipart_message(MimeInfo *mimeinfo, FILE *fp) partinfo->sub = sub = procmime_scan_mime_header(fp); if (!sub) break; + sub->level = partinfo->level + 1; sub->parent = partinfo->parent; sub->main = partinfo; - if (sub->mime_type == MIME_MULTIPART) { - if (sub->level < 8) + if (sub->level < 8) { + if (sub->mime_type == MIME_MULTIPART) { procmime_scan_multipart_message (sub, fp); + } else if (sub->mime_type == MIME_MESSAGE_RFC822) { + fseek(fp, sub->fpos, SEEK_SET); + procmime_scan_multipart_message + (sub, fp); + } } } @@ -284,11 +296,23 @@ void procmime_scan_multipart_message(MimeInfo *mimeinfo, FILE *fp) break; } } - if (p == NULL) - eom = TRUE; /* broken MIME message */ + if (p == NULL) { + /* broken MIME, or single part MIME message */ + buf[0] = '\0'; + eom = TRUE; + } fpos = ftell(fp); + debug_print("fpos: %ld\n", fpos); partinfo->size = fpos - prev_fpos - strlen(buf); + debug_print("partinfo->size: %d\n", partinfo->size); + if (partinfo->sub && !partinfo->sub->sub && + !partinfo->sub->children) { + partinfo->sub->size = fpos - partinfo->sub->fpos - strlen(buf); + debug_print("partinfo->sub->size: %d\n", + partinfo->sub->size); + } + debug_print("boundary: %s\n", buf); if (eom) break; } diff --git a/src/summaryview.c b/src/summaryview.c index 88552f2b2..15ee1f17d 100644 --- a/src/summaryview.c +++ b/src/summaryview.c @@ -3914,6 +3914,42 @@ void summary_processing(SummaryView *summaryview, GSList * mlist) summary_unlock(summaryview); } +void summary_expand_threads(SummaryView *summaryview) +{ + GtkCTree *ctree = GTK_CTREE(summaryview->ctree); + GtkCTreeNode *node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list); + + gtk_clist_freeze(GTK_CLIST(ctree)); + + while (node) { + if (GTK_CTREE_ROW(node)->children) + gtk_ctree_expand(ctree, node); + node = GTK_CTREE_NODE_NEXT(node); + } + + gtk_clist_thaw(GTK_CLIST(ctree)); + + gtk_ctree_node_moveto(ctree, summaryview->selected, -1, 0.5, 0); +} + +void summary_collapse_threads(SummaryView *summaryview) +{ + GtkCTree *ctree = GTK_CTREE(summaryview->ctree); + GtkCTreeNode *node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list); + + gtk_clist_freeze(GTK_CLIST(ctree)); + + while (node) { + if (GTK_CTREE_ROW(node)->children) + gtk_ctree_collapse(ctree, node); + node = GTK_CTREE_ROW(node)->sibling; + } + + gtk_clist_thaw(GTK_CLIST(ctree)); + + gtk_ctree_node_moveto(ctree, summaryview->selected, -1, 0.5, 0); +} + void summary_filter(SummaryView *summaryview) { if (!prefs_common.fltlist && !global_processing) { diff --git a/src/summaryview.h b/src/summaryview.h index 47c710e52..71bbcf147 100644 --- a/src/summaryview.h +++ b/src/summaryview.h @@ -197,6 +197,9 @@ void summary_select_node (SummaryView *summaryview, void summary_thread_build (SummaryView *summaryview); void summary_unthread (SummaryView *summaryview); +void summary_expand_threads (SummaryView *summaryview); +void summary_collapse_threads (SummaryView *summaryview); + void summary_filter (SummaryView *summaryview); void summary_filter_open (SummaryView *summaryview, PrefsFilterType type); diff --git a/src/textview.c b/src/textview.c index f30c0d46e..7e7ec51b9 100644 --- a/src/textview.c +++ b/src/textview.c @@ -115,6 +115,9 @@ static void textview_show_ertf (TextView *textview, static void textview_add_part (TextView *textview, MimeInfo *mimeinfo, FILE *fp); +static void textview_add_parts (TextView *textview, + MimeInfo *mimeinfo, + FILE *fp); static void textview_write_body (TextView *textview, MimeInfo *mimeinfo, FILE *fp, @@ -310,8 +313,6 @@ void textview_show_message(TextView *textview, MimeInfo *mimeinfo, charset = mimeinfo->charset; textview_set_font(textview, charset); textview_clear(textview); - textview->body_pos = 0; - textview->cur_pos = 0; gtk_stext_freeze(text); @@ -323,15 +324,7 @@ void textview_show_message(TextView *textview, MimeInfo *mimeinfo, textview->body_pos = gtk_stext_get_length(text); } - while (mimeinfo != NULL) { - textview_add_part(textview, mimeinfo, fp); - if (mimeinfo->parent && mimeinfo->parent->content_type && - !strcasecmp(mimeinfo->parent->content_type, - "multipart/alternative")) - mimeinfo = mimeinfo->parent->next; - else - mimeinfo = procmime_mimeinfo_next(mimeinfo); - } + textview_add_parts(textview, mimeinfo, fp); gtk_stext_thaw(text); @@ -350,7 +343,11 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp) g_return_if_fail(mimeinfo != NULL); g_return_if_fail(fp != NULL); - if (mimeinfo->mime_type == MIME_MULTIPART) return; + if (mimeinfo->mime_type == MIME_MULTIPART) { + textview_clear(textview); + textview_add_parts(textview, mimeinfo, fp); + return; + } if (mimeinfo->parent && mimeinfo->parent->boundary) { boundary = mimeinfo->parent->boundary; @@ -393,15 +390,12 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp) } /* display attached RFC822 single text message */ - if (mimeinfo->parent && mimeinfo->mime_type == MIME_MESSAGE_RFC822) { - if (headers) procheader_header_array_destroy(headers); - if (!mimeinfo->sub || mimeinfo->sub->children) return; - headers = textview_scan_header(textview, fp); - mimeinfo = mimeinfo->sub; - } else if (!mimeinfo->parent && - mimeinfo->mime_type == MIME_MESSAGE_RFC822) { + if (mimeinfo->mime_type == MIME_MESSAGE_RFC822) { if (headers) procheader_header_array_destroy(headers); - if (!mimeinfo->sub) return; + if (!mimeinfo->sub) { + textview_clear(textview); + return; + } headers = textview_scan_header(textview, fp); mimeinfo = mimeinfo->sub; } @@ -415,17 +409,18 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp) textview_clear(textview); gtk_stext_freeze(text); - textview->body_pos = 0; - textview->cur_pos = 0; - if (headers) { textview_show_header(textview, headers); - gtk_stext_insert(text, NULL, NULL, NULL, "\n", 1); procheader_header_array_destroy(headers); textview->body_pos = gtk_stext_get_length(text); + if (!mimeinfo->main) + gtk_stext_insert(text, NULL, NULL, NULL, "\n", 1); } - textview_write_body(textview, mimeinfo, fp, charset); + if (mimeinfo->mime_type == MIME_MULTIPART || mimeinfo->main) + textview_add_parts(textview, mimeinfo, fp); + else + textview_write_body(textview, mimeinfo, fp, charset); gtk_stext_thaw(text); } @@ -505,6 +500,28 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp) gtk_stext_thaw(text); } +static void textview_add_parts(TextView *textview, MimeInfo *mimeinfo, FILE *fp) +{ + gint level; + + g_return_if_fail(mimeinfo != NULL); + g_return_if_fail(fp != NULL); + + level = mimeinfo->level; + + for (;;) { + textview_add_part(textview, mimeinfo, fp); + if (mimeinfo->parent && mimeinfo->parent->content_type && + !strcasecmp(mimeinfo->parent->content_type, + "multipart/alternative")) + mimeinfo = mimeinfo->parent->next; + else + mimeinfo = procmime_mimeinfo_next(mimeinfo); + if (!mimeinfo || mimeinfo->level <= level) + break; + } +} + #define TEXT_INSERT(str) \ gtk_stext_insert(text, textview->msgfont, NULL, NULL, str, -1) @@ -1063,6 +1080,9 @@ void textview_clear(TextView *textview) textview_uri_list_remove_all(textview->uri_list); textview->uri_list = NULL; + + textview->body_pos = 0; + textview->cur_pos = 0; } void textview_destroy(TextView *textview)