2007-07-16 [colin] 2.10.0cvs30
authorColin Leroy <colin@colino.net>
Mon, 16 Jul 2007 17:13:43 +0000 (17:13 +0000)
committerColin Leroy <colin@colino.net>
Mon, 16 Jul 2007 17:13:43 +0000 (17:13 +0000)
* src/edittags.c
* src/edittags.h
* src/mainwindow.c
* src/summaryview.c
Improve the tag interface - allow
to set/unset tags from a special
window.
* src/gtk/gtkvscrollbutton.c
* src/mimeview.c
* src/mimeview.h
* src/stock_pixmap.c
Fix Mimeview's ugly hacks in the
icon list.

ChangeLog
PATCHSETS
configure.ac
src/edittags.c
src/edittags.h
src/gtk/gtkvscrollbutton.c
src/mainwindow.c
src/mimeview.c
src/mimeview.h
src/stock_pixmap.c
src/summaryview.c

index c30971b41d4c22667346f4efda9ecbcd685d2b86..47b9b019ae6d024bbd49763414339f5b7486c28c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2007-07-16 [colin]     2.10.0cvs30
+
+       * src/edittags.c
+       * src/edittags.h
+       * src/mainwindow.c
+       * src/summaryview.c
+               Improve the tag interface - allow
+               to set/unset tags from a special
+               window.
+       * src/gtk/gtkvscrollbutton.c
+       * src/mimeview.c
+       * src/mimeview.h
+       * src/stock_pixmap.c
+               Fix Mimeview's ugly hacks in the
+               icon list. 
+
 2007-07-16 [paul]      2.10.0cvs29
 
        * src/wizard.c
index 230c87acef2d27918fb0afa5da5340b0f3038ec5..d94ae780b2f85f2221c90c30ba1b4c22e18db691 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.83.2.109 -r 1.83.2.110 src/mimeview.c;  cvs diff -u -r 1.5.2.9 -r 1.5.2.10 src/gtk/gtkvscrollbutton.c;  ) > 2.10.0cvs27.patchset
 ( cvs diff -u -r 1.274.2.197 -r 1.274.2.198 src/mainwindow.c;  ) > 2.10.0cvs28.patchset
 ( cvs diff -u -r 1.1.2.54 -r 1.1.2.55 src/wizard.c;  cvs diff -u -r 1.1.2.14 -r 1.1.2.15 src/gtk/icon_legend.c;  ) > 2.10.0cvs29.patchset
+( cvs diff -u -r 1.1.2.2 -r 1.1.2.3 src/edittags.c;  cvs diff -u -r 1.1.2.2 -r 1.1.2.3 src/edittags.h;  cvs diff -u -r 1.274.2.198 -r 1.274.2.199 src/mainwindow.c;  cvs diff -u -r 1.83.2.110 -r 1.83.2.111 src/mimeview.c;  cvs diff -u -r 1.20.2.21 -r 1.20.2.22 src/mimeview.h;  cvs diff -u -r 1.25.2.41 -r 1.25.2.42 src/stock_pixmap.c;  cvs diff -u -r 1.395.2.311 -r 1.395.2.312 src/summaryview.c;  cvs diff -u -r 1.5.2.10 -r 1.5.2.11 src/gtk/gtkvscrollbutton.c;  ) > 2.10.0cvs30.patchset
index 99a4a7a91929357f9913fc17ce490c0cdc8fd8b7..bbcc07929ab6d87629f5e8eca4ecad7b0084577b 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=10
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=29
+EXTRA_VERSION=30
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 141020ab9723e7e8aff323f241c0d3628838d660..6ec316bfe46ad2d95be5b0e5aa79e298863cab59 100644 (file)
@@ -577,3 +577,366 @@ gint prefs_tags_create_new(MainWindow *mainwin)
        return id;
        
 }
