2006-09-02 [paul] 2.4.0cvs132
[claws.git] / src / mainwindow.c
index cc7e413fd90acfe508cd49a0f380dbf978b6cd6c..b700dcc7a324b4e716cc0f04281490c8f3664b39 100644 (file)
@@ -56,6 +56,7 @@
 #include "stock_pixmap.h"
 #include "folder.h"
 #include "inc.h"
+#include "log.h"
 #include "compose.h"
 #include "procmsg.h"
 #include "import.h"
 static GList *mainwin_list = NULL;
 
 static GdkCursor *watch_cursor = NULL;
+static GdkCursor *hand_cursor = NULL;
 
 static void main_window_menu_callback_block    (MainWindow     *mainwin);
 static void main_window_menu_callback_unblock  (MainWindow     *mainwin);
@@ -218,6 +220,10 @@ static void show_all_header_cb             (MainWindow     *mainwin,
                                         guint           action,
                                         GtkWidget      *widget);
 
+static void hide_quotes_cb(MainWindow  *mainwin,
+                                        guint           action,
+                                        GtkWidget      *widget);
+
 static void move_to_cb                 (MainWindow     *mainwin,
                                         guint           action,
                                         GtkWidget      *widget);
@@ -348,6 +354,12 @@ static void prev_labeled_cb         (MainWindow    *mainwin,
 static void next_labeled_cb     (MainWindow    *mainwin,
                                  guint          action,
                                  GtkWidget     *widget);
+static void last_read_cb        (MainWindow    *mainwin,
+                                 guint          action,
+                                 GtkWidget     *widget);
+static void parent_cb           (MainWindow    *mainwin,
+                                 guint          action,
+                                 GtkWidget     *widget);
 
 static void goto_folder_cb      (MainWindow    *mainwin,
                                  guint          action,
@@ -577,6 +589,11 @@ static GtkItemFactoryEntry mainwin_entries[] =
        {N_("/_View/_Go to/Next la_beled message"),
                                                NULL, next_labeled_cb, 0, NULL},
        {N_("/_View/_Go to/---"),               NULL, NULL, 0, "<Separator>"},
+       {N_("/_View/_Go to/Last read message"),
+                                               NULL, last_read_cb, 0, NULL},
+       {N_("/_View/_Go to/Parent message"),
+                                               "<control>Up", parent_cb, 0, NULL},
+       {N_("/_View/_Go to/---"),               NULL, NULL, 0, "<Separator>"},
        {N_("/_View/_Go to/Next unread _folder"),       "<shift>G", goto_unread_folder_cb, 0, NULL},
        {N_("/_View/_Go to/_Other folder..."),  "G", goto_folder_cb, 0, NULL},
        {N_("/_View/---"),                      NULL, NULL, 0, "<Separator>"},
@@ -699,7 +716,11 @@ static GtkItemFactoryEntry mainwin_entries[] =
        {N_("/_View/---"),                      NULL, NULL, 0, "<Separator>"},
        {N_("/_View/Open in new _window"),      "<control><alt>N", open_msg_cb, 0, NULL},
        {N_("/_View/Mess_age source"),          "<control>U", view_source_cb, 0, NULL},
-       {N_("/_View/Show all headers"),         "<control>H", show_all_header_cb, 0, "<ToggleItem>"},
+       {N_("/_View/All headers"),              "<control>H", show_all_header_cb, 0, "<ToggleItem>"},
+       {N_("/_View/Quotes"),                   NULL, NULL, 0, "<Branch>"},
+       {N_("/_View/Quotes/_Fold all"),         "<control><shift>Q", hide_quotes_cb, 1, "<ToggleItem>"},
+       {N_("/_View/Quotes/Fold from level _2"),NULL, hide_quotes_cb, 2, "<ToggleItem>"},
+       {N_("/_View/Quotes/Fold from level _3"),NULL, hide_quotes_cb, 3, "<ToggleItem>"},
        {N_("/_View/---"),                      NULL, NULL, 0, "<Separator>"},
        {N_("/_View/_Update summary"),          "<control><alt>U", update_summary_cb,  0, NULL},
 
@@ -1001,6 +1022,50 @@ static void mainwindow_colorlabel_menu_create(MainWindow *mainwin, gboolean refr
        mainwin->colorlabel_menu = menu;
 }
 
+static gboolean warning_icon_pressed(GtkWidget *widget, GdkEventButton *evt,
+                                   MainWindow *mainwindow)
+{
+       if (evt && evt->button == 1) {
+               log_window_show_error(mainwindow->logwin);
+               gtk_widget_hide(mainwindow->warning_btn);
+       }
+       return FALSE;
+}
+
+static gboolean warning_visi_notify(GtkWidget *widget,
+                                      GdkEventVisibility *event,
+                                      MainWindow *mainwindow)
+{
+       gdk_window_set_cursor(mainwindow->warning_btn->window, hand_cursor);
+       return FALSE;
+}
+
+static gboolean warning_leave_notify(GtkWidget *widget,
+                                     GdkEventCrossing *event,
+                                     MainWindow *mainwindow)
+{
+       gdk_window_set_cursor(mainwindow->warning_btn->window, NULL);
+       return FALSE;
+}
+
+static gboolean warning_enter_notify(GtkWidget *widget,
+                                     GdkEventCrossing *event,
+                                     MainWindow *mainwindow)
+{
+       gdk_window_set_cursor(mainwindow->warning_btn->window, hand_cursor);
+       return FALSE;
+}
+
+void mainwindow_show_error(void)
+{
+       MainWindow *mainwin = mainwindow_get_mainwindow();
+       gtk_widget_show(mainwin->warning_btn);
+}
+
+void mainwindow_clear_error(MainWindow *mainwin)
+{
+       gtk_widget_hide(mainwin->warning_btn);
+}
 
 MainWindow *main_window_create(SeparateType type)
 {
@@ -1020,9 +1085,9 @@ MainWindow *main_window_create(SeparateType type)
        GtkWidget *offline_pixmap;
        GtkWidget *online_switch;
        GtkWidget *offline_switch;
-       GtkTooltips *offline_tip;
-       GtkTooltips *online_tip;
-       GtkTooltips *sel_ac_tip;
+       GtkTooltips *tips;
+       GtkWidget *warning_icon;
+       GtkWidget *warning_btn;
 
        FolderView *folderview;
        SummaryView *summaryview;
@@ -1118,6 +1183,33 @@ MainWindow *main_window_create(SeparateType type)
        hbox_stat = gtk_hbox_new(FALSE, 2);
        gtk_box_pack_end(GTK_BOX(vbox_body), hbox_stat, FALSE, FALSE, 0);
 
+       tips = gtk_tooltips_new();
+
+       warning_icon = gtk_image_new_from_stock
+                        (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_SMALL_TOOLBAR);
+       warning_btn = gtk_event_box_new();
+       gtk_event_box_set_visible_window(GTK_EVENT_BOX(warning_btn), FALSE);
+       
+       mainwin->warning_btn      = warning_btn;
+       
+       g_signal_connect(G_OBJECT(warning_btn), "button-press-event", 
+                        G_CALLBACK(warning_icon_pressed),
+                        (gpointer) mainwin);
+       g_signal_connect(G_OBJECT(warning_btn), "visibility-notify-event",
+                        G_CALLBACK(warning_visi_notify), mainwin);
+       g_signal_connect(G_OBJECT(warning_btn), "motion-notify-event",
+                        G_CALLBACK(warning_visi_notify), mainwin);
+       g_signal_connect(G_OBJECT(warning_btn), "leave-notify-event",
+                        G_CALLBACK(warning_leave_notify), mainwin);
+       g_signal_connect(G_OBJECT(warning_btn), "enter-notify-event",
+                        G_CALLBACK(warning_enter_notify), mainwin);
+
+       gtk_container_add (GTK_CONTAINER(warning_btn), warning_icon);
+
+       gtk_tooltips_set_tip(GTK_TOOLTIPS(tips),warning_btn, 
+                            _("Some error(s) happened. Click here to view log."), NULL);
+       gtk_box_pack_start(GTK_BOX(hbox_stat), warning_btn, FALSE, FALSE, 0);
+
        statusbar = statusbar_create();
        gtk_box_pack_start(GTK_BOX(hbox_stat), statusbar, TRUE, TRUE, 0);
 
@@ -1127,13 +1219,11 @@ MainWindow *main_window_create(SeparateType type)
 
        online_pixmap = stock_pixmap_widget(hbox_stat, STOCK_PIXMAP_ONLINE);
        offline_pixmap = stock_pixmap_widget(hbox_stat, STOCK_PIXMAP_OFFLINE);
-       online_tip = gtk_tooltips_new();
        online_switch = gtk_button_new ();
-       gtk_tooltips_set_tip(GTK_TOOLTIPS(online_tip),online_switch, 
+       gtk_tooltips_set_tip(GTK_TOOLTIPS(tips),online_switch, 
                             _("You are online. Click the icon to go offline"), NULL);
-       offline_tip = gtk_tooltips_new();
        offline_switch = gtk_button_new ();
-       gtk_tooltips_set_tip(GTK_TOOLTIPS(offline_tip),offline_switch, 
+       gtk_tooltips_set_tip(GTK_TOOLTIPS(tips),offline_switch, 
                             _("You are offline. Click the icon to go online"),
                             NULL);
        gtk_container_add (GTK_CONTAINER(online_switch), online_pixmap);
@@ -1148,9 +1238,8 @@ MainWindow *main_window_create(SeparateType type)
        statuslabel = gtk_label_new("");
        gtk_box_pack_start(GTK_BOX(hbox_stat), statuslabel, FALSE, FALSE, 0);
 
-       sel_ac_tip = gtk_tooltips_new();
        ac_button = gtk_button_new();
-       gtk_tooltips_set_tip(GTK_TOOLTIPS(sel_ac_tip),
+       gtk_tooltips_set_tip(GTK_TOOLTIPS(tips),
                             ac_button, _("Select account"), NULL);
        GTK_WIDGET_UNSET_FLAGS(ac_button, GTK_CAN_FOCUS);
        gtk_widget_set_size_request(ac_button, -1, 0);
@@ -1164,6 +1253,7 @@ MainWindow *main_window_create(SeparateType type)
        gtk_widget_show_all(hbox_stat);
 
        gtk_widget_hide(offline_switch);
+       gtk_widget_hide(warning_btn);
        /* create views */
        mainwin->folderview  = folderview  = folderview_create();
        mainwin->summaryview = summaryview = summary_create();
@@ -1333,6 +1423,8 @@ MainWindow *main_window_create(SeparateType type)
 
        if (!watch_cursor)
                watch_cursor = gdk_cursor_new(GDK_WATCH);
+       if (!hand_cursor)
+               hand_cursor = gdk_cursor_new(GDK_HAND2);
 
        mainwin_list = g_list_append(mainwin_list, mainwin);
 
@@ -2038,7 +2130,7 @@ SensitiveCond main_window_get_current_state(MainWindow *mainwin)
 
                if ((selection == SUMMARY_NONE && item->hide_read_msgs)
                    || selection != SUMMARY_NONE)
-                       state |= M_HIDE_READ_MSG;       
+                       state |= M_HIDE_READ_MSG;
        }               
        if (mainwin->summaryview->threaded)
                state |= M_THREADED;
@@ -2054,6 +2146,12 @@ SensitiveCond main_window_get_current_state(MainWindow *mainwin)
                state |= M_NEWS;
        else
                state |= M_NOT_NEWS;
+       if (prefs_common.actions_list && g_slist_length(prefs_common.actions_list))
+               state |= M_ACTIONS_EXIST;
+
+       if (procmsg_have_queued_mails_fast() && !procmsg_is_sending())
+               state |= M_HAVE_QUEUED_MAILS;
+
        if (selection == SUMMARY_SELECTED_SINGLE &&
            (item &&
             (folder_has_parent_of_type(item, F_DRAFT) ||
@@ -2121,8 +2219,11 @@ void main_window_set_menu_sensitive(MainWindow *mainwin)
                {"/View/Go to/Previous marked message" , M_MSG_EXIST},
                {"/View/Go to/Previous labeled message", M_MSG_EXIST},
                {"/View/Go to/Next labeled message", M_MSG_EXIST},
+               {"/View/Go to/Last read message"   , M_SINGLE_TARGET_EXIST},
+               {"/View/Go to/Parent message"      , M_SINGLE_TARGET_EXIST},
                {"/View/Open in new window"        , M_SINGLE_TARGET_EXIST},
                {"/View/Show all headers"          , M_SINGLE_TARGET_EXIST},
+               {"/View/Quotes"                    , M_SINGLE_TARGET_EXIST},
                {"/View/Message source"            , M_SINGLE_TARGET_EXIST},
 
                {"/Message/Receive/Get from current account"
@@ -2131,7 +2232,7 @@ void main_window_set_menu_sensitive(MainWindow *mainwin)
                                                 , M_HAVE_ACCOUNT|M_UNLOCKED},
                {"/Message/Receive/Cancel receiving"
                                                 , M_INC_ACTIVE},
-
+               {"/Message/Send queued messages"  , M_HAVE_ACCOUNT|M_HAVE_QUEUED_MAILS},
                {"/Message/Compose a news message", M_HAVE_NEWS_ACCOUNT},
                {"/Message/Reply"                 , M_HAVE_ACCOUNT|M_TARGET_EXIST},
                {"/Message/Reply to"              , M_HAVE_ACCOUNT|M_TARGET_EXIST},
@@ -2158,7 +2259,7 @@ void main_window_set_menu_sensitive(MainWindow *mainwin)
                {"/Tools/Filter selected messages"     , M_TARGET_EXIST|M_EXEC},
                {"/Tools/Create filter rule"           , M_SINGLE_TARGET_EXIST|M_UNLOCKED},
                {"/Tools/Create processing rule"       , M_SINGLE_TARGET_EXIST|M_UNLOCKED},
-               {"/Tools/Actions"                      , M_TARGET_EXIST},
+               {"/Tools/Actions"                      , M_TARGET_EXIST|M_ACTIONS_EXIST},
                {"/Tools/Execute"                      , M_DELAY_EXEC},
                {"/Tools/Delete duplicated messages/In selected folder"   , M_MSG_EXIST|M_ALLOW_DELETE},
 
@@ -2255,6 +2356,15 @@ void main_window_set_menu_sensitive(MainWindow *mainwin)
                SET_CHECK_MENU_ACTIVE("/View/Show all headers",
                              mainwin->messageview->mimeview->textview->show_all_headers);
        SET_CHECK_MENU_ACTIVE("/View/Thread view", (state & M_THREADED) != 0);
+       SET_CHECK_MENU_ACTIVE("/View/Quotes/Fold all", FALSE);
+       SET_CHECK_MENU_ACTIVE("/View/Quotes/Fold from level 2", FALSE);
+       SET_CHECK_MENU_ACTIVE("/View/Quotes/Fold from level 3", FALSE);
+       if (prefs_common.hide_quotes == 1)
+               SET_CHECK_MENU_ACTIVE("/View/Quotes/Fold all", TRUE);
+       if (prefs_common.hide_quotes == 2)
+               SET_CHECK_MENU_ACTIVE("/View/Quotes/Fold from level 2", TRUE);
+       if (prefs_common.hide_quotes == 3)
+               SET_CHECK_MENU_ACTIVE("/View/Quotes/Fold from level 3", TRUE);
 
 #undef SET_CHECK_MENU_ACTIVE
 
@@ -2281,39 +2391,50 @@ static gint mailing_list_create_submenu (GtkItemFactory *ifactory, MsgInfo *msgi
 {
        gint menu_nb = 0;
        GtkWidget *menuitem;
-
+       
+       if (!msginfo || !msginfo->extradata) {
+               menu_set_sensitive(ifactory, "/Message/Mailing-List/Post", FALSE);
+               menu_set_sensitive(ifactory, "/Message/Mailing-List/Help", FALSE);
+               menu_set_sensitive(ifactory, "/Message/Mailing-List/Subscribe", FALSE);
+               menu_set_sensitive(ifactory, "/Message/Mailing-List/Unsubscribe", FALSE);
+               menu_set_sensitive(ifactory, "/Message/Mailing-List/View archive", FALSE);
+               menu_set_sensitive(ifactory, "/Message/Mailing-List/Contact owner", FALSE);
+               return 0;
+       }
+               
        /* Mailing list post */
-       if (msginfo && !strcmp2 (msginfo->list_post, "NO")) {
-               msginfo->list_post = g_strdup (_("No posting allowed"));
+       if (!strcmp2 (msginfo->extradata->list_post, "NO")) {
+               g_free(msginfo->extradata->list_post);
+               msginfo->extradata->list_post = g_strdup (_("No posting allowed"));
        }
        menuitem = gtk_item_factory_get_item (ifactory, "/Message/Mailing-List/Post");
                
-       menu_nb += mailing_list_populate_submenu (menuitem, msginfo->list_post);
+       menu_nb += mailing_list_populate_submenu (menuitem, msginfo->extradata->list_post);
  
        /* Mailing list help */
        menuitem = gtk_item_factory_get_item (ifactory, "/Message/Mailing-List/Help");
        
-       menu_nb += mailing_list_populate_submenu (menuitem, msginfo->list_help);
+       menu_nb += mailing_list_populate_submenu (menuitem, msginfo->extradata->list_help);
 
        /* Mailing list subscribe */
        menuitem = gtk_item_factory_get_item (ifactory, "/Message/Mailing-List/Subscribe");
        
-       menu_nb += mailing_list_populate_submenu (menuitem, msginfo->list_subscribe);
+       menu_nb += mailing_list_populate_submenu (menuitem, msginfo->extradata->list_subscribe);
                
        /* Mailing list unsubscribe */
        menuitem = gtk_item_factory_get_item (ifactory, "/Message/Mailing-List/Unsubscribe");
        
-       menu_nb += mailing_list_populate_submenu (menuitem, msginfo->list_unsubscribe);
+       menu_nb += mailing_list_populate_submenu (menuitem, msginfo->extradata->list_unsubscribe);
        
        /* Mailing list view archive */
        menuitem = gtk_item_factory_get_item (ifactory, "/Message/Mailing-List/View archive");
        
-       menu_nb += mailing_list_populate_submenu (menuitem, msginfo->list_archive);
+       menu_nb += mailing_list_populate_submenu (menuitem, msginfo->extradata->list_archive);
        
        /* Mailing list contact owner */
        menuitem = gtk_item_factory_get_item (ifactory, "/Message/Mailing-List/Contact owner");
        
-       menu_nb += mailing_list_populate_submenu (menuitem, msginfo->list_owner);
+       menu_nb += mailing_list_populate_submenu (menuitem, msginfo->extradata->list_owner);
        
        return menu_nb;
 }
@@ -3142,15 +3263,16 @@ static void online_switch_clicked (GtkButton *btn, gpointer data)
        g_return_if_fail(menuitem != NULL);
        
        if (btn == GTK_BUTTON(mainwin->online_switch)) {
+               gtk_widget_hide (mainwin->online_switch);
+               gtk_widget_show (mainwin->offline_switch);
+               menuitem->active = TRUE;
+               inc_autocheck_timer_remove();
+                       
                /* go offline */
                if (prefs_common.work_offline)
                        return;
                mainwindow_check_synchronise(mainwin, TRUE);
-               gtk_widget_hide (mainwin->online_switch);
-               gtk_widget_show (mainwin->offline_switch);
-               menuitem->active = TRUE;
                prefs_common.work_offline = TRUE;
-               inc_autocheck_timer_remove();           
                imap_disconnect_all();
        } else {
                /*go online */
@@ -3228,6 +3350,34 @@ static void show_all_header_cb(MainWindow *mainwin, guint action,
                                     GTK_CHECK_MENU_ITEM(widget)->active);
 }
 
+#define SET_CHECK_MENU_ACTIVE(path, active) \
+{ \
+       menuitem = gtk_item_factory_get_widget(ifactory, path); \
+       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), active); \
+}
+
+static void hide_quotes_cb(MainWindow *mainwin, guint action,
+                              GtkWidget *widget)
+{
+       GtkWidget *menuitem;
+       GtkItemFactory *ifactory = mainwin->menu_factory;
+
+       if (mainwin->menu_lock_count) return;
+
+       prefs_common.hide_quotes = 
+                       GTK_CHECK_MENU_ITEM(widget)->active ? action : 0;
+
+       mainwin->menu_lock_count++;
+       SET_CHECK_MENU_ACTIVE("/View/Quotes/Fold all", FALSE);
+       SET_CHECK_MENU_ACTIVE("/View/Quotes/Fold from level 2", FALSE);
+       SET_CHECK_MENU_ACTIVE("/View/Quotes/Fold from level 3", FALSE);
+       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), prefs_common.hide_quotes > 0);
+       mainwin->menu_lock_count--;
+
+       summary_redisplay_msg(mainwin->summaryview);
+}
+
+#undef SET_CHECK_MENU_ACTIVE
 static void mark_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
 {
        summary_mark(mainwin->summaryview);
@@ -3522,6 +3672,18 @@ static void next_labeled_cb(MainWindow *mainwin, guint action,
        summary_select_next_labeled(mainwin->summaryview);
 }
 
+static void last_read_cb(MainWindow *mainwin, guint action,
+                           GtkWidget *widget)
+{
+       summary_select_last_read(mainwin->summaryview);
+}
+
+static void parent_cb(MainWindow *mainwin, guint action,
+                           GtkWidget *widget)
+{
+       summary_select_parent(mainwin->summaryview);
+}
+
 static void goto_folder_cb(MainWindow *mainwin, guint action,
                           GtkWidget *widget)
 {
@@ -3536,7 +3698,7 @@ static void goto_folder_cb(MainWindow *mainwin, guint action,
 static void goto_unread_folder_cb(MainWindow *mainwin, guint action,
                           GtkWidget *widget)
 {
-       folderview_select_next_unread(mainwin->folderview);
+       folderview_select_next_unread(mainwin->folderview, FALSE);
 }
 
 static void copy_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
@@ -3579,7 +3741,7 @@ static void prefs_pre_processing_open_cb(MainWindow *mainwin, guint action,
        prefs_filtering_open(&pre_global_processing,
                             _("Processing rules to apply before folder rules"),
                             MANUAL_ANCHOR_PROCESSING,
-                            NULL, NULL);
+                            NULL, NULL, FALSE);
 }
 
 static void prefs_post_processing_open_cb(MainWindow *mainwin, guint action,
@@ -3588,7 +3750,7 @@ static void prefs_post_processing_open_cb(MainWindow *mainwin, guint action,
        prefs_filtering_open(&post_global_processing,
                             _("Processing rules to apply after folder rules"),
                             MANUAL_ANCHOR_PROCESSING,
-                            NULL, NULL);
+                            NULL, NULL, FALSE);
 }
 
 static void prefs_filtering_open_cb(MainWindow *mainwin, guint action,
@@ -3597,7 +3759,7 @@ static void prefs_filtering_open_cb(MainWindow *mainwin, guint action,
        prefs_filtering_open(&filtering_rules,
                             _("Filtering configuration"),
                             MANUAL_ANCHOR_FILTERING,
-                            NULL, NULL);
+                            NULL, NULL, TRUE);
 }
 
 static void prefs_template_open_cb(MainWindow *mainwin, guint action,
@@ -3762,7 +3924,7 @@ gboolean mainwindow_key_pressed (GtkWidget *widget, GdkEventKey *event,
                            && mainwin->summaryview->folder_item->total_msgs == 0))) {
                        g_signal_stop_emission_by_name(G_OBJECT(widget), 
                                        "key_press_event");
-                       folderview_select_next_unread(mainwin->folderview);
+                       folderview_select_next_unread(mainwin->folderview, TRUE);
                }
                break;
        default: