remove gtk_window_set_wmclass()
[claws.git] / src / foldersel.c
index 8a4045993459f7428e5f4096da0fd7c239fac740..70ecb77d34549f3ba7656ed6bcbf0da060e3d799 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2001 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2004 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
@@ -23,7 +23,6 @@
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtkmain.h>
 #include <gtk/gtkwidget.h>
-#include <gtk/gtkctree.h>
 #include <gtk/gtkwindow.h>
 #include <gtk/gtkvbox.h>
 #include <gtk/gtkscrolledwindow.h>
 #include "main.h"
 #include "utils.h"
 #include "gtkutils.h"
+#include "gtksctree.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;
@@ -62,26 +60,46 @@ static GtkWidget *ok_button;
 static GtkWidget *cancel_button;
 
 static FolderItem *folder_item;
+static FolderItem *selected_item;
 
 static gboolean cancelled;
-
-static void foldersel_create(void);
-static void foldersel_init(void);
-static void foldersel_set_tree(Folder *cur_folder);
-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 gboolean finished;
+
+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 gboolean 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;
 
+       selected_item = NULL;
+
        if (!window) {
                foldersel_create();
                foldersel_init();
@@ -89,7 +107,7 @@ FolderItem *foldersel_folder_sel(Folder *cur_folder,
                gtk_widget_show(window);
        manage_window_set_transient(GTK_WINDOW(window));
 
-       foldersel_set_tree(cur_folder);
+       foldersel_set_tree(cur_folder, type);
 
        if (folder_item) {
                node = gtk_ctree_find_by_row_data
@@ -108,17 +126,20 @@ FolderItem *foldersel_folder_sel(Folder *cur_folder,
        gtk_widget_grab_focus(ok_button);
        gtk_widget_grab_focus(ctree);
 
-       cancelled = FALSE;
+       cancelled = finished = FALSE;
 
-       gtk_main();
+       while (finished == FALSE)
+               gtk_main_iteration();
 
        gtk_widget_hide(window);
        gtk_entry_set_text(GTK_ENTRY(entry), "");
        gtk_clist_clear(GTK_CLIST(ctree));
 
-       if (!cancelled && folder_item && folder_item->path)
+       if (!cancelled &&
+           selected_item && selected_item->path) {
+               folder_item = selected_item;
                return folder_item;
-       else
+       else
                return NULL;
 }
 
@@ -128,26 +149,23 @@ static void foldersel_create(void)
        GtkWidget *scrolledwin;
        GtkWidget *confirm_area;
 
-       window = gtk_window_new(GTK_WINDOW_DIALOG);
+       window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(window), _("Select folder"));
-       gtk_widget_set_usize(window, 300, 400);
-       gtk_container_set_border_width(GTK_CONTAINER(window), BORDER_WIDTH);
+       gtk_container_set_border_width(GTK_CONTAINER(window), 4);
        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_signal_connect(GTK_OBJECT(window), "delete_event",
-                          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);
+       gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
+       g_signal_connect(G_OBJECT(window), "delete_event",
+                        G_CALLBACK(delete_event), NULL);
+       g_signal_connect(G_OBJECT(window), "key_press_event",
+                        G_CALLBACK(key_pressed), NULL);
+       MANAGE_WINDOW_SIGNALS_CONNECT(window);
 
        vbox = gtk_vbox_new(FALSE, 4);
        gtk_container_add(GTK_CONTAINER(window), vbox);
 
        scrolledwin = gtk_scrolled_window_new(NULL, NULL);
+       gtk_widget_set_size_request(window, 300, 360);
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
                                       GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
        gtk_box_pack_start(GTK_BOX(vbox), scrolledwin, TRUE, TRUE, 0);
@@ -161,39 +179,42 @@ 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), "select_row",
-                          GTK_SIGNAL_FUNC(foldersel_selected), NULL);
+       /* g_signal_connect(G_OBJECT(ctree), "tree_select_row",
+                           G_CALLBACK(foldersel_selected), NULL); */
+       g_signal_connect(G_OBJECT(ctree), "select_row",
+                        G_CALLBACK(foldersel_selected), NULL);
 
        entry = gtk_entry_new();
+       gtk_entry_set_editable(GTK_ENTRY(entry), FALSE);
        gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
-       gtk_signal_connect(GTK_OBJECT(entry), "activate",
-                          GTK_SIGNAL_FUNC(foldersel_activated), NULL);
+       g_signal_connect(G_OBJECT(entry), "activate",
+                        G_CALLBACK(foldersel_activated), NULL);
 
        gtkut_button_set_create(&confirm_area,
                                &ok_button,     _("OK"),
                                &cancel_button, _("Cancel"),
-                               NULL, NULL);
+                               NULL,           NULL);
 
        gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
        gtk_widget_grab_default(ok_button);
 
