2004-09-28 [colin] 0.9.12cvs110
[claws.git] / src / mainwindow.c
index 2c81f0a7268cc6ccc8da12ad8772ec73f3f28e98..17acb0b4d292d588ef586dfb84f2a50d484994be 100644 (file)
@@ -88,6 +88,8 @@
 #include "progressindicator.h"
 #include "localfolder.h"
 #include "filtering.h"
+#include "folderutils.h"
+#include "foldersort.h"
 
 #define AC_LABEL_WIDTH 240
 
@@ -143,21 +145,15 @@ static void message_window_size_allocate_cb       (GtkWidget      *widget,
                                                 GtkAllocation  *allocation,
                                                 gpointer        data);
 
-static void new_folder_cb       (MainWindow    *mainwin,
-                                 guint          action,
-                                 GtkWidget     *widget);
-static void rename_folder_cb    (MainWindow    *mainwin,
-                                 guint          action,
-                                 GtkWidget     *widget);
-static void delete_folder_cb    (MainWindow    *mainwin,
-                                 guint          action,
-                                 GtkWidget     *widget);
 static void update_folderview_cb (MainWindow   *mainwin,
                                  guint          action,
                                  GtkWidget     *widget);
 static void add_mailbox_cb      (MainWindow    *mainwin,
                                  guint          action,
                                  GtkWidget     *widget);
+static void foldersort_cb       (MainWindow    *mainwin,
+                                 guint          action,
+                                 GtkWidget     *widget);
 static void import_mbox_cb      (MainWindow    *mainwin,
                                  guint          action,
                                  GtkWidget     *widget);
@@ -221,10 +217,6 @@ static void show_all_header_cb             (MainWindow     *mainwin,
                                         guint           action,
                                         GtkWidget      *widget);
 
-static void reedit_cb                  (MainWindow     *mainwin,
-                                        guint           action,
-                                        GtkWidget      *widget);
-
 static void move_to_cb                 (MainWindow     *mainwin,
                                         guint           action,
                                         GtkWidget      *widget);
