2007-11-23 [wwp] 3.1.0cvs25
[claws.git] / src / summaryview.c
index 7e2a1e392e86ad6c5edf3a6beb24ede4a08ade65..54795ea09159846ee0d96a411aaa89c1a76ddc20 100644 (file)
@@ -313,6 +313,7 @@ static void summary_col_resized             (GtkCList               *clist,
 static void summary_reply_cb           (SummaryView            *summaryview,
                                         guint                   action,
                                         GtkWidget              *widget);
+#ifndef MAEMO
 static void summary_show_all_header_cb (SummaryView            *summaryview,
                                         guint                   action,
                                         GtkWidget              *widget);
@@ -320,13 +321,15 @@ static void summary_show_all_header_cb    (SummaryView            *summaryview,
 static void summary_add_address_cb     (SummaryView            *summaryview,
                                         guint                   action,
                                         GtkWidget              *widget);
+#endif
 static void summary_create_filter_cb   (SummaryView            *summaryview,
                                         guint                   action,
                                         GtkWidget              *widget);
+#ifndef MAEMO
 static void summary_create_processing_cb(SummaryView           *summaryview,
                                         guint                   action,
                                         GtkWidget              *widget);
-
+#endif
 static void summary_mark_clicked       (GtkWidget              *button,
                                         SummaryView            *summaryview);
 static void summary_status_clicked     (GtkWidget              *button,
@@ -441,6 +444,10 @@ static void summary_find_answers   (SummaryView    *summaryview,
 static gboolean summary_update_msg     (gpointer source, gpointer data);
 static gboolean summary_update_folder_item_hook(gpointer source, gpointer data);
 static gboolean summary_update_folder_hook(gpointer source, gpointer data);
+static void summary_set_colorlabel_color (GtkCTree             *ctree,
+                                  GtkCTreeNode         *node,
+                                  guint                 labelcolor);
+static void summary_thread_build(SummaryView *summaryview);
 
 GtkTargetEntry summary_drag_types[2] =
 {
@@ -1127,7 +1134,9 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                }
        }
        if (!prefs_common.summary_quicksearch_sticky
-        && !prefs_common.summary_quicksearch_recurse
+        && (!prefs_common.summary_quicksearch_recurse
+         || !quicksearch_is_active(summaryview->quicksearch)
+         || (item && !quicksearch_is_in_subfolder(summaryview->quicksearch, item)))
         && !quicksearch_is_running(summaryview->quicksearch)
         && !is_refresh) {
                quicksearch_set(summaryview->quicksearch, prefs_common.summary_quicksearch_type, "");
@@ -1177,7 +1186,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                g_free(buf);
                debug_print("empty folder (%p %s %p %d)\n\n",
                                item, 
-                               item?item->path:"NULL",
+                               (item && item->path)?item->path:"(null)",
                                item?folder_item_parent(item):0x0,
                                item?item->no_select:FALSE);
                summary_set_hide_read_msgs_menu(summaryview, FALSE);
@@ -1410,6 +1419,14 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                                                 ? 0 : GTK_CLIST(ctree)->rows - 1);
                                }
                                break;
+                       case ACTION_FIRST_LIST:
+                               if (GTK_CLIST(ctree)->row_list != NULL) {
+                                       node = gtk_ctree_node_nth
+                                               (ctree,
+                                                item->sort_type == SORT_ASCENDING
+                                                ? 0 : GTK_CLIST(ctree)->rows - 1);
+                               }
+                               break;
                        case ACTION_NOTHING:
                        case ACTION_UNSET:
                                node = NULL;
@@ -1571,7 +1588,9 @@ void summary_set_menu_sensitive(SummaryView *summaryview)
        GtkItemFactory *ifactory = summaryview->popupfactory;
        SensitiveCond state;
        gboolean sensitive;
+#ifndef MAEMO
        GtkWidget *menuitem;
+#endif
        gint i;
 
        static const struct {
@@ -2493,6 +2512,7 @@ static void summary_status_show(SummaryView *summaryview)
                g_free(str);
        }
 
+       summary_set_menu_sensitive(summaryview);
        toolbar_main_set_sensitive(summaryview->mainwin);
 }
 
@@ -2575,6 +2595,9 @@ static void summary_set_column_titles(SummaryView *summaryview)
 
                hbox  = gtk_hbox_new(FALSE, 4);
                label = gtk_label_new(title);
+#ifdef MAEMO
+       gtk_widget_set_size_request(hbox, -1, 20);
+#endif
 
                if (justify == GTK_JUSTIFY_RIGHT)
                        gtk_box_pack_end(GTK_BOX(hbox), label,
@@ -4007,13 +4030,10 @@ void summary_delete(SummaryView *summaryview)
        if (!prefs_common.live_dangerously) {
                gchar *buf = NULL;
                int num = g_list_length(GTK_CLIST(summaryview->ctree)->selection);
-               if (num == 1)
-                       buf = g_strdup_printf(_(
-                               "Do you really want to delete the selected message?"));
-               else
-                       buf = g_strdup_printf(_(
-                               "Do you really want to delete the %d selected messages?"), 
-                               num);
+               buf = g_strdup_printf(ngettext(
+                       "Do you really want to delete the selected message?",
+                       "Do you really want to delete the %d selected messages?", num), 
+                       num);
                aval = alertpanel(_("Delete message(s)"),
                                  buf,
                                  GTK_STOCK_CANCEL, "+"GTK_STOCK_DELETE, NULL);
@@ -4173,6 +4193,12 @@ void summary_move_selected_to(SummaryView *summaryview, FolderItem *to_folder)
                return;
        }
 
+       if (to_folder->no_select) {
+               alertpanel_error(_("The destination folder can only be used to "
+                                  "store subfolders."));
+               return;
+       }
+
        START_LONG_OPERATION(summaryview, FALSE); 
 
        for (cur = GTK_CLIST(summaryview->ctree)->selection;
@@ -4264,6 +4290,12 @@ void summary_copy_selected_to(SummaryView *summaryview, FolderItem *to_folder)
                return;
        }
 
+       if (to_folder->no_select) {
+               alertpanel_error(_("The destination folder can only be used to "
+                                  "store subfolders."));
+               return;
+       }
+
        START_LONG_OPERATION(summaryview, FALSE);
 
        for (cur = GTK_CLIST(summaryview->ctree)->selection;
@@ -4293,17 +4325,43 @@ void summary_copy_to(SummaryView *summaryview)
 
 void summary_add_address(SummaryView *summaryview)
 {
-       MsgInfo *msginfo;
+       MsgInfo *msginfo, *full_msginfo;
        gchar *from;
+       GtkWidget *image = NULL;
+       GdkPixbuf *picture = NULL;
 
        msginfo = gtk_ctree_node_get_row_data(GTK_CTREE(summaryview->ctree),
                                              summaryview->selected);
-       if (!msginfo) return;
+       if (!msginfo || !msginfo->from) 
+               return;
 
        Xstrdup_a(from, msginfo->from, return);
        eliminate_address_comment(from);
        extract_address(from);
-       addressbook_add_contact(msginfo->fromname, from, NULL);
+       
+       full_msginfo = procmsg_msginfo_get_full_info(msginfo);
+       if (full_msginfo &&
+           full_msginfo->extradata &&
+           full_msginfo->extradata->face) {
+               image = face_get_from_header(full_msginfo->extradata->face);
+       } 
+#if HAVE_LIBCOMPFACE
+       else if (full_msginfo &&
+                full_msginfo->extradata &&
+                full_msginfo->extradata->xface) {
+               image = xface_get_from_header(full_msginfo->extradata->xface,
+                               &summaryview->ctree->style->white,
+                               summaryview->mainwin->window->window);  
+       }
+#endif
+       procmsg_msginfo_free(full_msginfo);
+       if (image)
+               picture = gtk_image_get_pixbuf(GTK_IMAGE(image));
+
+       addressbook_add_contact(msginfo->fromname, from, NULL, picture);
+
+       if (image)
+               gtk_widget_destroy(image);
 }
 
 void summary_select_all(SummaryView *summaryview)
@@ -4435,7 +4493,7 @@ void summary_save_as(SummaryView *summaryview)
 void summary_print(SummaryView *summaryview)
 {
        GtkCList *clist = GTK_CLIST(summaryview->ctree);
-#ifndef USE_GNOMEPRINT
+#if !defined(USE_GNOMEPRINT) && !GTK_CHECK_VERSION(2,10,0)
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        MsgInfo *msginfo;
        gchar *cmdline = NULL;
@@ -4455,7 +4513,7 @@ void summary_print(SummaryView *summaryview)
        g_free(msg);
 
        if (clist->selection == NULL) return;
-#ifndef USE_GNOMEPRINT
+#if !defined(USE_GNOMEPRINT) && !GTK_CHECK_VERSION(2,10,0)
        cmdline = input_dialog(_("Print"),
                               _("Enter the print command line:\n"
                                 "('%s' will be replaced with file name)"),
@@ -4751,7 +4809,7 @@ static void summary_execute_delete_func(GtkCTree *ctree, GtkCTreeNode *node,
 
 /* thread functions */
 
-void summary_thread_build(SummaryView *summaryview)
+static void summary_thread_build(SummaryView *summaryview)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GtkCTreeNode *node;
@@ -5533,15 +5591,32 @@ static void summary_tags_menu_item_apply_tags_activate_cb(GtkWidget *widget,
        tag_apply_open(summary_get_selection(summaryview));     
 }
 
+static gint summary_tag_cmp_list(gconstpointer a, gconstpointer b)
+{
+       gint id_a = GPOINTER_TO_INT(a);
+       gint id_b = GPOINTER_TO_INT(b);
+       const gchar *tag_a = tags_get_tag(id_a);
+       const gchar *tag_b = tags_get_tag(id_b);
+       
+       if (tag_a == NULL)
+               return tag_b == NULL ? 0:1;
+       
+       if (tag_b == NULL)
+               return tag_a == NULL ? 0:1;
+
+       return g_utf8_collate(tag_a, tag_b);
+}
+
 static void summary_tags_menu_create(SummaryView *summaryview, gboolean refresh)
 {
        GtkWidget *label_menuitem;
        GtkWidget *menu;
        GtkWidget *item;
        GSList *cur = tags_get_list();
-       GSList *orig = cur;
+       GSList *orig = NULL;
        gboolean existing_tags = FALSE;
 
+       cur = orig = g_slist_sort(cur, summary_tag_cmp_list);
        label_menuitem = gtk_item_factory_get_item(summaryview->popupfactory,
                                                   "/Tags");
        g_signal_connect(G_OBJECT(label_menuitem), "activate",
@@ -5605,6 +5680,137 @@ static gboolean summary_popup_menu(GtkWidget *widget, gpointer data)
        return TRUE;
 }
 
+#if GTK_CHECK_VERSION(2,12,0) && !MAEMO
+static gchar *summaryview_get_tooltip_text(SummaryView *summaryview, MsgInfo *info, gint column)
+{
+       MsgFlags flags;
+
+       if (!info)
+               return NULL;
+
+       flags = info->flags;
+
+       switch(summaryview->col_state[column].type) {
+               case S_COL_STATUS:
+                       if (MSG_IS_IGNORE_THREAD(flags)) {
+                               return _("Ignored thread");
+                       } else if (MSG_IS_WATCH_THREAD(flags)) {
+                               return _("Watched thread");
+                       } else if (MSG_IS_SPAM(flags)) {
+                               return _("Spam");
+                       } else if (MSG_IS_NEW(flags)) {
+                               return _("New");
+                       } else if (MSG_IS_UNREAD(flags)) {
+                               return _("Unread");
+                       } else if (MSG_IS_REPLIED(flags)) {
+                               return _("Replied");
+                       } else if (MSG_IS_FORWARDED(flags)) {
+                               return _("Forwarded");
+                       } else {
+                               return NULL;
+                       }
+               case S_COL_MARK:
+                       if (MSG_IS_DELETED(flags)) {
+                               return _("Deleted");
+                       } else if (MSG_IS_MARKED(flags)) {
+                               return _("Marked");
+                       } else if (MSG_IS_MOVE(flags)) {
+                               return _("To be moved");
+                       } else if (MSG_IS_COPY(flags)) {
+                               return _("To be copied");
+                       } else {
+                               return NULL;
+                       }
+               case S_COL_LOCKED:
+                       if (MSG_IS_LOCKED(flags)) {
+                               return _("Locked");
+                       } else {
+                               return NULL;
+                       }
+               case S_COL_MIME:
+                       if (MSG_IS_WITH_ATTACHMENT(flags) && MSG_IS_SIGNED(flags)) {
+                               return _("Signed, has attachment(s)");
+                       } else if (MSG_IS_SIGNED(flags)) {
+                               return _("Signed");
+                       } else if (MSG_IS_WITH_ATTACHMENT(flags) && MSG_IS_ENCRYPTED(flags)) {
+                               return _("Encrypted, has attachment(s)");
+                       } else if (MSG_IS_ENCRYPTED(flags)) {
+                               return _("Encrypted");
+                       } else if (MSG_IS_WITH_ATTACHMENT(flags)) {
+                               return _("Has attachment(s)");
+                       } else {
+                               return NULL;
+                       }
+               default:
+                       return NULL;
+       }
+}
+static gboolean tooltip_cb (GtkWidget  *widget,
+                            gint        x,
+                            gint        y,
+                            gboolean    keyboard_mode,
+                            GtkTooltip *tooltip,
+                            gpointer    user_data) 
+{
+       GtkCTree *ctree = GTK_CTREE(widget);
+       SummaryView *summaryview = (SummaryView *)user_data;
+       gint row = -1, column = -1;
+       int offset = prefs_common.show_col_headers ? 24:0;
+       GtkCTreeNode *node = NULL;
+       gchar *text = NULL;
+       gchar *formatted = NULL;
+       MsgInfo *info = NULL;
+       GdkRectangle rect;
+
+       if (!prefs_common.show_tooltips)
+               return FALSE;
+
+       if (y - offset < 0)
+               return FALSE;
+
+       if (!gtk_clist_get_selection_info(GTK_CLIST(ctree), x, y - offset,
+                                         &row, &column))
+               return FALSE;
+
+       if ((node = gtk_ctree_node_nth(ctree, row)) == NULL)
+               return FALSE;
+
+       if ((info = gtk_ctree_node_get_row_data(ctree, node)) == NULL)
+               return FALSE;
+
+       switch (gtk_ctree_node_get_cell_type(ctree, node, column)) {
+               case GTK_CELL_TEXT:
+                       if (gtk_ctree_node_get_text(ctree, node, column, &text) != TRUE)
+                               return FALSE;
+                       break;
+               case GTK_CELL_PIXTEXT:
+                       if (gtk_ctree_node_get_pixtext(ctree, node, column, &text, 
+                               NULL, NULL, NULL) != TRUE)
+                               return FALSE;
+                       break;
+               default: 
+                       if ((text = summaryview_get_tooltip_text(summaryview, info, column)) == NULL)
+                               return FALSE;
+       }
+       
+       if (!text || !*text)
+               return FALSE;
+
+       formatted = g_strdup(text);
+       g_strstrip(formatted);
+       
+       gtk_tooltip_set_text (tooltip, formatted);
+       g_free(formatted);
+       
+       rect.x = x - 2;
+       rect.y = y - 2;
+       rect.width = 12;
+       rect.height= 12;        
+       gtk_tooltip_set_tip_area(tooltip, &rect);
+       
+       return TRUE;
+}
+#endif
 static GtkWidget *summary_ctree_create(SummaryView *summaryview)
 {
        GtkWidget *ctree;
@@ -5713,7 +5919,7 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview)
        CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SCORE,   summary_score_clicked);
        CLIST_BUTTON_SIGNAL_CONNECT(S_COL_LOCKED,  summary_locked_clicked);
        CLIST_BUTTON_SIGNAL_CONNECT(S_COL_TAGS,    summary_tags_clicked);
-
+       
 #undef CLIST_BUTTON_SIGNAL_CONNECT
 
        g_signal_connect(G_OBJECT(ctree), "tree_select_row",
@@ -5771,6 +5977,12 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview)
                         G_CALLBACK(summary_drag_motion_cb),
                         summaryview);
 
+#if GTK_CHECK_VERSION(2,12,0) && !MAEMO
+       g_object_set (G_OBJECT(ctree), "has-tooltip", TRUE, NULL);
+       g_signal_connect(G_OBJECT(ctree), "query-tooltip", 
+                        G_CALLBACK(tooltip_cb),
+                       summaryview);
+#endif
        return ctree;
 }
 
@@ -5926,8 +6138,12 @@ static gboolean summary_key_pressed(GtkWidget *widget, GdkEventKey *event,
                case GDK_KP_Enter:
                        handled = TRUE;
                        if (summaryview->displayed != summaryview->selected) {
+#ifndef MAEMO
                                summary_display_msg(summaryview,
                                                    summaryview->selected);
+#else
+                               summary_open_row(NULL, summaryview);
+#endif
                                break;
                        }
                        mimeview_scroll_one_line(messageview->mimeview, mod_pressed);
@@ -6242,7 +6458,7 @@ static void summary_reply_cb(SummaryView *summaryview, guint action,
        compose_reply_from_messageview(msgview, msginfo_list, action);
        g_slist_free(msginfo_list);
 }
-
+#ifndef MAEMO
 static void summary_show_all_header_cb(SummaryView *summaryview,
                                       guint action, GtkWidget *widget)
 {
@@ -6257,19 +6473,19 @@ static void summary_add_address_cb(SummaryView *summaryview,
 {
        summary_add_address(summaryview);
 }
-
+#endif
 static void summary_create_filter_cb(SummaryView *summaryview,
                                     guint action, GtkWidget *widget)
 {
        summary_filter_open(summaryview, (PrefsFilterType)action, 0);
 }
-
+#ifndef MAEMO
 static void summary_create_processing_cb(SummaryView *summaryview,
                                         guint action, GtkWidget *widget)
 {
        summary_filter_open(summaryview, (PrefsFilterType)action, 1);
 }
-
+#endif
 static void summary_sort_by_column_click(SummaryView *summaryview,
                                         FolderSortKey sort_key)
 {
@@ -7198,7 +7414,9 @@ gint summaryview_export_mbox_list(SummaryView *summaryview)
        gchar *mbox = filesel_select_file_save(_("Export to mbox file"), NULL);
        gint ret;
        
-       if (mbox == NULL || list == NULL)
+       if (mbox == NULL)
+               return -2;
+       if (list == NULL)
                return -1;
                
        ret = export_list_to_mbox(list, mbox);