+
+enum {
+       TAG_SELECTED,
+       TAG_SELECTED_INCONSISTENT,
+       TAG_NAME,
+       TAG_DATA,
+       N_TAG_EDIT_COLUMNS
+};
+
+static void apply_window_create(void);
+
+static struct TagApplyWindow
+{
+       GtkWidget *window;
+       GtkWidget *hbox1;
+       GtkWidget *vbox1;
+       GtkWidget *label;
+       GtkWidget *taglist;
+       GtkWidget *close_btn;
+       GtkWidget *add_entry;
+       GtkWidget *add_btn;
+       GSList *msglist;
+} applywindow;
+
+static void apply_window_load_tags (void);
+
+void tag_apply_open(GSList *msglist)
+{
+       g_return_if_fail(msglist);
+
+       if (!applywindow.window)
+               apply_window_create();
+
+       manage_window_set_transient(GTK_WINDOW(applywindow.window));
+       gtk_widget_grab_focus(applywindow.close_btn);
+       
+       applywindow.msglist = msglist;
+       apply_window_load_tags();
+
+       gtk_widget_show(applywindow.window);
+       gtk_widget_grab_focus(applywindow.taglist);
+       gtk_window_set_modal(GTK_WINDOW(applywindow.window), TRUE);
+}
+
+static GtkListStore* apply_window_create_data_store(void)
+{
+       return gtk_list_store_new(N_TAG_EDIT_COLUMNS,
+                                 G_TYPE_BOOLEAN,
+                                 G_TYPE_BOOLEAN,
+                                 G_TYPE_STRING,
+                                 G_TYPE_POINTER,
+                                 -1);
+}
+
+static void tag_apply_selected_toggled(GtkCellRendererToggle *widget,
+               gchar *path,
+               GtkWidget *list_view);
+
+static void apply_window_create_list_view_columns(GtkWidget *list_view)
+{
+       GtkTreeViewColumn *column;
+       GtkCellRenderer *renderer;
+
+       renderer = gtk_cell_renderer_toggle_new();
+       g_object_set(renderer,
+                    "radio", FALSE,
+                    "activatable", TRUE,
+                    NULL);
+       column = gtk_tree_view_column_new_with_attributes
+               (_(""),
+                renderer,
+                "active", TAG_SELECTED,
+                "inconsistent", TAG_SELECTED_INCONSISTENT,
+                NULL);
+       gtk_tree_view_column_set_alignment (column, 0.5);
+       gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);          
+       g_signal_connect(G_OBJECT(renderer), "toggled",
+                        G_CALLBACK(tag_apply_selected_toggled),
+                        list_view);
+
+       renderer = gtk_cell_renderer_text_new();
+       column = gtk_tree_view_column_new_with_attributes
+               (_("Tag"),
+                renderer,
+                "text", TAG_NAME,
+                NULL);
+       gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);
+       gtk_tree_view_column_set_resizable(column, TRUE);
+}
+
+static GtkWidget *apply_window_list_view_create        (void)
+{
+       GtkTreeView *list_view;
+       GtkTreeSelection *selector;
+       GtkTreeModel *model;
+
+       model = GTK_TREE_MODEL(apply_window_create_data_store());
+       list_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(model));
+       g_object_unref(model);  
+       
+       gtk_tree_view_set_rules_hint(list_view, prefs_common.use_stripes_everywhere);
+       
+       selector = gtk_tree_view_get_selection(list_view);
+       gtk_tree_selection_set_mode(selector, GTK_SELECTION_BROWSE);
+
+       /* create the columns */
+       apply_window_create_list_view_columns(GTK_WIDGET(list_view));
+
+       return GTK_WIDGET(list_view);
+
+}
+
+static void apply_window_close(void) 
+{
+       g_slist_free(applywindow.msglist);
+       applywindow.msglist = NULL;
+       gtk_widget_hide(applywindow.window);
+}
+
+static void apply_window_close_cb(GtkWidget *widget,
+                                gpointer data) 
+{
+       apply_window_close();
+}
+
+static void apply_window_list_view_insert_tag(GtkWidget *list_view,
+                                                 GtkTreeIter *row_iter,
+                                                 gint tag);
+
+static void apply_window_add_tag(void)
+{
+       gchar *new_tag = gtk_editable_get_chars(GTK_EDITABLE(applywindow.add_entry), 0, -1);
+       if (new_tag) {
+               gint id = tags_get_id_for_str(new_tag);
+               if (id == -1) {
+                       id = tags_add_tag(new_tag);
+                       tags_write_tags();
+                       if (mainwindow_get_mainwindow())
+                               summary_set_tag(
+                                       mainwindow_get_mainwindow()->summaryview, 
+                                       id, NULL);
+                       main_window_reflect_tags_changes(mainwindow_get_mainwindow());
+                       apply_window_list_view_insert_tag(applywindow.taglist, NULL, id);
+               }
+               g_free(new_tag);
+       }
+}
+
+static void apply_window_add_tag_cb(GtkWidget *widget,
+                                gpointer data) 
+{
+       apply_window_add_tag();
+}
+
+static gboolean apply_window_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+       if (event && event->keyval == GDK_Escape)
+               apply_window_close();
+       return FALSE;
+}
+
+static gboolean apply_window_add_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+       if (event && (event->keyval == GDK_KP_Enter || event->keyval == GDK_Return)) {
+               apply_window_add_tag();
+               gtk_entry_set_text(GTK_ENTRY(applywindow.add_entry), "");
+               gtk_widget_grab_focus(applywindow.taglist);
+       }
+               
+       return FALSE;
+}
+
+static void apply_window_create(void) 
+{
+       GtkWidget *window;
+       GtkWidget *hbox1;
+       GtkWidget *vbox1;
+       GtkWidget *label;
+       GtkWidget *taglist;
+       GtkWidget *close_btn;
+       GtkWidget *scrolledwin;
+       GtkWidget *new_tag_label;
+       GtkWidget *new_tag_entry;
+       GtkWidget *add_btn;
+
+       window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "tag_apply_window");
+       gtk_window_set_title (GTK_WINDOW(window),
+                             Q_("Dialog title|Apply tags"));
+
+       gtk_container_set_border_width (GTK_CONTAINER (window), 8);
+       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
+       gtk_window_set_resizable(GTK_WINDOW (window), TRUE);
+       g_signal_connect(G_OBJECT(window), "delete_event",
+                        G_CALLBACK(apply_window_close_cb), NULL);
+       g_signal_connect(G_OBJECT(window), "key_press_event",
+                        G_CALLBACK(apply_window_key_pressed), NULL);
+       MANAGE_WINDOW_SIGNALS_CONNECT (window);
+
+       vbox1 = gtk_vbox_new(FALSE, 6);
+       hbox1 = gtk_hbox_new(FALSE, 6);
+       
+       new_tag_label = gtk_label_new(_("New tag:"));
+       gtk_misc_set_alignment(GTK_MISC(new_tag_label), 0, 0.5);
+       gtk_box_pack_start(GTK_BOX(hbox1), new_tag_label, FALSE, FALSE, 0);
+       
+       new_tag_entry = gtk_entry_new();
+       gtk_box_pack_start(GTK_BOX(hbox1), new_tag_entry, FALSE, FALSE, 0);
+       g_signal_connect(G_OBJECT(new_tag_entry), "key_press_event",
+                        G_CALLBACK(apply_window_add_key_pressed), NULL);
+       
+       add_btn = gtk_button_new_from_stock(GTK_STOCK_ADD);
+       gtk_box_pack_start(GTK_BOX(hbox1), add_btn, FALSE, FALSE, 0);
+       
+       close_btn = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
+       gtk_box_pack_end(GTK_BOX(hbox1), close_btn, FALSE, FALSE, 0);
+
+       gtk_widget_show(new_tag_label);
+       gtk_widget_show(new_tag_entry);
+       gtk_widget_show(close_btn);
+       gtk_widget_show(add_btn);
+       g_signal_connect(G_OBJECT(close_btn), "clicked",
+                        G_CALLBACK(apply_window_close_cb), NULL);
+       g_signal_connect(G_OBJECT(add_btn), "clicked",
+                        G_CALLBACK(apply_window_add_tag_cb), NULL);
+
+       taglist = apply_window_list_view_create();
+       
+       label = gtk_label_new(_("Please select tags to apply/remove. Changes are immediate."));
+       gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+       gtk_box_pack_start(GTK_BOX(vbox1), label, FALSE, TRUE, 0);
+       
+       scrolledwin = gtk_scrolled_window_new(NULL, NULL);
+       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
+                                      GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+                                      
+       gtk_widget_set_size_request(scrolledwin, 500, 250);
+
+       gtk_container_add(GTK_CONTAINER(scrolledwin), taglist);
+       gtk_box_pack_start(GTK_BOX(vbox1), scrolledwin, TRUE, TRUE, 0);
+       gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 0);
+       
+       gtk_widget_show(label);
+       gtk_widget_show(scrolledwin);
+       gtk_widget_show(taglist);
+       gtk_widget_show(hbox1);
+       gtk_widget_show(vbox1);
+       gtk_widget_show(close_btn);
+       gtk_container_add(GTK_CONTAINER (window), vbox1);
+
+       applywindow.window = window;
+       applywindow.hbox1 = hbox1;
+       applywindow.vbox1 = vbox1;
+       applywindow.label = label;
+       applywindow.taglist = taglist;
+       applywindow.close_btn = close_btn;
+       applywindow.add_btn = add_btn;
+       applywindow.add_entry = new_tag_entry;
+}
+
+static void apply_window_list_view_clear_tags(GtkWidget *list_view)
+{
+       GtkListStore *list_store = GTK_LIST_STORE(gtk_tree_view_get_model
+                                       (GTK_TREE_VIEW(list_view)));
+       gtk_list_store_clear(list_store);
+}
+
+
+static void tag_apply_selected_toggled(GtkCellRendererToggle *widget,
+               gchar *path,
+               GtkWidget *list_view)
+{
+       GtkTreeIter iter;
+       GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list_view));
+       gboolean enabled = TRUE, set = FALSE;
+       gpointer tmp;
+       gint tag_id;
+       SummaryView *summaryview = NULL;
+       
+       if (mainwindow_get_mainwindow() != NULL)
+               summaryview = mainwindow_get_mainwindow()->summaryview;
+
+       if (!gtk_tree_model_get_iter_from_string(model, &iter, path))
+               return;
+
+       gtk_tree_model_get(model, &iter,
+                          TAG_SELECTED, &enabled,
+                          TAG_DATA, &tmp,
+                          -1);
+
+       set = !enabled;
+       tag_id = GPOINTER_TO_INT(tmp);
+
+       gtk_list_store_set(GTK_LIST_STORE(model), &iter,
+                          TAG_SELECTED, set,
+                          TAG_SELECTED_INCONSISTENT, FALSE,
+                          -1);
+       
+       if (summaryview)
+               summary_set_tag(summaryview, set ? tag_id : -tag_id, NULL);
+}
+
+static void apply_window_get_selected_state(gint tag, gboolean *selected, gboolean *selected_inconsistent)
+{
+       GSList *cur = applywindow.msglist;
+       gint num_mails = 0;
+       gint num_selected = 0;
+       for (; cur; cur = cur->next) {
+               MsgInfo *msginfo = (MsgInfo *)cur->data;
+               num_mails++;
+               if (msginfo->tags && g_slist_find(msginfo->tags, GINT_TO_POINTER(tag))) {
+                       *selected = TRUE;
+                       num_selected++;
+               }
+       }
+       if (num_selected > 0 && num_selected < num_mails)
+               *selected_inconsistent = TRUE;
+       else
+               *selected_inconsistent = FALSE;
+}
+
+static void apply_window_list_view_insert_tag(GtkWidget *list_view,
+                                                 GtkTreeIter *row_iter,
+                                                 gint tag) 
+{
+       GtkTreeIter iter;
+       GtkListStore *list_store = GTK_LIST_STORE(gtk_tree_view_get_model
+                                       (GTK_TREE_VIEW(list_view)));
+       const gchar *name = tags_get_tag(tag);
+       gboolean selected = FALSE, selected_inconsistent = FALSE;
+
+       apply_window_get_selected_state(tag, &selected, &selected_inconsistent);
+       if (row_iter == NULL) {
+               /* append new */
+               gtk_list_store_append(list_store, &iter);
+               gtk_list_store_set(list_store, &iter,
+                                  TAG_SELECTED, selected,
+                                  TAG_SELECTED_INCONSISTENT, selected_inconsistent,
+                                  TAG_NAME, name,
+                                  TAG_DATA, GINT_TO_POINTER(tag),
+                                  -1);
+       } else {
+               gtk_list_store_set(list_store, row_iter,
+                                  TAG_SELECTED, selected,
+                                  TAG_SELECTED_INCONSISTENT, selected_inconsistent,
+                                  TAG_NAME, name,
+                                  TAG_DATA, GINT_TO_POINTER(tag),
+                                  -1);
+       }
+}
+
+static void apply_window_load_tags (void) 
+{
+       GSList *cur;
+       GSList *tags = tags_get_list();
+       apply_window_list_view_clear_tags(applywindow.taglist);
+       
+       cur = tags;
+       for (; cur; cur = cur->next) {
+               gint id = GPOINTER_TO_INT(cur->data);
+               apply_window_list_view_insert_tag(applywindow.taglist, NULL, id);
+       }
+}
+
index 7b02d064b13e827fe9b7098c0643be9fa2809e3e..3d4fa30c8034215797ddc0234175ce493fba0a7e 100644 (file)
@@ -25,4 +25,5 @@
 void prefs_tags_open(MainWindow *mainwin);
 gint prefs_tags_create_new(MainWindow *mainwin);
 