@@ -255,6 +247,11 @@ static void mark_as_read_cb                (MainWindow     *mainwin,
 static void mark_all_read_cb           (MainWindow     *mainwin,
                                         guint           action,
                                         GtkWidget      *widget);
+
+static void reedit_cb                  (MainWindow     *mainwin,
+                                        guint           action,
+                                        GtkWidget      *widget);
+
 static void add_address_cb             (MainWindow     *mainwin,
                                         guint           action,
                                         GtkWidget      *widget);
@@ -293,6 +290,9 @@ static void attract_by_subject_cb(MainWindow        *mainwin,
 static void delete_duplicated_cb (MainWindow   *mainwin,
                                  guint          action,
                                  GtkWidget     *widget);
+static void delete_duplicated_all_cb (MainWindow       *mainwin,
+                                 guint          action,
+                                 GtkWidget     *widget);
 static void filter_cb           (MainWindow    *mainwin,
                                  guint          action,
                                  GtkWidget     *widget);
@@ -433,16 +433,9 @@ gboolean mainwindow_progressindicator_hook (gpointer        source,
 static GtkItemFactoryEntry mainwin_entries[] =
 {
        {N_("/_File"),                          NULL, NULL, 0, "<Branch>"},
-       {N_("/_File/_Folder"),                  NULL, NULL, 0, "<Branch>"},
-       {N_("/_File/_Folder/Create _new folder..."),
-                                               NULL, new_folder_cb, 0, NULL},
-       {N_("/_File/_Folder/_Rename folder..."),NULL, rename_folder_cb, 0, NULL},
-       {N_("/_File/_Folder/_Delete folder"),   NULL, delete_folder_cb, 0, NULL},
-       {N_("/_File/_Folder/---"),                      NULL, NULL, 0, "<Separator>"},
-       {N_("/_File/_Folder/_Check for new messages in all folders"),
-                                               NULL, update_folderview_cb, 0, NULL},
        {N_("/_File/_Add mailbox"),             NULL, NULL, 0, "<Branch>"},
        {N_("/_File/_Add mailbox/MH..."),       NULL, add_mailbox_cb, 0, NULL},
+       {N_("/_File/Change folder order"),      NULL, foldersort_cb,  0, NULL},
        {N_("/_File/_Import mbox file..."),     NULL, import_mbox_cb, 0, NULL},
        {N_("/_File/_Export to mbox file..."),  NULL, export_mbox_cb, 0, NULL},
        {N_("/_File/Empty _trash"),             "<shift>D", empty_trash_cb, 0, NULL},
@@ -580,6 +573,8 @@ static GtkItemFactoryEntry mainwin_entries[] =
         CODESET_ACTION(C_ISO_8859_5)},
        {N_("/_View/_Code set/Cyrillic (KOI8-_R)"),
         CODESET_ACTION(C_KOI8_R)},
+       {N_("/_View/_Code set/Cyrillic (KOI8-U)"),
+        CODESET_ACTION(C_KOI8_U)},
        {N_("/_View/_Code set/Cyrillic (Windows-1251)"),
         CODESET_ACTION(C_WINDOWS_1251)},
        CODESET_SEPARATOR,
@@ -650,8 +645,6 @@ static GtkItemFactoryEntry mainwin_entries[] =
        {N_("/_Message/_Forward"),              "<control><alt>F", main_window_reply_cb, COMPOSE_FORWARD, NULL},
        {N_("/_Message/Redirect"),              NULL, main_window_reply_cb, COMPOSE_REDIRECT, NULL},
        {N_("/_Message/---"),                   NULL, NULL, 0, "<Separator>"},
-       {N_("/_Message/Re-_edit"),              NULL, reedit_cb, 0, NULL},
-       {N_("/_Message/---"),                   NULL, NULL, 0, "<Separator>"},
        {N_("/_Message/M_ove..."),              "<control>O", move_to_cb, 0, NULL},
        {N_("/_Message/_Copy..."),              "<shift><control>O", copy_to_cb, 0, NULL},
        {N_("/_Message/_Delete"),               "<control>D", delete_cb,  0, NULL},
@@ -665,6 +658,8 @@ static GtkItemFactoryEntry mainwin_entries[] =
        {N_("/_Message/_Mark/Mark as rea_d"),
                                                NULL, mark_as_read_cb, 0, NULL},
        {N_("/_Message/_Mark/Mark all _read"),  NULL, mark_all_read_cb, 0, NULL},
+       {N_("/_Message/---"),                   NULL, NULL, 0, "<Separator>"},
+       {N_("/_Message/Re-_edit"),              NULL, reedit_cb, 0, NULL},
 
        {N_("/_Tools"),                         NULL, NULL, 0, "<Branch>"},
        {N_("/_Tools/_Address book..."),        "<shift><control>A", addressbook_open_cb, 0, NULL},
@@ -676,7 +671,10 @@ static GtkItemFactoryEntry mainwin_entries[] =
        {N_("/_Tools/_Harvest addresses/from _Messages..."),
                                                NULL, addr_harvest_msg_cb, 0, NULL},
        {N_("/_Tools/---"),                     NULL, NULL, 0, "<Separator>"},
-       {N_("/_Tools/_Filter messages"),                NULL, filter_cb, 0, NULL},
+       {N_("/_Tools/_Filter all messages in folder"),
+                                               NULL, filter_cb, 0, NULL},
+       {N_("/_Tools/Filter _selected messages"),
+                                               NULL, filter_cb, 1, NULL},
        {N_("/_Tools/_Create filter rule"),     NULL, NULL, 0, "<Branch>"},
        {N_("/_Tools/_Create filter rule/_Automatically"),
                                                NULL, create_filter_cb, FILTER_BY_AUTO, NULL},
@@ -698,8 +696,14 @@ static GtkItemFactoryEntry mainwin_entries[] =
        {N_("/_Tools/---"),                     NULL, NULL, 0, "<Separator>"},
        {N_("/_Tools/Actio_ns"),                NULL, NULL, 0, "<Branch>"},
        {N_("/_Tools/---"),                     NULL, NULL, 0, "<Separator>"},
+       {N_("/_Tools/_Check for new messages in all folders"),
+                                               NULL, update_folderview_cb, 0, NULL},
        {N_("/_Tools/Delete du_plicated messages"),
+                                               NULL, NULL, 0, "<Branch>"},
+       {N_("/_Tools/Delete du_plicated messages/In selected folder"),
                                                NULL, delete_duplicated_cb,   0, NULL},
+       {N_("/_Tools/Delete du_plicated messages/In all folders"),
+                                               NULL, delete_duplicated_all_cb,   0, NULL},
        {N_("/_Tools/---"),                     NULL, NULL, 0, "<Separator>"},
        {N_("/_Tools/E_xecute"),                "X", execute_summary_cb, 0, NULL},
 #ifdef USE_OPENSSL
@@ -779,6 +783,7 @@ MainWindow *main_window_create(SeparateType type)
        GtkWidget *menuitem;
        gint i;
        guint n_menu_entries;
+       gboolean hide_messageview = FALSE;
 
        static GdkGeometry geometry;
 
@@ -914,22 +919,22 @@ MainWindow *main_window_create(SeparateType type)
        summaryview->messageview = messageview;
        summaryview->window      = window;
 
-       mainwin->vbox         = vbox;
-       mainwin->menubar      = menubar;
-       mainwin->menu_factory = ifactory;
-       mainwin->handlebox    = handlebox;
-       mainwin->vbox_body    = vbox_body;
-       mainwin->hbox_stat    = hbox_stat;
-       mainwin->statusbar    = statusbar;
-       mainwin->progressbar  = progressbar;
-       mainwin->statuslabel  = statuslabel;
-       mainwin->ac_button    = ac_button;
-       mainwin->ac_label     = ac_label;
-       
-       mainwin->online_switch     = online_switch;
+       messageview->statusbar   = statusbar;
+       mainwin->vbox           = vbox;
+       mainwin->menubar        = menubar;
+       mainwin->menu_factory   = ifactory;
+       mainwin->handlebox      = handlebox;
+       mainwin->vbox_body      = vbox_body;
+       mainwin->hbox_stat      = hbox_stat;
+       mainwin->statusbar      = statusbar;
+       mainwin->progressbar    = progressbar;
+       mainwin->statuslabel    = statuslabel;
+       mainwin->online_switch  = online_switch;
+       mainwin->online_pixmap  = online_pixmap;
+       mainwin->offline_pixmap = offline_pixmap;
+       mainwin->ac_button      = ac_button;
+       mainwin->ac_label       = ac_label;
        mainwin->offline_switch    = offline_switch;
-       mainwin->online_pixmap     = online_pixmap;
-       mainwin->offline_pixmap    = offline_pixmap;
        
        /* set context IDs for status bar */
        mainwin->mainwin_cid = gtk_statusbar_get_context_id
@@ -941,6 +946,8 @@ MainWindow *main_window_create(SeparateType type)
        mainwin->messageview_cid = gtk_statusbar_get_context_id
                (GTK_STATUSBAR(statusbar), "Message View");
 
+       messageview->statusbar_cid = mainwin->messageview_cid;
+
        /* allocate colors for summary view and folder view */
        summaryview->color_marked.red = summaryview->color_marked.green = 0;
        summaryview->color_marked.blue = (guint16)65535;
@@ -973,7 +980,8 @@ MainWindow *main_window_create(SeparateType type)
        debug_print("done.\n");
 
        messageview->visible = prefs_common.msgview_visible;
-
+       hide_messageview = !messageview->visible;
+       
        main_window_set_widgets(mainwin, type);
 
        gtk_signal_connect(GTK_OBJECT(window), "size_allocate",
@@ -1010,14 +1018,6 @@ MainWindow *main_window_create(SeparateType type)
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
                                       prefs_common.show_statusbar);
        
-       gtk_widget_hide(GTK_WIDGET(mainwin->summaryview->hbox_search));
-       
-       if (prefs_common.show_searchbar) {
-               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mainwin->summaryview->toggle_search), TRUE);
-               if (prefs_common.summary_quicksearch_type != S_SEARCH_EXTENDED)
-                       gtk_widget_hide(summaryview->search_description);
-       }
-
        /* set account selection menu */
        ac_menu = gtk_item_factory_get_widget
                (ifactory, "/Configuration/Change current account");
@@ -1036,7 +1036,7 @@ MainWindow *main_window_create(SeparateType type)
                (GTK_WINDOW(win),                       \
                 gtk_item_factory_from_widget(menu)->accel_group)                
        
-       ADD_MENU_ACCEL_GROUP_TO_WINDOW(summaryview->popupmenu,mainwin->window);
+       ADD_MENU_ACCEL_GROUP_TO_WINDOW(summaryview->popupmenu, mainwin->window);
        
        /* connect the accelerators for equivalent 
           menu items in different menus             */
@@ -1073,6 +1073,9 @@ MainWindow *main_window_create(SeparateType type)
        if (prefs_common.work_offline)
                online_switch_clicked (GTK_BUTTON(online_switch), mainwin);
 
+       if (mainwin->type == SEPARATE_NONE && hide_messageview)
+               main_window_toggle_message_view(mainwin);
+
        return mainwin;
 }
 
