sync with 0.7.6cvs4
[claws.git] / src / foldersel.c
index 22285e38ba3deac07e8367a0e562fcbbcf354e76..be3b84c204bcaf6c6f104337501bf9564d2461de 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999,2000 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2002 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include "main.h"
 #include "utils.h"
 #include "gtkutils.h"
+#include "stock_pixmap.h"
 #include "foldersel.h"
 #include "alertpanel.h"
 #include "manage_window.h"
 #include "folder.h"
 
-#include "pixmaps/dir-close.xpm"
-#include "pixmaps/dir-open.xpm"
-
 static GdkPixmap *folderxpm;
 static GdkBitmap *folderxpmmask;
 static GdkPixmap *folderopenxpm;
@@ -65,18 +63,36 @@ static FolderItem *folder_item;
 
 static gboolean cancelled;
 
-static void foldersel_create(void);
-static void foldersel_init(void);
-static void foldersel_set_tree(void);
-static void foldersel_selected(GtkCList *clist, gint row, gint column,
-                              GdkEvent *event, gpointer data);
-
-static void foldersel_ok(GtkButton *button, gpointer data);
-static void foldersel_cancel(GtkButton *button, gpointer data);
-static void foldersel_activated(void);
-static void key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data);
-
-FolderItem *foldersel_folder_sel(const gchar *default_folder)
+static void foldersel_create   (void);
+static void foldersel_init     (void);
+static void foldersel_set_tree (Folder                 *cur_folder,
+                                FolderSelectionType     type);
+
+static void foldersel_selected (GtkCList       *clist,
+                                gint            row,
+                                gint            column,
+                                GdkEvent       *event,
+                                gpointer        data);
+
+static void foldersel_ok       (GtkButton      *button,
+                                gpointer        data);
+static void foldersel_cancel   (GtkButton      *button,
+                                gpointer        data);
+static void foldersel_activated        (void);
+static gint delete_event       (GtkWidget      *widget,
+                                GdkEventAny    *event,
+                                gpointer        data);
+static void key_pressed                (GtkWidget      *widget,
+                                GdkEventKey    *event,
+                                gpointer        data);
+
+static gint foldersel_clist_compare    (GtkCList       *clist,
+                                        gconstpointer   ptr1,
+                                        gconstpointer   ptr2);
+
+FolderItem *foldersel_folder_sel(Folder *cur_folder,
+                                FolderSelectionType type,
+                                const gchar *default_folder)
 {
        GtkCTreeNode *node;
 
@@ -87,7 +103,7 @@ FolderItem *foldersel_folder_sel(const gchar *default_folder)
                gtk_widget_show(window);
        manage_window_set_transient(GTK_WINDOW(window));
 
-       foldersel_set_tree();
+       foldersel_set_tree(cur_folder, type);
 
        if (folder_item) {
                node = gtk_ctree_find_by_row_data
@@ -133,14 +149,13 @@ static void foldersel_create(void)
        gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
        gtk_window_set_modal(GTK_WINDOW(window), TRUE);
        gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, TRUE);
+       gtk_window_set_wmclass
+               (GTK_WINDOW(window), "folder_selection", "Sylpheed");
        gtk_signal_connect(GTK_OBJECT(window), "delete_event",
-                          GTK_SIGNAL_FUNC(foldersel_cancel), NULL);
+                          GTK_SIGNAL_FUNC(delete_event), NULL);
        gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
                           GTK_SIGNAL_FUNC(key_pressed), NULL);
-       gtk_signal_connect(GTK_OBJECT(window), "focus_in_event",
-                          GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
-       gtk_signal_connect(GTK_OBJECT(window), "focus_out_event",
-                          GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
+       MANAGE_WINDOW_SIGNALS_CONNECT(window);
 
        vbox = gtk_vbox_new(FALSE, 4);
        gtk_container_add(GTK_CONTAINER(window), vbox);
@@ -159,10 +174,11 @@ static void foldersel_create(void)
        gtk_ctree_set_expander_style(GTK_CTREE(ctree),
                                     GTK_CTREE_EXPANDER_SQUARE);
        gtk_ctree_set_indent(GTK_CTREE(ctree), CTREE_INDENT);
+       gtk_clist_set_compare_func(GTK_CLIST(ctree), foldersel_clist_compare);
        GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(ctree)->column[0].button,
                               GTK_CAN_FOCUS);
-       //gtk_signal_connect(GTK_OBJECT(ctree), "tree_select_row",
-       //                 GTK_SIGNAL_FUNC(foldersel_selected), NULL);
+       /gtk_signal_connect(GTK_OBJECT(ctree), "tree_select_row",
+                          GTK_SIGNAL_FUNC(foldersel_selected), NULL); */
        gtk_signal_connect(GTK_OBJECT(ctree), "select_row",
                           GTK_SIGNAL_FUNC(foldersel_selected), NULL);
 
@@ -189,9 +205,10 @@ static void foldersel_create(void)
 
 static void foldersel_init(void)
 {
-       PIXMAP_CREATE(ctree, folderxpm, folderxpmmask, DIRECTORY_CLOSE_XPM);
-       PIXMAP_CREATE(ctree, folderopenxpm, folderopenxpmmask,
-                     DIRECTORY_OPEN_XPM);
+       stock_pixmap_gdk(ctree, STOCK_PIXMAP_DIR_CLOSE,
+                        &folderxpm, &folderxpmmask);
+       stock_pixmap_gdk(ctree, STOCK_PIXMAP_DIR_OPEN,
+                        &folderopenxpm, &folderopenxpmmask);
 }
 
 static gboolean foldersel_gnode_func(GtkCTree *ctree, guint depth,
@@ -199,9 +216,45 @@ static gboolean foldersel_gnode_func(GtkCTree *ctree, guint depth,
                                     gpointer data)
 {
        FolderItem *item = FOLDER_ITEM(gnode->data);
+       gchar *name;
+
+       switch (item->stype) {
+       case F_INBOX:
+               name = _("Inbox");
+               break;
+       case F_OUTBOX:
+               name = _("Sent");
+               break;
+       case F_QUEUE:
+               name = _("Queue");
+               break;
+       case F_TRASH:
+               name = _("Trash");
+               break;
+       case F_DRAFT:
+               name = _("Drafts");
+               break;
+       default:
+               name = item->name;
+
+               if (!item->parent) {
+                       switch (item->folder->type) {
+                       case F_MBOX:
+                               Xstrcat_a(name, name, " (MBOX)", ); break;
+                       case F_MH:
+                               Xstrcat_a(name, name, " (MH)", ); break;
+                       case F_IMAP:
+                               Xstrcat_a(name, name, " (IMAP4)", ); break;
+                       case F_NEWS:
+                               Xstrcat_a(name, name, " (News)", ); break;
+                       default:
+                               break;
+                       }
+               }
+       }
 
        gtk_ctree_node_set_row_data(ctree, cnode, item);
-       gtk_ctree_set_node_info(ctree, cnode, item->name,
+       gtk_ctree_set_node_info(ctree, cnode, name,
                                FOLDER_SPACING,
                                folderxpm, folderxpmmask,
                                folderopenxpm, folderopenxpmmask,
@@ -217,7 +270,31 @@ static void foldersel_expand_func(GtkCTree *ctree, GtkCTreeNode *node,
                gtk_ctree_expand(ctree, node);
 }
 
-static void foldersel_set_tree(void)
+#define SET_SPECIAL_FOLDER(item) \
+{ \
+       if (item) { \
+               GtkCTreeNode *node_, *parent, *sibling; \
+ \
+               node_ = gtk_ctree_find_by_row_data \
+                       (GTK_CTREE(ctree), node, item); \
+               if (!node_) \
+                       g_warning("%s not found.\n", item->path); \
+               else { \
+                       parent = GTK_CTREE_ROW(node_)->parent; \
+                       if (prev && parent == GTK_CTREE_ROW(prev)->parent) \
+                               sibling = GTK_CTREE_ROW(prev)->sibling; \
+                       else \
+                               sibling = GTK_CTREE_ROW(parent)->children; \
+                       if (node_ != sibling) \
+                               gtk_ctree_move(GTK_CTREE(ctree), \
+                                              node_, parent, sibling); \
+               } \
+ \
+               prev = node_; \
+       } \
+}
+
+static void foldersel_set_tree(Folder *cur_folder, FolderSelectionType type)
 {
        Folder *folder;
        GtkCTreeNode *node;
@@ -228,16 +305,26 @@ static void foldersel_set_tree(void)
        gtk_clist_freeze(GTK_CLIST(ctree));
 
        for (; list != NULL; list = list->next) {
+               GtkCTreeNode *prev = NULL;
+
                folder = FOLDER(list->data);
                g_return_if_fail(folder != NULL);
 
-               if (folder->type != F_MH) continue;
+               if (type != FOLDER_SEL_ALL) {
+                       if (folder->type == F_NEWS)
+                               continue;
+               }
 
                node = gtk_ctree_insert_gnode(GTK_CTREE(ctree), NULL, NULL,
                                              folder->node,
                                              foldersel_gnode_func,
                                              NULL);
                gtk_ctree_sort_recursive(GTK_CTREE(ctree), node);
+               SET_SPECIAL_FOLDER(folder->inbox);
+               SET_SPECIAL_FOLDER(folder->outbox);
+               SET_SPECIAL_FOLDER(folder->draft);
+               SET_SPECIAL_FOLDER(folder->queue);
+               SET_SPECIAL_FOLDER(folder->trash);
                gtk_ctree_pre_recursive(GTK_CTREE(ctree), node,
                                        foldersel_expand_func,
                                        NULL);
@@ -283,8 +370,28 @@ static void foldersel_activated(void)
        gtk_button_clicked(GTK_BUTTON(ok_button));
 }
 
+static gint delete_event(GtkWidget *widget, GdkEventAny *event, gpointer data)
+{
+       foldersel_cancel(NULL, NULL);
+       return TRUE;
+}
+
 static void key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
 {
        if (event && event->keyval == GDK_Escape)
                foldersel_cancel(NULL, NULL);
 }
+
+static gint foldersel_clist_compare(GtkCList *clist,
+                                   gconstpointer ptr1, gconstpointer ptr2)
+{
+       FolderItem *item1 = ((GtkCListRow *)ptr1)->data;
+       FolderItem *item2 = ((GtkCListRow *)ptr2)->data;
+
+       if (!item1->name)
+               return (item2->name != NULL);
+       if (!item2->name)
+               return -1;
+
+       return g_strcasecmp(item1->name, item2->name);
+}