+void tag_apply_open(GSList *msglist);
 #endif
index 9b495684a265bcc2d5d2b51b0dc5ae4ce520a4f4..005fed6af2407cbb71adf1b50eb81d6da0a0de35 100644 (file)
@@ -114,32 +114,72 @@ static void gtk_vscrollbutton_class_init(GtkVScrollbuttonClass *class)
 {
 }
 
+static GdkCursor *hand_cursor = NULL;
+
+static gboolean vscroll_visi_notify(GtkWidget *widget,
+                                      GdkEventVisibility *event,
+                                      gpointer data)
+{
+       gdk_window_set_cursor(widget->window, hand_cursor);
+       return FALSE;
+}
+
+static gboolean vscroll_leave_notify(GtkWidget *widget,
+                                     GdkEventCrossing *event,
+                                      gpointer data)
+{
+       gdk_window_set_cursor(widget->window, NULL);
+       return FALSE;
+}
+
+static gboolean vscroll_enter_notify(GtkWidget *widget,
+                                     GdkEventCrossing *event,
+                                      gpointer data)
+{
+       gdk_window_set_cursor(widget->window, hand_cursor);
+       return FALSE;
+}
+
+
 static void gtk_vscrollbutton_init(GtkVScrollbutton *scrollbutton)
 {
     GtkWidget *arrow;
-    scrollbutton->upbutton = gtk_button_new();
-    scrollbutton->downbutton = gtk_button_new();
+
+    if (!hand_cursor)
+           hand_cursor = gdk_cursor_new(GDK_HAND2);
+
+    scrollbutton->upbutton = gtk_event_box_new();
+    scrollbutton->downbutton = gtk_event_box_new();
     arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_NONE);
     gtk_widget_show(arrow);
     gtk_container_add(GTK_CONTAINER(scrollbutton->upbutton), arrow);
-#ifndef MAEMO
     gtk_widget_set_size_request(scrollbutton->upbutton, -1, 16);
-#else
-    gtk_widget_set_size_request(scrollbutton->upbutton, -1, arrow->requisition.height + 8);
-#endif
     arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
     gtk_widget_show(arrow);
     gtk_container_add(GTK_CONTAINER(scrollbutton->downbutton), arrow);
-#ifndef MAEMO
     gtk_widget_set_size_request(scrollbutton->downbutton, -1, 16);
-#else
-    gtk_widget_set_size_request(scrollbutton->downbutton, -1, arrow->requisition.height + 8);
-#endif
     GTK_WIDGET_UNSET_FLAGS(scrollbutton->upbutton, GTK_CAN_FOCUS);
     GTK_WIDGET_UNSET_FLAGS(scrollbutton->downbutton, GTK_CAN_FOCUS);
     gtk_widget_show(scrollbutton->downbutton);
     gtk_widget_show(scrollbutton->upbutton);
 