@@ -1522,6 +1525,30 @@ void main_window_get_position(MainWindow *mainwin)
        }
 }
 
+void main_window_progress_on(MainWindow *mainwin)
+{
+       gtk_progress_set_show_text(GTK_PROGRESS(mainwin->progressbar), TRUE);
+       gtk_progress_set_format_string(GTK_PROGRESS(mainwin->progressbar), "");
+}
+
+void main_window_progress_off(MainWindow *mainwin)
+{
+       gtk_progress_set_show_text(GTK_PROGRESS(mainwin->progressbar), FALSE);
+       gtk_progress_bar_update(GTK_PROGRESS_BAR(mainwin->progressbar), 0.0);
+       gtk_progress_set_format_string(GTK_PROGRESS(mainwin->progressbar), "");
+}
+
+void main_window_progress_set(MainWindow *mainwin, gint cur, gint total)
+{
+       gchar buf[32];
+
+       g_snprintf(buf, sizeof(buf), "%d / %d", cur, total);
+       gtk_progress_set_format_string(GTK_PROGRESS(mainwin->progressbar), buf);
+       gtk_progress_bar_update(GTK_PROGRESS_BAR(mainwin->progressbar),
+                               (cur == 0 && total == 0) ? 0 :
+                               (gfloat)cur / (gfloat)total);
+}
+
 void main_window_empty_trash(MainWindow *mainwin, gboolean confirm)
 {
        GList *list;
@@ -1664,10 +1691,10 @@ void main_window_set_menu_sensitive(MainWindow *mainwin)
                gchar *const entry;
                SensitiveCond cond;
        } entry[] = {
-               {"/File/Folder"                               , M_UNLOCKED},
                {"/File/Add mailbox"                          , M_UNLOCKED},
 
                 {"/File/Add mailbox/MH..."                   , M_UNLOCKED},
+               {"/File/Change folder order"                  , M_UNLOCKED},
                {"/File/Export to mbox file..."               , M_UNLOCKED},
                {"/File/Empty trash"                          , M_UNLOCKED},
                {"/File/Work offline"                         , M_UNLOCKED},
@@ -1709,20 +1736,21 @@ void main_window_set_menu_sensitive(MainWindow *mainwin)
                {"/Message/Follow-up and reply to", M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST|M_NEWS},
                {"/Message/Forward"               , M_HAVE_ACCOUNT|M_TARGET_EXIST},
                {"/Message/Redirect"              , M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST},
-               {"/Message/Re-edit"               , M_HAVE_ACCOUNT|M_ALLOW_REEDIT},
                {"/Message/Move..."               , M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED},
                {"/Message/Copy..."               , M_TARGET_EXIST|M_EXEC|M_UNLOCKED},
                {"/Message/Delete"                , M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED|M_NOT_NEWS},
                {"/Message/Cancel a news message" , M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED|M_NEWS},
                {"/Message/Mark"                  , M_TARGET_EXIST},
+               {"/Message/Re-edit"              , M_HAVE_ACCOUNT|M_ALLOW_REEDIT},
 
-               {"/Tools/Add sender to address book", M_SINGLE_TARGET_EXIST},
-               {"/Tools/Harvest addresses"         , M_UNLOCKED},
-               {"/Tools/Filter messages"           , M_MSG_EXIST|M_EXEC|M_UNLOCKED},
-               {"/Tools/Create filter rule"        , M_SINGLE_TARGET_EXIST|M_UNLOCKED},
-               {"/Tools/Actions"                   , M_TARGET_EXIST|M_UNLOCKED},
-               {"/Tools/Execute"                   , M_DELAY_EXEC},
-               {"/Tools/Delete duplicated messages", M_MSG_EXIST|M_ALLOW_DELETE|M_UNLOCKED},
+               {"/Tools/Add sender to address book"   , M_SINGLE_TARGET_EXIST},
+               {"/Tools/Harvest addresses"            , M_UNLOCKED},
+               {"/Tools/Filter all messages in folder", M_MSG_EXIST|M_EXEC|M_UNLOCKED},
+               {"/Tools/Filter selected messages"     , M_TARGET_EXIST|M_EXEC|M_UNLOCKED},
+               {"/Tools/Create filter rule"           , M_SINGLE_TARGET_EXIST|M_UNLOCKED},
+               {"/Tools/Actions"                      , M_TARGET_EXIST|M_UNLOCKED},
+               {"/Tools/Execute"                      , M_DELAY_EXEC},
+               {"/Tools/Delete duplicated messages/In selected folder"   , M_MSG_EXIST|M_ALLOW_DELETE|M_UNLOCKED},
 
                {"/Configuration", M_UNLOCKED},
 
@@ -2080,10 +2108,6 @@ static void main_window_set_widgets(MainWindow *mainwin, SeparateType type)
        else 
                gtk_widget_hide(mainwin->messageview->mimeview->ctree_mainbox);
 
-       /* rehide quick search if necessary */
-       if (!prefs_common.show_searchbar)
-               gtk_widget_hide(mainwin->summaryview->hbox_search);
-       
        mainwin->type = type;
 
 
@@ -2280,22 +2304,10 @@ static void update_folderview_cb(MainWindow *mainwin, guint action,
        folderview_check_new_all();
 }
 
-static void new_folder_cb(MainWindow *mainwin, guint action,
-                         GtkWidget *widget)
-{
-       folderview_new_folder(mainwin->folderview);
-}
-
-static void rename_folder_cb(MainWindow *mainwin, guint action,
-                            GtkWidget *widget)
-{
-       folderview_rename_folder(mainwin->folderview);
-}
-
-static void delete_folder_cb(MainWindow *mainwin, guint action,
-                            GtkWidget *widget)
+static void foldersort_cb(MainWindow *mainwin, guint action,
+                           GtkWidget *widget)
 {
-       folderview_delete_folder(mainwin->folderview);
+       foldersort_open();
 }
 
 static void import_mbox_cb(MainWindow *mainwin, guint action,
@@ -2545,11 +2557,6 @@ static void show_all_header_cb(MainWindow *mainwin, guint action,
                                     GTK_CHECK_MENU_ITEM(widget)->active);
 }
 
-static void reedit_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
-{
-       summary_reedit(mainwin->summaryview);
-}
-
 static void mark_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
 {
        summary_mark(mainwin->summaryview);
@@ -2578,6 +2585,11 @@ static void mark_all_read_cb(MainWindow *mainwin, guint action,
        summary_mark_all_read(mainwin->summaryview);
 }
 
+static void reedit_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
+{
+       summary_reedit(mainwin->summaryview);
+}
+
 static void add_address_cb(MainWindow *mainwin, guint action,
                           GtkWidget *widget)
 {
@@ -2679,12 +2691,52 @@ static void attract_by_subject_cb(MainWindow *mainwin, guint action,
 static void delete_duplicated_cb(MainWindow *mainwin, guint action,
                                 GtkWidget *widget)
 {
-       summary_delete_duplicated(mainwin->summaryview);
+       FolderItem *item;
+
+       item = folderview_get_selected(mainwin->folderview);
+       if (item) {
+               main_window_cursor_wait(mainwin);
+               STATUSBAR_PUSH(mainwin, _("Deleting duplicated messages..."));
+
+               folderutils_delete_duplicates(item, prefs_common.immediate_exec ?
+                                             DELETE_DUPLICATES_REMOVE : DELETE_DUPLICATES_SETFLAG);
+
+               STATUSBAR_POP(mainwin);
+               main_window_cursor_normal(mainwin);
+       }
+}
+
+struct DelDupsData
+{
+       guint   dups;
+       guint   folders;
+};
+
+static void deldup_all(FolderItem *item, gpointer _data)
+{
+       struct DelDupsData *data = _data;
+       gint result;
+       
+       result = folderutils_delete_duplicates(item, DELETE_DUPLICATES_REMOVE);
+       if (result >= 0) {
+               data->dups += result;
+               data->folders += 1;
+       }
+}
+
+static void delete_duplicated_all_cb(MainWindow *mainwin, guint action,
+                                GtkWidget *widget)
+{
+       struct DelDupsData data = {0, 0};
+
+       folder_func_to_all_folders(deldup_all, &data);
+       alertpanel_notice(_("Deleted %d duplicate message(s) in %d folders.\n"),
+                         data.dups, data.folders);
 }
 
 static void filter_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
 {
-       summary_filter(mainwin->summaryview);
+       summary_filter(mainwin->summaryview, (gboolean)action);
 }
 
 static void execute_summary_cb(MainWindow *mainwin, guint action,
@@ -3031,4 +3083,3 @@ gboolean mainwindow_progressindicator_hook(gpointer source, gpointer userdata)
 /*
 * End of Source.
 */
-