-       gtk_signal_connect(GTK_OBJECT(ok_button), "clicked",
-                          GTK_SIGNAL_FUNC(foldersel_ok), NULL);
-       gtk_signal_connect(GTK_OBJECT(cancel_button), "clicked",
-                          GTK_SIGNAL_FUNC(foldersel_cancel), NULL);
+       g_signal_connect(G_OBJECT(ok_button), "clicked",
+                        G_CALLBACK(foldersel_ok), NULL);
+       g_signal_connect(G_OBJECT(cancel_button), "clicked",
+                        G_CALLBACK(foldersel_cancel), NULL);
 
        gtk_widget_show_all(window);
 }
 
 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,
@@ -201,14 +222,19 @@ static gboolean foldersel_gnode_func(GtkCTree *ctree, guint depth,
                                     gpointer data)
 {
        FolderItem *item = FOLDER_ITEM(gnode->data);
+       gchar *name;
+
+       name = folder_item_get_name(item);
 
        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,
                                FALSE, FALSE);
 
+       g_free(name);
+
        return TRUE;
 }
 
@@ -219,7 +245,31 @@ static void foldersel_expand_func(GtkCTree *ctree, GtkCTreeNode *node,
                gtk_ctree_expand(ctree, node);
 }
 
-static void foldersel_set_tree(Folder *cur_folder)
+#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;
@@ -230,23 +280,26 @@ static void foldersel_set_tree(Folder *cur_folder)
        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_NEWS) continue;
-               if (cur_folder) {
-                       if (cur_folder->type != folder->type) continue;
-                       if (cur_folder->type == F_IMAP) {
-                               if (cur_folder->account != folder->account)
-                                       continue;
-                       }
+               if (type != FOLDER_SEL_ALL) {
+                       if (FOLDER_TYPE(folder) == 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);
+               gtk_sctree_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);
@@ -258,12 +311,16 @@ static void foldersel_set_tree(Folder *cur_folder)
 static void foldersel_selected(GtkCList *clist, gint row, gint column,
                               GdkEvent *event, gpointer data)
 {
-       FolderItem *item;
        GdkEventButton *ev = (GdkEventButton *)event;
 
-       item = gtk_clist_get_row_data(clist, row);
-       if (item) gtk_entry_set_text(GTK_ENTRY(entry),
-                                    item->path ? item->path : "");
+       selected_item = gtk_clist_get_row_data(clist, row);
+       if (selected_item && selected_item->path) {
+               gchar *id;
+               id = folder_item_get_identifier(selected_item);
+               gtk_entry_set_text(GTK_ENTRY(entry), id);
+               g_free(id);
+       } else
+               gtk_entry_set_text(GTK_ENTRY(entry), "");
 
        if (ev && GDK_2BUTTON_PRESS == ev->type)
                gtk_button_clicked(GTK_BUTTON(ok_button));
@@ -271,20 +328,13 @@ static void foldersel_selected(GtkCList *clist, gint row, gint column,
 
 static void foldersel_ok(GtkButton *button, gpointer data)
 {
-       GList *list;
-
-       list = GTK_CLIST(ctree)->selection;
-       if (list)
-               folder_item = gtk_ctree_node_get_row_data
-                       (GTK_CTREE(ctree), GTK_CTREE_NODE(list->data));
-
-       gtk_main_quit();
+       finished = TRUE;
 }
 
 static void foldersel_cancel(GtkButton *button, gpointer data)
 {
        cancelled = TRUE;
-       gtk_main_quit();
+       finished = TRUE;
 }
 
 static void foldersel_activated(void)
@@ -298,8 +348,23 @@ static gint delete_event(GtkWidget *widget, GdkEventAny *event, gpointer data)
        return TRUE;
 }
 
-static void key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
+static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
 {
        if (event && event->keyval == GDK_Escape)
                foldersel_cancel(NULL, NULL);
+       return FALSE;
+}
+
+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);
 }