+    g_signal_connect(G_OBJECT(scrollbutton->upbutton), "visibility-notify-event",
+                    G_CALLBACK(vscroll_visi_notify), NULL);
+    g_signal_connect(G_OBJECT(scrollbutton->upbutton), "motion-notify-event",
+                    G_CALLBACK(vscroll_visi_notify), NULL);
+    g_signal_connect(G_OBJECT(scrollbutton->upbutton), "leave-notify-event",
+                    G_CALLBACK(vscroll_leave_notify), NULL);
+    g_signal_connect(G_OBJECT(scrollbutton->upbutton), "enter-notify-event",
+                    G_CALLBACK(vscroll_enter_notify), NULL);
+    g_signal_connect(G_OBJECT(scrollbutton->downbutton), "visibility-notify-event",
+                    G_CALLBACK(vscroll_visi_notify), NULL);
+    g_signal_connect(G_OBJECT(scrollbutton->downbutton), "motion-notify-event",
+                    G_CALLBACK(vscroll_visi_notify), NULL);
+    g_signal_connect(G_OBJECT(scrollbutton->downbutton), "leave-notify-event",
+                    G_CALLBACK(vscroll_leave_notify), NULL);
+    g_signal_connect(G_OBJECT(scrollbutton->downbutton), "enter-notify-event",
+                    G_CALLBACK(vscroll_enter_notify), NULL);
+
     g_signal_connect(G_OBJECT(scrollbutton->upbutton),
                       "button_press_event",
                       G_CALLBACK(gtk_vscrollbutton_button_press),
index 6fa82e6cec9708625dff4aac483678b9b82ef63c..c73ebf0109185e56bec781ff505cf5c6a5ba75ca 100644 (file)
@@ -1021,7 +1021,11 @@ static void mainwindow_tags_menu_item_activate_item_cb(GtkMenuItem *menu_item,
                                        g_direct_hash,
                                        g_direct_equal,
                                        NULL, NULL);
-
+       GHashTable *menu_allsel_table = g_hash_table_new_full(
+                                       g_direct_hash,
+                                       g_direct_equal,
+                                       NULL, NULL);
+       gint sel_len;
        mainwin = (MainWindow *)data;
        g_return_if_fail(mainwin != NULL);
 
@@ -1045,34 +1049,53 @@ static void mainwindow_tags_menu_item_activate_item_cb(GtkMenuItem *menu_item,
                                (GTK_CHECK_MENU_ITEM(cur->data), FALSE);
                                
                        g_hash_table_insert(menu_table, GINT_TO_POINTER(id), GTK_CHECK_MENU_ITEM(cur->data));
+                       g_hash_table_insert(menu_allsel_table, GINT_TO_POINTER(id), GINT_TO_POINTER(0));
                }
        }
 
        /* iterate all messages and set the state of the appropriate
         * items */
+       sel_len = 0;
        for (; sel != NULL; sel = sel->next) {
                MsgInfo *msginfo;
                GSList *tags = NULL;
                gint id;
                GtkCheckMenuItem *item;
                msginfo = (MsgInfo *)sel->data;
+               sel_len++;
                if (msginfo) {
                        tags =  msginfo->tags;
                        if (!tags)
                                continue;
 
                        for (; tags; tags = tags->next) {
+                               gint num_checked = GPOINTER_TO_INT(g_hash_table_lookup(menu_allsel_table, tags->data));
                                id = GPOINTER_TO_INT(tags->data);
                                item = g_hash_table_lookup(menu_table, GINT_TO_POINTER(tags->data));
-                               if (item && !item->active)
+                               if (item && !item->active) {
                                        gtk_check_menu_item_set_active
                                                (item, TRUE);
+                               }
+                               num_checked++;
+                               g_hash_table_replace(menu_allsel_table, tags->data, GINT_TO_POINTER(num_checked));
                        }
                }
        }
 
+       for (cur = menu->children; cur != NULL && cur->data != NULL; cur = cur->next) {
+               if (GTK_IS_CHECK_MENU_ITEM(cur->data)) {
+                       gint id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cur->data),
+                               "tag_id"));
+                       gint num_checked = GPOINTER_TO_INT(g_hash_table_lookup(menu_allsel_table, GINT_TO_POINTER(id)));
+                       if (num_checked < sel_len && num_checked > 0)
+                               gtk_check_menu_item_set_inconsistent(GTK_CHECK_MENU_ITEM(cur->data), TRUE);
+                       else
+                               gtk_check_menu_item_set_inconsistent(GTK_CHECK_MENU_ITEM(cur->data), FALSE);
+               }
+       }
        g_slist_free(sel);
        g_hash_table_destroy(menu_table);
+       g_hash_table_destroy(menu_allsel_table);
        /* reset "dont_toggle" state */
        g_object_set_data(G_OBJECT(menu), "dont_toggle",
                          GINT_TO_POINTER(0));
@@ -1158,11 +1181,11 @@ static void mainwindow_colorlabel_menu_create(MainWindow *mainwin, gboolean refr
        mainwin->colorlabel_menu = menu;
 }
 
-static void mainwindow_tags_menu_item_new_tag_activate_cb(GtkWidget *widget,
+static void mainwindow_tags_menu_item_apply_tags_activate_cb(GtkWidget *widget,
                                                     gpointer data)
 {
        MainWindow *mainwin;
-       gint id;
+
        mainwin = g_object_get_data(G_OBJECT(widget), "mainwin");
        g_return_if_fail(mainwin != NULL);
 
@@ -1171,11 +1194,7 @@ static void mainwindow_tags_menu_item_new_tag_activate_cb(GtkWidget *widget,
                                "dont_toggle"))
                return;
        
-       id = prefs_tags_create_new(mainwin);
-       if (id != -1) {
-               summary_set_tag(mainwin->summaryview, id, NULL);
-               main_window_reflect_tags_changes(mainwindow_get_mainwindow());
-       }
+       tag_apply_open(summary_get_selection(mainwin->summaryview));    
 }
 
 static void mainwindow_tags_menu_create(MainWindow *mainwin, gboolean refresh)
@@ -1220,14 +1239,20 @@ static void mainwindow_tags_menu_create(MainWindow *mainwin, gboolean refresh)
                gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
                gtk_widget_show(item);
        }
-       item = gtk_menu_item_new_with_label(_("New tag..."));
+
+       item = gtk_menu_item_new_with_label(_("Apply tags..."));
+       gtk_widget_add_accelerator(item, "activate", 
+                  mainwin->menu_factory->accel_group, 
+                  GDK_T, GDK_CONTROL_MASK|GDK_SHIFT_MASK,
+                  GTK_ACCEL_LOCKED | GTK_ACCEL_VISIBLE);
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
        g_signal_connect(G_OBJECT(item), "activate",
-                        G_CALLBACK(mainwindow_tags_menu_item_new_tag_activate_cb),
+                        G_CALLBACK(mainwindow_tags_menu_item_apply_tags_activate_cb),
                         NULL);
        g_object_set_data(G_OBJECT(item), "mainwin",
                          mainwin);
        gtk_widget_show(item);
+
        g_slist_free(orig);
        gtk_widget_show(menu);
        gtk_menu_item_set_submenu(GTK_MENU_ITEM(label_menuitem), menu);
@@ -3103,7 +3128,7 @@ static void main_window_set_widgets(MainWindow *mainwin, LayoutType layout_mode)
                gtk_widget_hide(GTK_WIDGET_PTR(mainwin->messageview->noticeview));
        if (!noticeview_is_visible(mainwin->messageview->mimeview->siginfoview)) 
                gtk_widget_hide(GTK_WIDGET_PTR(mainwin->messageview->mimeview->siginfoview));
-       if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mainwin->messageview->mimeview->mime_toggle)))
+       if (mainwin->messageview->mimeview->ctree_mode)
                gtk_widget_hide(mainwin->messageview->mimeview->icon_mainbox);
        else 
                gtk_widget_hide(mainwin->messageview->mimeview->ctree_mainbox);
index fcd27e9b187cfe190481a60d782cc005b0c35193..5eef45c03ecd80ed2c7b8397204ce52e5f8c56ad 100644 (file)
@@ -126,6 +126,7 @@ static void mimeview_open_part_with (MimeView       *mimeview,
                                         MimeInfo       *partinfo,
                                         gboolean        automatic);
 static void mimeview_select_next_part  (MimeView       *mimeview);
