sync with 0.7.6cvs8
authorPaul Mangan <paul@claws-mail.org>
Sat, 18 May 2002 15:22:17 +0000 (15:22 +0000)
committerPaul Mangan <paul@claws-mail.org>
Sat, 18 May 2002 15:22:17 +0000 (15:22 +0000)
ChangeLog
ChangeLog.claws
ChangeLog.jp
configure.in
src/addr_compl.c
src/mainwindow.c
src/mimeview.c
src/procmime.c
src/summaryview.c
src/summaryview.h
src/textview.c

index 8afc976..5d8b741 100644 (file)
--- 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
index 0fb3943..6e87ab1 100644 (file)
@@ -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
index 5739a14..87c43d3 100644 (file)
@@ -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(): ¥µ¥Ö¥Õ¥©¥ë¥À¤ò´Þ¤à¥Õ¥©¥ë¥À¤ò
index 20342e9..6f89d0f 100644 (file)
@@ -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
index ee1b621..0054989 100644 (file)
@@ -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(&quote, "\"", 1) < 0) return NULL;
        if (mbtowc(&lt, "<", 1) < 0) return NULL;
+       if (mbtowc(&gt, ">", 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;
        }
 
index e9dedba..f13fd52 100644 (file)
@@ -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"),     "<shift>V", toggle_expand_messageview_cb, 0, "<ToggleItem>"},
        {N_("/_View/---"),                      NULL, NULL, 0, "<Separator>"},
        {N_("/_View/_Sort"),                    NULL, NULL, 0, "<Branch>"},
-       {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, "<Separator>"},
        {N_("/_View/_Sort/_Attract by subject"),
                                                NULL, attract_by_subject_cb, 0, NULL},
-       {N_("/_View/Th_read view"),             "<control>T",        thread_cb, 0, "<ToggleItem>"},
+       {N_("/_View/Th_read view"),             "<control>T", thread_cb, 0, "<ToggleItem>"},
+       {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, "<ToggleItem>"},
        {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"),          "<control>U", view_source_cb, 0, NULL},
        {N_("/_View/Show all _header"),         "<control>H", show_all_header_cb, 0, "<ToggleItem>"},
        {N_("/_View/---"),                      NULL, NULL, 0, "<Separator>"},
-       {N_("/_View/_Update"),                  "<control><alt>U", update_summary_cb,  0, NULL},
+       {N_("/_View/_Update summary"),          "<control><alt>U", update_summary_cb,  0, NULL},
 
        {N_("/_Message"),                       NULL, NULL, 0, "<Branch>"},
        {N_("/_Message/Get new ma_il"),         "<control>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)
 {
index b10a455..d186a53 100644 (file)
@@ -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);
index 1866303..503466a 100644 (file)
@@ -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;
        }
index 88552f2..15ee1f1 100644 (file)
@@ -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) {
index 47c710e..71bbcf1 100644 (file)
@@ -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);
index f30c0d4..7e7ec51 100644 (file)
@@ -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)