+static void mimeview_select_prev_part  (MimeView       *mimeview);
 static void mimeview_view_file         (const gchar    *filename,
                                         MimeInfo       *partinfo,
                                         const gchar    *cmd,
@@ -139,8 +140,6 @@ static void icon_selected               (MimeView       *mimeview,
 static gint icon_key_pressed            (GtkWidget      *button, 
                                         GdkEventKey    *event,
                                         MimeView       *mimeview);
-static void toggle_icon                        (GtkToggleButton *button,
-                                        MimeView       *mimeview);
 static void icon_list_append_icon      (MimeView       *mimeview, 
                                         MimeInfo       *mimeinfo);
 static void icon_list_create           (MimeView       *mimeview, 
@@ -148,10 +147,8 @@ static void icon_list_create               (MimeView       *mimeview,
 static void icon_list_clear            (MimeView       *mimeview);
 static void icon_list_toggle_by_mime_info (MimeView    *mimeview,
                                           MimeInfo     *mimeinfo);
-static gboolean icon_list_select_by_number(MimeView    *mimeview,
-                                          gint          number);
-static void mime_toggle_button_cb      (GtkWidget      *button,
-                                        MimeView       *mimeview);
+static gint mime_toggle_button_cb(GtkWidget *button, GdkEventButton *event,
+                                   MimeView *mimeview);
 static gboolean part_button_pressed    (MimeView       *mimeview, 
                                         GdkEventButton *event, 
                                         MimeInfo       *partinfo);
@@ -182,6 +179,32 @@ static GtkTargetEntry mimeview_mime_types[] =
 GSList *mimeviewer_factories;
 GSList *mimeviews;
 
+static GdkCursor *hand_cursor = NULL;
+
+static gboolean mimeview_visi_notify(GtkWidget *widget,
+                                      GdkEventVisibility *event,
+                                      MimeView *mimeview)
+{
+       gdk_window_set_cursor(widget->window, hand_cursor);
+       return FALSE;
+}
+
+static gboolean mimeview_leave_notify(GtkWidget *widget,
+                                     GdkEventCrossing *event,
+                                     MimeView *mimeview)
+{
+       gdk_window_set_cursor(widget->window, NULL);
+       return FALSE;
+}
+
+static gboolean mimeview_enter_notify(GtkWidget *widget,
+                                     GdkEventCrossing *event,
+                                     MimeView *mimeview)
+{
+       gdk_window_set_cursor(widget->window, hand_cursor);
+       return FALSE;
+}
+
 MimeView *mimeview_create(MainWindow *mainwin)
 {
        MimeView *mimeview;
@@ -207,6 +230,9 @@ MimeView *mimeview_create(MainWindow *mainwin)
        gint n_entries;
        gint i;
 
+       if (!hand_cursor)
+               hand_cursor = gdk_cursor_new(GDK_HAND2);
+
        debug_print("Creating MIME view...\n");
        mimeview = g_new0(MimeView, 1);
 
@@ -261,16 +287,30 @@ MimeView *mimeview_create(MainWindow *mainwin)
        g_signal_connect(G_OBJECT(icon_scroll), "scroll_event",
                         G_CALLBACK(mimeview_scrolled), mimeview);
 
-       mime_toggle = gtk_toggle_button_new();
+       mime_toggle = gtk_event_box_new();
+       gtk_event_box_set_visible_window(GTK_EVENT_BOX(mime_toggle), FALSE);
+
+       g_signal_connect(G_OBJECT(mime_toggle), "visibility-notify-event",
+                        G_CALLBACK(mimeview_visi_notify), mimeview);
+       g_signal_connect(G_OBJECT(mime_toggle), "motion-notify-event",
+                        G_CALLBACK(mimeview_visi_notify), mimeview);
+       g_signal_connect(G_OBJECT(mime_toggle), "leave-notify-event",
+                        G_CALLBACK(mimeview_leave_notify), mimeview);
+       g_signal_connect(G_OBJECT(mime_toggle), "enter-notify-event",
+                        G_CALLBACK(mimeview_enter_notify), mimeview);
+
+       gtk_container_set_border_width(GTK_CONTAINER(mime_toggle), 2);
        gtk_widget_show(mime_toggle);
+       mimeview->ctree_mode = FALSE;
        arrow = gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_NONE);
        gtk_widget_show(arrow);
        gtk_container_add(GTK_CONTAINER(mime_toggle), arrow);
-       g_signal_connect(G_OBJECT(mime_toggle), "toggled", 
+       g_signal_connect(G_OBJECT(mime_toggle), "button_release_event", 
                         G_CALLBACK(mime_toggle_button_cb), mimeview);
 
        icon_mainbox = gtk_vbox_new(FALSE, 0);
        gtk_widget_show(icon_mainbox);
+       gtk_widget_set_size_request(icon_mainbox, 32, -1);
        gtk_box_pack_start(GTK_BOX(icon_mainbox), mime_toggle, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX(icon_mainbox), icon_scroll, TRUE, TRUE, 3);
        gtk_box_pack_end(GTK_BOX(icon_mainbox), scrollbutton, FALSE, FALSE, 0);
@@ -1236,39 +1276,43 @@ void mimeview_pass_key_press_event(MimeView *mimeview, GdkEventKey *event)
 
 static void mimeview_select_next_part(MimeView *mimeview)
 {
-       gboolean is_next = FALSE;
+       GtkCTree *ctree = GTK_CTREE(mimeview->ctree);
+       GtkCTreeNode *node = mimeview->opened;
+       MimeInfo *partinfo = NULL;
+       
+skip:
+       node = GTK_CTREE_NODE_NEXT(node);
+       if (!node)
+               node = gtk_ctree_node_nth(GTK_CTREE(ctree), 0);
 
-       GList *child = gtk_container_children(GTK_CONTAINER(mimeview->icon_vbox));
-       for (; child != NULL; child = g_list_next(child)) {
-               if (GTK_IS_TOGGLE_BUTTON(child->data) &&  
-                   gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(child->data))) {
-                       is_next = TRUE;
-               } else if (GTK_IS_TOGGLE_BUTTON(child->data) &&
-                          is_next) {
-                       toggle_icon(GTK_TOGGLE_BUTTON(child->data), mimeview);
-                       gtk_toggle_button_set_active
-                               (GTK_TOGGLE_BUTTON(child->data), TRUE);
-                       icon_selected(mimeview, -1, 
-                               (MimeInfo *)g_object_get_data(G_OBJECT(child->data),
-                                     "partinfo"));
-                       is_next = FALSE;
-                       break;
-               }
+       if (node) {
+               partinfo = gtk_ctree_node_get_row_data(ctree, node);
+               if (partinfo->type == MIMETYPE_MULTIPART)
+                       goto skip;
+               gtk_sctree_unselect_all(GTK_SCTREE(ctree));
+               gtk_sctree_select(GTK_SCTREE(ctree), node);
+               icon_list_toggle_by_mime_info(mimeview, partinfo);
        }
-       if (is_next) {
-               /* we were on the last one, go to first */
-               child = gtk_container_children(GTK_CONTAINER(mimeview->icon_vbox));
-               for (; child != NULL; child = g_list_next(child)) {
-                       if (GTK_IS_TOGGLE_BUTTON(child->data)) {
-                               toggle_icon(GTK_TOGGLE_BUTTON(child->data), mimeview);
-                               gtk_toggle_button_set_active
-                                       (GTK_TOGGLE_BUTTON(child->data), TRUE);
-                               icon_selected(mimeview, -1, 
-                                       (MimeInfo *)g_object_get_data(G_OBJECT(child->data),
-                                               "partinfo"));
-                               break;
-                       }
-               }
+}
+
+static void mimeview_select_prev_part(MimeView *mimeview)
+{
+       GtkCTree *ctree = GTK_CTREE(mimeview->ctree);
+       GtkCTreeNode *node = mimeview->opened;
+       MimeInfo *partinfo = NULL;
+       
+skip:
+       node = GTK_CTREE_NODE_PREV(node);
+       if (!node)
+               node = gtk_ctree_node_nth(GTK_CTREE(ctree), GTK_CLIST(ctree)->rows - 1);
+
+       if (node) {
+               partinfo = gtk_ctree_node_get_row_data(ctree, node);
+               if (partinfo->type == MIMETYPE_MULTIPART)
+                       goto skip;
+               gtk_sctree_unselect_all(GTK_SCTREE(ctree));
+               gtk_sctree_select(GTK_SCTREE(ctree), node);
+               icon_list_toggle_by_mime_info(mimeview, partinfo);
        }
 }
 
@@ -1284,7 +1328,6 @@ static gint mimeview_key_pressed(GtkWidget *widget, GdkEventKey *event,
 {
        SummaryView *summaryview;
        GtkCTree *ctree = GTK_CTREE(widget);
-       GtkCTreeNode *node;
 
        if (!event) return FALSE;
        if (!mimeview->opened) return FALSE;
@@ -1299,13 +1342,9 @@ static gint mimeview_key_pressed(GtkWidget *widget, GdkEventKey *event,
                if (mimeview_scroll_page(mimeview, FALSE))
                        return TRUE;
 
-               node = GTK_CTREE_NODE_NEXT(mimeview->opened);
-               if (node) {
-                       gtk_sctree_unselect_all(GTK_SCTREE(ctree));
-                       gtk_sctree_select(GTK_SCTREE(ctree), node);
-                       return TRUE;
-               }
-               break;
+               mimeview_select_next_part(mimeview);
+               return TRUE;
+
        case GDK_BackSpace:
                mimeview_scroll_page(mimeview, TRUE);
                return TRUE;
@@ -1317,19 +1356,15 @@ static gint mimeview_key_pressed(GtkWidget *widget, GdkEventKey *event,
        case GDK_n:
        case GDK_N:
                BREAK_ON_MODIFIER_KEY();
-               if (!GTK_CTREE_NODE_NEXT(mimeview->opened)) break;
-               KEY_PRESS_EVENT_STOP();
-               g_signal_emit_by_name(G_OBJECT(ctree), "scroll_vertical",
-                                       GTK_SCROLL_STEP_FORWARD, 0.0);
+               mimeview_select_next_part(mimeview);
                return TRUE;
+
        case GDK_p:
        case GDK_P:
                BREAK_ON_MODIFIER_KEY();
-               if (!GTK_CTREE_NODE_PREV(mimeview->opened)) break;
-               KEY_PRESS_EVENT_STOP();
-               g_signal_emit_by_name(G_OBJECT(ctree), "scroll_vertical",
-                                       GTK_SCROLL_STEP_BACKWARD, 0.0);
+               mimeview_select_prev_part(mimeview);
                return TRUE;
+
        case GDK_y:
                BREAK_ON_MODIFIER_KEY();
                KEY_PRESS_EVENT_STOP();
@@ -1886,11 +1921,9 @@ static gboolean icon_clicked_cb (GtkWidget *button, GdkEventButton *event, MimeV
        if (event->button == 1) {
                icon_selected(mimeview, num, partinfo);
                gtk_widget_grab_focus(button);
-               if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
-                       toggle_icon(GTK_TOGGLE_BUTTON(button), mimeview);
-               }
        }
        part_button_pressed(mimeview, event, partinfo);
+       icon_list_toggle_by_mime_info(mimeview, partinfo);
 
        return FALSE;
 }
@@ -1910,11 +1943,6 @@ void mimeview_select_mimepart_icon(MimeView *mimeview, MimeInfo *partinfo)
        icon_selected(mimeview, -1, partinfo);
 }
 
-#undef  KEY_PRESS_EVENT_STOP
-#define KEY_PRESS_EVENT_STOP() \
-        g_signal_stop_emission_by_name(G_OBJECT(button), \
-                                       "key_press_event");
-
 static gint icon_key_pressed(GtkWidget *button, GdkEventKey *event,
                             MimeView *mimeview)
 {
@@ -1932,19 +1960,11 @@ static gint icon_key_pressed(GtkWidget *button, GdkEventKey *event,
 
        switch (event->keyval) {
        case GDK_space:
-               if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
-                       /* stop the button being untoggled */
-                       KEY_PRESS_EVENT_STOP();
-                       if (mimeview_scroll_page(mimeview, FALSE))
-                               return TRUE;
-
-                       if (icon_list_select_by_number(mimeview, num + 1))
-                               return TRUE;
-               } else {
-                       icon_selected(mimeview, num, partinfo);
-                       toggle_icon(GTK_TOGGLE_BUTTON(button), mimeview);
+               if (mimeview_scroll_page(mimeview, FALSE))
                        return TRUE;
-               }
+
+               mimeview_select_next_part(mimeview);
+               return TRUE;
 
                break;
        case GDK_BackSpace:
@@ -1952,63 +1972,44 @@ static gint icon_key_pressed(GtkWidget *button, GdkEventKey *event,
                return TRUE;
        case GDK_Return:
        case GDK_KP_Enter:
-               if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
-                       KEY_PRESS_EVENT_STOP();
-                       mimeview_scroll_one_line(mimeview,
-                                                (event->state & GDK_MOD1_MASK) != 0);
-                       return TRUE;
-               } else {
-                       icon_selected(mimeview, num, partinfo);
-                       toggle_icon(GTK_TOGGLE_BUTTON(button), mimeview);
-                       return TRUE;
-               }
+               mimeview_scroll_one_line(mimeview,
+                                        (event->state & GDK_MOD1_MASK) != 0);
+               return TRUE;
 
        case GDK_n:
        case GDK_N:
                BREAK_ON_MODIFIER_KEY();
-               if (icon_list_select_by_number(mimeview, num + 1)) {
-                       KEY_PRESS_EVENT_STOP();
-                       return TRUE;
-               }
-               break;
+               mimeview_select_next_part(mimeview);
+               return TRUE;
                
        case GDK_p:
        case GDK_P:
                BREAK_ON_MODIFIER_KEY();
-               if (icon_list_select_by_number(mimeview, num - 1)) {
-                       KEY_PRESS_EVENT_STOP();
-                       return TRUE;
-               }
+               mimeview_select_prev_part(mimeview);
                break;
 
        case GDK_y:
                BREAK_ON_MODIFIER_KEY();
-               KEY_PRESS_EVENT_STOP();
                mimeview_save_as(mimeview);
                return TRUE;
        case GDK_t:
                BREAK_ON_MODIFIER_KEY();
-               KEY_PRESS_EVENT_STOP();
                mimeview_display_as_text(mimeview);
                return TRUE;    
        case GDK_l:
                BREAK_ON_MODIFIER_KEY();
-               KEY_PRESS_EVENT_STOP();
                mimeview_launch(mimeview, NULL);
                return TRUE;
        case GDK_o:
                BREAK_ON_MODIFIER_KEY();
-               KEY_PRESS_EVENT_STOP();
                mimeview_open_with(mimeview);
                return TRUE;
        case GDK_c:
                BREAK_ON_MODIFIER_KEY();
-               KEY_PRESS_EVENT_STOP();
                mimeview_check_signature(mimeview);
                return TRUE;
        case GDK_a:
                BREAK_ON_MODIFIER_KEY();
-               KEY_PRESS_EVENT_STOP();
                mimeview_select_next_part(mimeview);
                return TRUE;
        default:
@@ -2020,21 +2021,6 @@ static gint icon_key_pressed(GtkWidget *button, GdkEventKey *event,
        return summary_pass_key_press_event(summaryview, event);
 }
 
-static void toggle_icon(GtkToggleButton *button, MimeView *mimeview)
-{
-       GList *child;
-       
-       child = gtk_container_get_children(GTK_CONTAINER(mimeview->icon_vbox));
-       for (; child != NULL; child = g_list_next(child)) {
-               if (GTK_IS_TOGGLE_BUTTON(child->data) && 
-                   GTK_TOGGLE_BUTTON(child->data) != button &&
-                   gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(child->data)))
-                       gtk_toggle_button_set_active
-                               (GTK_TOGGLE_BUTTON(child->data),
-                                FALSE);
-       }
-}
-
 static gboolean icon_popup_menu(GtkWidget *widget, gpointer data)
 {
        MimeView *mimeview = (MimeView *)data;
@@ -2065,8 +2051,18 @@ static void icon_list_append_icon (MimeView *mimeview, MimeInfo *mimeinfo)
        
        vbox = mimeview->icon_vbox;
        mimeview->icon_count++;
-       button = gtk_toggle_button_new();
-       gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+       button = gtk_event_box_new();
+
+       g_signal_connect(G_OBJECT(button), "visibility-notify-event",
+                        G_CALLBACK(mimeview_visi_notify), mimeview);
+       g_signal_connect(G_OBJECT(button), "motion-notify-event",
+                        G_CALLBACK(mimeview_visi_notify), mimeview);
+       g_signal_connect(G_OBJECT(button), "leave-notify-event",
+                        G_CALLBACK(mimeview_leave_notify), mimeview);
+       g_signal_connect(G_OBJECT(button), "enter-notify-event",
+                        G_CALLBACK(mimeview_enter_notify), mimeview);
+
+       gtk_container_set_border_width(GTK_CONTAINER(button), 2);
        g_object_set_data(G_OBJECT(button), "icon_number", 
                          GINT_TO_POINTER(mimeview->icon_count));
        g_object_set_data(G_OBJECT(button), "partinfo", 
@@ -2228,53 +2224,11 @@ static void icon_list_clear (MimeView *mimeview)
        gtk_adjustment_set_value(adj, adj->lower);
 }
 
-static void icon_list_toggle_by_mime_info(MimeView     *mimeview,
-                                         MimeInfo      *mimeinfo)
-{
-       GList *child;
-       
-       child = gtk_container_children(GTK_CONTAINER(mimeview->icon_vbox));
-       for (; child != NULL; child = g_list_next(child)) {
-               if (GTK_IS_TOGGLE_BUTTON(child->data) &&  
-                   g_object_get_data(G_OBJECT(child->data),
-                                     "partinfo") == (gpointer)mimeinfo) {
-                       toggle_icon(GTK_TOGGLE_BUTTON(child->data), mimeview);
-                       gtk_toggle_button_set_active
-                               (GTK_TOGGLE_BUTTON(child->data), TRUE); 
-               }                                
-       }
-}
-
 /*!
  *\brief        Used to 'click' the next or previous icon.
  *
  *\return       true if the icon 'number' exists and was selected.
  */
-static gboolean icon_list_select_by_number(MimeView    *mimeview,
-                                          gint          number)
-{
-       GList *child;
-
-       if (number == 0) return FALSE;
-       child = gtk_container_children(GTK_CONTAINER(mimeview->icon_vbox));
-       for (; child != NULL; child = g_list_next(child)) {
-               if (GTK_IS_TOGGLE_BUTTON(child->data) &&  
-                   GPOINTER_TO_INT(g_object_get_data(G_OBJECT(child->data),
-                                       "icon_number")) == number) {
-                       icon_selected(mimeview, number,
-                                     (MimeInfo*)g_object_get_data(G_OBJECT(child->data),
-                                                                  "partinfo"));
-                       toggle_icon(GTK_TOGGLE_BUTTON(child->data), mimeview);
-                       gtk_toggle_button_set_active
-                               (GTK_TOGGLE_BUTTON(child->data), TRUE);
-                       gtk_widget_grab_focus(GTK_WIDGET(child->data));
-               
-                       return TRUE;
-               }                                
-       }
-       return FALSE;
-}
-
 static void icon_scroll_size_allocate_cb(GtkWidget *widget, 
                                         GtkAllocation *size, MimeView *mimeview)
 {
@@ -2318,11 +2272,41 @@ static void icon_list_create(MimeView *mimeview, MimeInfo *mimeinfo)
        }
 }
 
-static void mime_toggle_button_cb (GtkWidget *button, MimeView *mimeview) 
+static void icon_list_toggle_by_mime_info (MimeView    *mimeview,
+                                          MimeInfo     *mimeinfo)
+{
+       GList *child;
+       
+       child = gtk_container_children(GTK_CONTAINER(mimeview->icon_vbox));
+       for (; child != NULL; child = g_list_next(child)) {
+               if (!GTK_IS_EVENT_BOX(child->data))
+                       continue;
+               if(g_object_get_data(G_OBJECT(child->data),
+                                     "partinfo") == (gpointer)mimeinfo) {
+                       gint *border_x = NULL;
+                       GtkWidget *icon = gtk_bin_get_child(GTK_BIN(child->data));
+                       border_x = g_object_get_data(G_OBJECT(icon), "border_x");
+                       *border_x = 0;
+                       gtk_widget_queue_draw(icon);
+               } else {
+                       gint *border_x = NULL;
+                       GtkWidget *icon = gtk_bin_get_child(GTK_BIN(child->data));
+                       border_x = g_object_get_data(G_OBJECT(icon), "border_x");
+                       *border_x = 6;
+                       gtk_widget_queue_draw(icon);
+               }                        
+       }
+}
+
+static gint mime_toggle_button_cb(GtkWidget *button, GdkEventButton *event,
+                                   MimeView *mimeview)
 {
        gtk_widget_ref(button); 
 
-       if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
+       mimeview_leave_notify(button, NULL, NULL);
+
+       mimeview->ctree_mode = !mimeview->ctree_mode;
+       if (mimeview->ctree_mode) {
                gtk_arrow_set(GTK_ARROW(GTK_BIN(button)->child), GTK_ARROW_RIGHT, 
                                        GTK_SHADOW_NONE);
                gtk_widget_hide(mimeview->icon_mainbox);
@@ -2354,9 +2338,8 @@ static void mime_toggle_button_cb (GtkWidget *button, MimeView *mimeview)
 
                gtk_paned_set_gutter_size(GTK_PANED(mimeview->paned), 0);
        }
-       gtk_widget_grab_focus(button);
        gtk_widget_unref(button);
-
+       return TRUE;
 }
 
 void mimeview_update (MimeView *mimeview) {
index 4f110da8bafc1b0d4429ce68b88c9584015f8c6c..dae076b74e9b328d11760631a84e830cde5988aa 100644 (file)
@@ -70,6 +70,7 @@ struct _MimeView
        GtkWidget *mime_toggle;
        GtkWidget *scrollbutton;
        MimeViewType type;
+       gboolean ctree_mode;
 
        GtkWidget *popupmenu;
        GtkItemFactory *popupfactory;
index 4a28da9fd248a2865000815d656d3666329f7127..12cb8295374f9e80f2209afd3a4537ecf67e71b0 100644 (file)
@@ -736,6 +736,7 @@ GtkWidget *stock_pixmap_widget_with_overlay(GtkWidget *window, StockPixmap icon,
                         G_CALLBACK(pixmap_with_overlay_expose_event_cb), data);
        g_signal_connect(G_OBJECT(widget), "destroy",
                         G_CALLBACK(pixmap_with_overlay_destroy_cb), data);
+       g_object_set_data(G_OBJECT(widget), "border_x", &(data->border_x));
        return widget;
 
 }
index b2472b9532215c09270980679ede2f9507c2c560..90bf2d83aac0cf0032446c4121ea7b897192e277 100644 (file)
@@ -5389,6 +5389,11 @@ static void summary_tags_menu_item_activate_item_cb(GtkMenuItem *menu_item,
                                        g_direct_hash,
                                        g_direct_equal,
                                        NULL, NULL);
+       GHashTable *menu_allsel_table = g_hash_table_new_full(
+                                       g_direct_hash,
+                                       g_direct_equal,
+                                       NULL, NULL);
+       gint sel_len;
        SummaryView *summaryview = (SummaryView *)data;
        g_return_if_fail(summaryview != NULL);
 
@@ -5412,11 +5417,13 @@ static void summary_tags_menu_item_activate_item_cb(GtkMenuItem *menu_item,
                                (GTK_CHECK_MENU_ITEM(cur->data), FALSE);
                                
                        g_hash_table_insert(menu_table, GINT_TO_POINTER(id), GTK_CHECK_MENU_ITEM(cur->data));
+                       g_hash_table_insert(menu_allsel_table, GINT_TO_POINTER(id), GINT_TO_POINTER(0));
                }
        }
 
        /* iterate all messages and set the state of the appropriate
         * items */
+       sel_len = 0;
        for (; sel != NULL; sel = sel->next) {
                MsgInfo *msginfo;
                GSList *tags = NULL;
@@ -5425,33 +5432,49 @@ static void summary_tags_menu_item_activate_item_cb(GtkMenuItem *menu_item,
                msginfo = gtk_ctree_node_get_row_data
                        (GTK_CTREE(summaryview->ctree),
                         GTK_CTREE_NODE(sel->data));
+               sel_len++;
                if (msginfo) {
                        tags =  msginfo->tags;
                        if (!tags)
                                continue;
 
                        for (; tags; tags = tags->next) {
+                               gint num_checked = GPOINTER_TO_INT(g_hash_table_lookup(menu_allsel_table, tags->data));
                                id = GPOINTER_TO_INT(tags->data);
                                item = g_hash_table_lookup(menu_table, GINT_TO_POINTER(tags->data));
-                               if (item && !item->active)
+                               if (item && !item->active) {
                                        gtk_check_menu_item_set_active
                                                (item, TRUE);
+                               }
+                               num_checked++;
+                               g_hash_table_replace(menu_allsel_table, tags->data, GINT_TO_POINTER(num_checked));
                        }
                }
        }
 
+       for (cur = menu->children; cur != NULL && cur->data != NULL; cur = cur->next) {
+               if (GTK_IS_CHECK_MENU_ITEM(cur->data)) {
+                       gint id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cur->data),
+                               "tag_id"));
+                       gint num_checked = GPOINTER_TO_INT(g_hash_table_lookup(menu_allsel_table, GINT_TO_POINTER(id)));
+                       if (num_checked < sel_len && num_checked > 0)
+                               gtk_check_menu_item_set_inconsistent(GTK_CHECK_MENU_ITEM(cur->data), TRUE);
+                       else
+                               gtk_check_menu_item_set_inconsistent(GTK_CHECK_MENU_ITEM(cur->data), FALSE);
+               }
+       }
        g_hash_table_destroy(menu_table);
+       g_hash_table_destroy(menu_allsel_table);
        /* reset "dont_toggle" state */
        g_object_set_data(G_OBJECT(menu), "dont_toggle",
                          GINT_TO_POINTER(0));
 
 }
 
-static void summary_tags_menu_item_new_tag_activate_cb(GtkWidget *widget,
+static void summary_tags_menu_item_apply_tags_activate_cb(GtkWidget *widget,
                                                     gpointer data)
 {
        SummaryView *summaryview;
-       gint id;
 
        summaryview = g_object_get_data(G_OBJECT(widget), "summaryview");
        g_return_if_fail(summaryview != NULL);
@@ -5460,12 +5483,8 @@ static void summary_tags_menu_item_new_tag_activate_cb(GtkWidget *widget,
        if (g_object_get_data(G_OBJECT(summaryview->tags_menu),
                                "dont_toggle"))
                return;
-
-       id = prefs_tags_create_new(summaryview->mainwin);
-       if (id != -1) {
-               summary_set_tag(summaryview, id, NULL);
-               main_window_reflect_tags_changes(mainwindow_get_mainwindow());
-       }
+       
+       tag_apply_open(summary_get_selection(summaryview));     
 }
 
 static void summary_tags_menu_create(SummaryView *summaryview, gboolean refresh)
@@ -5510,14 +5529,20 @@ static void summary_tags_menu_create(SummaryView *summaryview, gboolean refresh)
                gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
                gtk_widget_show(item);
        }
-       item = gtk_menu_item_new_with_label(_("New tag..."));
+
+       item = gtk_menu_item_new_with_label(_("Apply tags..."));
+       gtk_widget_add_accelerator(item, "activate", 
+                  summaryview->popupfactory->accel_group, 
+                  GDK_T, GDK_CONTROL_MASK|GDK_SHIFT_MASK,
+                  GTK_ACCEL_LOCKED | GTK_ACCEL_VISIBLE);
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
        g_signal_connect(G_OBJECT(item), "activate",
-                        G_CALLBACK(summary_tags_menu_item_new_tag_activate_cb),
+                        G_CALLBACK(summary_tags_menu_item_apply_tags_activate_cb),
                         NULL);
        g_object_set_data(G_OBJECT(item), "summaryview",
                          summaryview);
        gtk_widget_show(item);
+
        g_slist_free(orig);
        gtk_widget_show(menu);
        gtk_menu_item_set_submenu(GTK_MENU_ITEM(label_menuitem), menu);