Statistics
| Revision:

root / src / foldersel.c @ 1124

History | View | Annotate | Download (17.6 kB)

1 1 hiro
/*
2 1 hiro
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 1070 hiro
 * Copyright (C) 1999-2006 Hiroyuki Yamamoto
4 1 hiro
 *
5 1 hiro
 * This program is free software; you can redistribute it and/or modify
6 1 hiro
 * it under the terms of the GNU General Public License as published by
7 1 hiro
 * the Free Software Foundation; either version 2 of the License, or
8 1 hiro
 * (at your option) any later version.
9 1 hiro
 *
10 1 hiro
 * This program is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 1 hiro
 * GNU General Public License for more details.
14 1 hiro
 *
15 1 hiro
 * You should have received a copy of the GNU General Public License
16 1 hiro
 * along with this program; if not, write to the Free Software
17 1 hiro
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 1 hiro
 */
19 1 hiro
20 1 hiro
#include "defs.h"
21 1 hiro
22 1 hiro
#include <glib.h>
23 92 hiro
#include <glib/gi18n.h>
24 1 hiro
#include <gdk/gdkkeysyms.h>
25 1 hiro
#include <gtk/gtkmain.h>
26 1 hiro
#include <gtk/gtkwidget.h>
27 189 hiro
#include <gtk/gtktreestore.h>
28 189 hiro
#include <gtk/gtktreeview.h>
29 237 hiro
#include <gtk/gtktreeselection.h>
30 237 hiro
#include <gtk/gtkcellrendererpixbuf.h>
31 237 hiro
#include <gtk/gtkcellrenderertext.h>
32 1 hiro
#include <gtk/gtkwindow.h>
33 1 hiro
#include <gtk/gtkvbox.h>
34 1 hiro
#include <gtk/gtkscrolledwindow.h>
35 1 hiro
#include <gtk/gtkentry.h>
36 1 hiro
#include <gtk/gtkhbbox.h>
37 1 hiro
#include <gtk/gtksignal.h>
38 237 hiro
#include <gtk/gtkstock.h>
39 1 hiro
#include <stdio.h>
40 1 hiro
#include <unistd.h>
41 1 hiro
#include <string.h>
42 1 hiro
#include <sys/stat.h>
43 1 hiro
#include <sys/types.h>
44 1 hiro
#include <fcntl.h>
45 1 hiro
#include <errno.h>
46 1 hiro
47 1 hiro
#include "main.h"
48 1 hiro
#include "utils.h"
49 1 hiro
#include "gtkutils.h"
50 1 hiro
#include "stock_pixmap.h"
51 1 hiro
#include "foldersel.h"
52 1 hiro
#include "alertpanel.h"
53 1 hiro
#include "manage_window.h"
54 1 hiro
#include "folderview.h"
55 1 hiro
#include "inputdialog.h"
56 1 hiro
#include "folder.h"
57 405 hiro
#include "prefs_common.h"
58 1 hiro
59 189 hiro
enum {
60 189 hiro
        FOLDERSEL_FOLDERNAME,
61 189 hiro
        FOLDERSEL_FOLDERITEM,
62 189 hiro
        FOLDERSEL_PIXBUF,
63 189 hiro
        FOLDERSEL_PIXBUF_OPEN,
64 426 hiro
        FOLDERSEL_FOREGROUND,
65 426 hiro
        FOLDERSEL_BOLD,
66 189 hiro
        N_FOLDERSEL_COLUMNS
67 189 hiro
};
68 1 hiro
69 189 hiro
typedef struct _FolderItemSearch        FolderItemSearch;
70 189 hiro
71 189 hiro
struct _FolderItemSearch
72 189 hiro
{
73 189 hiro
        FolderItem *item;
74 189 hiro
        GtkTreePath *path;
75 189 hiro
        GtkTreeIter iter;
76 189 hiro
};
77 189 hiro
78 189 hiro
static GdkPixbuf *folder_pixbuf;
79 189 hiro
static GdkPixbuf *folderopen_pixbuf;
80 189 hiro
static GdkPixbuf *foldernoselect_pixbuf;
81 189 hiro
82 1 hiro
static GtkWidget *window;
83 189 hiro
static GtkWidget *treeview;
84 1 hiro
static GtkWidget *entry;
85 405 hiro
static GtkWidget *confirm_area;
86 1 hiro
static GtkWidget *ok_button;
87 1 hiro
static GtkWidget *cancel_button;
88 1 hiro
static GtkWidget *new_button;
89 1 hiro
90 389 hiro
static GtkTreeStore *tree_store;
91 389 hiro
92 1 hiro
static FolderItem *folder_item;
93 1 hiro
static FolderItem *selected_item;
94 1 hiro
95 389 hiro
FolderSelectionType sel_type;
96 189 hiro
97 1 hiro
static gboolean cancelled;
98 1 hiro
static gboolean finished;
99 1 hiro
100 189 hiro
static void foldersel_create                (void);
101 189 hiro
static void foldersel_init                (void);
102 1 hiro
103 189 hiro
static void foldersel_append_item        (GtkTreeStore        *store,
104 189 hiro
                                         FolderItem        *item,
105 189 hiro
                                         GtkTreeIter        *iter,
106 189 hiro
                                         GtkTreeIter        *parent);
107 1 hiro
108 389 hiro
static void foldersel_set_tree                (Folder                *cur_folder);
109 1 hiro
110 189 hiro
static gboolean foldersel_selected        (GtkTreeSelection *selection,
111 189 hiro
                                         GtkTreeModel          *model,
112 189 hiro
                                         GtkTreePath          *path,
113 189 hiro
                                         gboolean           currently_selected,
114 189 hiro
                                         gpointer           data);
115 1 hiro
116 189 hiro
static void foldersel_ok                (GtkButton        *button,
117 189 hiro
                                         gpointer         data);
118 189 hiro
static void foldersel_cancel                (GtkButton        *button,
119 189 hiro
                                         gpointer         data);
120 189 hiro
static void foldersel_new_folder        (GtkButton        *button,
121 189 hiro
                                         gpointer         data);
122 189 hiro
123 189 hiro
static void foldersel_entry_activated        (GtkEntry        *entry,
124 189 hiro
                                         gpointer         data);
125 189 hiro
126 189 hiro
static void foldersel_tree_activated        (GtkTreeView                *treeview,
127 189 hiro
                                         GtkTreePath                *path,
128 189 hiro
                                         GtkTreeViewColumn        *column,
129 189 hiro
                                         gpointer                 data);
130 189 hiro
131 189 hiro
static gint delete_event                (GtkWidget        *widget,
132 189 hiro
                                         GdkEventAny        *event,
133 189 hiro
                                         gpointer         data);
134 189 hiro
static gboolean key_pressed                (GtkWidget        *widget,
135 189 hiro
                                         GdkEventKey        *event,
136 189 hiro
                                         gpointer         data);
137 189 hiro
138 189 hiro
static gint foldersel_folder_name_compare        (GtkTreeModel        *model,
139 189 hiro
                                                 GtkTreeIter        *a,
140 189 hiro
                                                 GtkTreeIter        *b,
141 189 hiro
                                                 gpointer         context);
142 189 hiro
143 189 hiro
static gboolean tree_view_folder_item_func        (GtkTreeModel          *model,
144 189 hiro
                                                 GtkTreePath          *path,
145 189 hiro
                                                 GtkTreeIter          *iter,
146 189 hiro
                                                 FolderItemSearch *data);
147 189 hiro
148 189 hiro
FolderItem *foldersel_folder_sel(Folder *cur_folder, FolderSelectionType type,
149 1 hiro
                                 const gchar *default_folder)
150 1 hiro
{
151 1 hiro
        selected_item = NULL;
152 389 hiro
        sel_type = type;
153 1 hiro
154 1 hiro
        if (!window) {
155 1 hiro
                foldersel_create();
156 1 hiro
                foldersel_init();
157 189 hiro
        }
158 1 hiro
159 389 hiro
        foldersel_set_tree(cur_folder);
160 1 hiro
161 189 hiro
        /* select current */
162 1 hiro
        if (folder_item) {
163 189 hiro
                FolderItemSearch fis;
164 1 hiro
165 189 hiro
                fis.item = folder_item;
166 189 hiro
                fis.path = NULL;
167 189 hiro
168 189 hiro
                /* find matching model entry */
169 189 hiro
                gtk_tree_model_foreach
170 189 hiro
                        (GTK_TREE_MODEL(tree_store),
171 189 hiro
                         (GtkTreeModelForeachFunc)tree_view_folder_item_func,
172 189 hiro
                         &fis);
173 189 hiro
174 189 hiro
                if (fis.path) {
175 189 hiro
                        GtkTreeSelection *selection;
176 189 hiro
177 189 hiro
                        selection = gtk_tree_view_get_selection
178 189 hiro
                                (GTK_TREE_VIEW(treeview));
179 189 hiro
                        gtk_tree_selection_select_iter(selection, &fis.iter);
180 189 hiro
                        gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview),
181 189 hiro
                                                 fis.path, NULL, FALSE);
182 189 hiro
                        gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(treeview),
183 189 hiro
                                                     fis.path,
184 189 hiro
                                                     NULL, TRUE, 0.5, 0.0);
185 189 hiro
                        gtk_tree_path_free(fis.path);
186 189 hiro
                } else
187 189 hiro
                        gtk_tree_view_scroll_to_point
188 189 hiro
                                (GTK_TREE_VIEW(treeview), 0, 0);
189 189 hiro
        } else
190 189 hiro
                gtk_tree_view_scroll_to_point(GTK_TREE_VIEW(treeview), 0, 0);
191 189 hiro
192 405 hiro
        gtkut_box_set_reverse_order(GTK_BOX(confirm_area),
193 405 hiro
                                    !prefs_common.comply_gnome_hig);
194 1 hiro
        gtk_widget_grab_focus(ok_button);
195 189 hiro
        gtk_widget_grab_focus(treeview);
196 1 hiro
197 923 hiro
        manage_window_set_transient(GTK_WINDOW(window));
198 189 hiro
        gtk_widget_show(window);
199 189 hiro
200 1 hiro
        cancelled = finished = FALSE;
201 1 hiro
202 1 hiro
        while (finished == FALSE)
203 1 hiro
                gtk_main_iteration();
204 1 hiro
205 1 hiro
        gtk_widget_hide(window);
206 1 hiro
        gtk_entry_set_text(GTK_ENTRY(entry), "");
207 189 hiro
        gtk_tree_store_clear(tree_store);
208 1 hiro
209 389 hiro
        if (cancelled || !selected_item)
210 389 hiro
                return NULL;
211 389 hiro
212 817 hiro
        if (type == FOLDER_SEL_ALL || type == FOLDER_SEL_MOVE_FOLDER ||
213 389 hiro
            (selected_item->path && !selected_item->no_select)) {
214 1 hiro
                folder_item = selected_item;
215 1 hiro
                return folder_item;
216 389 hiro
        }
217 389 hiro
218 389 hiro
        return NULL;
219 1 hiro
}
220 1 hiro
221 1 hiro
static void foldersel_create(void)
222 1 hiro
{
223 1 hiro
        GtkWidget *vbox;
224 1 hiro
        GtkWidget *scrolledwin;
225 189 hiro
        GtkTreeViewColumn *column;
226 189 hiro
        GtkCellRenderer *renderer;
227 189 hiro
        GtkTreeSelection *selection;
228 1 hiro
229 1 hiro
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
230 1 hiro
        gtk_window_set_title(GTK_WINDOW(window), _("Select folder"));
231 1 hiro
        gtk_container_set_border_width(GTK_CONTAINER(window), 4);
232 923 hiro
        gtk_window_set_position(GTK_WINDOW(window),
233 923 hiro
                                GTK_WIN_POS_CENTER_ON_PARENT);
234 1 hiro
        gtk_window_set_modal(GTK_WINDOW(window), TRUE);
235 1 hiro
        gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE);
236 1 hiro
        gtk_window_set_wmclass
237 1 hiro
                (GTK_WINDOW(window), "folder_selection", "Sylpheed");
238 189 hiro
        gtk_widget_realize(window);
239 1 hiro
        g_signal_connect(G_OBJECT(window), "delete_event",
240 1 hiro
                         G_CALLBACK(delete_event), NULL);
241 1 hiro
        g_signal_connect(G_OBJECT(window), "key_press_event",
242 1 hiro
                         G_CALLBACK(key_pressed), NULL);
243 1 hiro
        MANAGE_WINDOW_SIGNALS_CONNECT(window);
244 1 hiro
245 1 hiro
        vbox = gtk_vbox_new(FALSE, 4);
246 1 hiro
        gtk_container_add(GTK_CONTAINER(window), vbox);
247 1 hiro
248 1 hiro
        scrolledwin = gtk_scrolled_window_new(NULL, NULL);
249 1 hiro
        gtk_widget_set_size_request(scrolledwin, 300, 360);
250 1 hiro
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
251 189 hiro
                                       GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
252 189 hiro
        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwin),
253 189 hiro
                                            GTK_SHADOW_IN);
254 1 hiro
        gtk_box_pack_start(GTK_BOX(vbox), scrolledwin, TRUE, TRUE, 0);
255 1 hiro
256 189 hiro
        tree_store = gtk_tree_store_new(N_FOLDERSEL_COLUMNS,
257 189 hiro
                                        G_TYPE_STRING,
258 189 hiro
                                        G_TYPE_POINTER,
259 189 hiro
                                        GDK_TYPE_PIXBUF,
260 189 hiro
                                        GDK_TYPE_PIXBUF,
261 426 hiro
                                        GDK_TYPE_COLOR,
262 1070 hiro
                                        G_TYPE_INT);
263 189 hiro
        gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tree_store),
264 189 hiro
                                        FOLDERSEL_FOLDERNAME,
265 189 hiro
                                        foldersel_folder_name_compare,
266 189 hiro
                                        NULL, NULL);
267 1 hiro
268 189 hiro
        treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(tree_store));
269 189 hiro
        g_object_unref(G_OBJECT(tree_store));
270 189 hiro
        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
271 189 hiro
        gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
272 189 hiro
        gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview),
273 189 hiro
                                        FOLDERSEL_FOLDERNAME);
274 189 hiro
275 189 hiro
        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
276 189 hiro
        gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
277 189 hiro
        gtk_tree_selection_set_select_function(selection, foldersel_selected,
278 189 hiro
                                               NULL, NULL);
279 189 hiro
280 189 hiro
        g_signal_connect(G_OBJECT(treeview), "row-activated",
281 189 hiro
                         G_CALLBACK(foldersel_tree_activated), NULL);
282 189 hiro
283 189 hiro
        gtk_container_add(GTK_CONTAINER(scrolledwin), treeview);
284 189 hiro
285 189 hiro
        column = gtk_tree_view_column_new();
286 189 hiro
        gtk_tree_view_column_set_spacing(column, 2);
287 189 hiro
        renderer = gtk_cell_renderer_pixbuf_new();
288 189 hiro
        gtk_tree_view_column_pack_start(column, renderer, FALSE);
289 189 hiro
        gtk_tree_view_column_set_attributes
290 189 hiro
                (column, renderer,
291 189 hiro
                 "pixbuf", FOLDERSEL_PIXBUF,
292 189 hiro
                 "pixbuf-expander-open", FOLDERSEL_PIXBUF_OPEN,
293 189 hiro
                 "pixbuf-expander-closed", FOLDERSEL_PIXBUF,
294 189 hiro
                 NULL);
295 189 hiro
296 189 hiro
        /* create text renderer */
297 189 hiro
        renderer = gtk_cell_renderer_text_new();
298 189 hiro
        gtk_tree_view_column_pack_start(column, renderer, TRUE);
299 426 hiro
        gtk_tree_view_column_set_attributes
300 426 hiro
                (column, renderer,
301 426 hiro
                 "text", FOLDERSEL_FOLDERNAME,
302 426 hiro
                 "foreground-gdk", FOLDERSEL_FOREGROUND,
303 1070 hiro
                 "weight", FOLDERSEL_BOLD,
304 426 hiro
                 NULL);
305 197 hiro
        gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
306 189 hiro
307 189 hiro
        gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
308 189 hiro
309 1 hiro
        entry = gtk_entry_new();
310 1 hiro
        gtk_entry_set_editable(GTK_ENTRY(entry), FALSE);
311 1 hiro
        gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
312 1 hiro
        g_signal_connect(G_OBJECT(entry), "activate",
313 189 hiro
                         G_CALLBACK(foldersel_entry_activated), NULL);
314 1 hiro
315 30 hiro
        gtkut_stock_button_set_create(&confirm_area,
316 30 hiro
                                      &ok_button,     GTK_STOCK_OK,
317 30 hiro
                                      &cancel_button, GTK_STOCK_CANCEL,
318 30 hiro
                                      &new_button,    GTK_STOCK_NEW);
319 1 hiro
320 1 hiro
        gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
321 1 hiro
        gtk_widget_grab_default(ok_button);
322 1 hiro
323 1 hiro
        g_signal_connect(G_OBJECT(ok_button), "clicked",
324 1 hiro
                         G_CALLBACK(foldersel_ok), NULL);
325 1 hiro
        g_signal_connect(G_OBJECT(cancel_button), "clicked",
326 1 hiro
                         G_CALLBACK(foldersel_cancel), NULL);
327 1 hiro
        g_signal_connect(G_OBJECT(new_button), "clicked",
328 1 hiro
                         G_CALLBACK(foldersel_new_folder), NULL);
329 1 hiro
330 189 hiro
        gtk_widget_show_all(vbox);
331 1 hiro
}
332 1 hiro
333 1 hiro
static void foldersel_init(void)
334 1 hiro
{
335 189 hiro
        stock_pixbuf_gdk(treeview, STOCK_PIXMAP_DIR_CLOSE,
336 189 hiro
                         &folder_pixbuf);
337 189 hiro
        stock_pixbuf_gdk(treeview, STOCK_PIXMAP_DIR_OPEN,
338 189 hiro
                         &folderopen_pixbuf);
339 189 hiro
        stock_pixbuf_gdk(treeview, STOCK_PIXMAP_DIR_NOSELECT,
340 189 hiro
                         &foldernoselect_pixbuf);
341 1 hiro
}
342 1 hiro
343 189 hiro
static void foldersel_append_item(GtkTreeStore *store, FolderItem *item,
344 189 hiro
                                  GtkTreeIter *iter, GtkTreeIter *parent)
345 1 hiro
{
346 426 hiro
        gchar *name;
347 189 hiro
        GdkPixbuf *pixbuf, *pixbuf_open;
348 1070 hiro
        gboolean use_color;
349 1070 hiro
        PangoWeight weight = PANGO_WEIGHT_NORMAL;
350 426 hiro
        GdkColor *foreground = NULL;
351 426 hiro
        static GdkColor color_noselect = {0, COLOR_DIM, COLOR_DIM, COLOR_DIM};
352 426 hiro
        static GdkColor color_new = {0, (guint16)55000, 15000, 15000};
353 1 hiro
354 189 hiro
        name = item->name;
355 1 hiro
356 189 hiro
        if (item->stype != F_NORMAL && FOLDER_IS_LOCAL(item->folder)) {
357 189 hiro
                switch (item->stype) {
358 189 hiro
                case F_INBOX:
359 189 hiro
                        if (!strcmp2(item->name, INBOX_DIR))
360 189 hiro
                                name = _("Inbox");
361 189 hiro
                        break;
362 189 hiro
                case F_OUTBOX:
363 189 hiro
                        if (!strcmp2(item->name, OUTBOX_DIR))
364 189 hiro
                                name = _("Sent");
365 189 hiro
                        break;
366 189 hiro
                case F_QUEUE:
367 189 hiro
                        if (!strcmp2(item->name, QUEUE_DIR))
368 189 hiro
                                name = _("Queue");
369 189 hiro
                        break;
370 189 hiro
                case F_TRASH:
371 189 hiro
                        if (!strcmp2(item->name, TRASH_DIR))
372 189 hiro
                                name = _("Trash");
373 189 hiro
                        break;
374 189 hiro
                case F_DRAFT:
375 189 hiro
                        if (!strcmp2(item->name, DRAFT_DIR))
376 189 hiro
                                name = _("Drafts");
377 189 hiro
                        break;
378 189 hiro
                default:
379 189 hiro
                        break;
380 1 hiro
                }
381 1 hiro
        }
382 1 hiro
383 189 hiro
        if (!item->parent) {
384 189 hiro
                switch (FOLDER_TYPE(item->folder)) {
385 189 hiro
                case F_MH:
386 189 hiro
                        Xstrcat_a(name, name, " (MH)", ); break;
387 189 hiro
                case F_IMAP:
388 189 hiro
                        Xstrcat_a(name, name, " (IMAP4)", ); break;
389 189 hiro
                case F_NEWS:
390 189 hiro
                        Xstrcat_a(name, name, " (News)", ); break;
391 189 hiro
                default:
392 189 hiro
                        break;
393 189 hiro
                }
394 1 hiro
        }
395 1 hiro
396 426 hiro
        if (item->stype == F_QUEUE && item->total > 0) {
397 426 hiro
                name = g_strdup_printf("%s (%d)", name, item->total);
398 426 hiro
        } else if (item->unread > 0) {
399 426 hiro
                name = g_strdup_printf("%s (%d)", name, item->unread);
400 426 hiro
        } else
401 426 hiro
                name = g_strdup(name);
402 1 hiro
403 426 hiro
        pixbuf = item->no_select ? foldernoselect_pixbuf : folder_pixbuf;
404 189 hiro
        pixbuf_open =
405 426 hiro
                item->no_select ? foldernoselect_pixbuf : folderopen_pixbuf;
406 189 hiro
407 426 hiro
        if (item->stype == F_OUTBOX || item->stype == F_DRAFT ||
408 426 hiro
            item->stype == F_TRASH) {
409 1070 hiro
                use_color = FALSE;
410 426 hiro
        } else if (item->stype == F_QUEUE) {
411 1070 hiro
                use_color = (item->total > 0);
412 1070 hiro
                if (item->total > 0)
413 1070 hiro
                        weight = PANGO_WEIGHT_BOLD;
414 426 hiro
        } else {
415 426 hiro
                use_color = (item->new > 0);
416 1070 hiro
                if (item->unread > 0)
417 1070 hiro
                        weight = PANGO_WEIGHT_BOLD;
418 426 hiro
        }
419 426 hiro
420 426 hiro
        if (item->no_select)
421 426 hiro
                foreground = &color_noselect;
422 426 hiro
        else if (use_color)
423 426 hiro
                foreground = &color_new;
424 426 hiro
425 189 hiro
        /* insert this node */
426 426 hiro
        gtk_tree_store_append(store, iter, parent);
427 189 hiro
        gtk_tree_store_set(store, iter,
428 189 hiro
                           FOLDERSEL_FOLDERNAME, name,
429 189 hiro
                           FOLDERSEL_FOLDERITEM, item,
430 189 hiro
                           FOLDERSEL_PIXBUF, pixbuf,
431 189 hiro
                           FOLDERSEL_PIXBUF_OPEN, pixbuf_open,
432 426 hiro
                           FOLDERSEL_FOREGROUND, foreground,
433 1070 hiro
                           FOLDERSEL_BOLD, weight,
434 189 hiro
                           -1);
435 426 hiro
        g_free(name);
436 1 hiro
}
437 1 hiro
438 189 hiro
static void foldersel_insert_gnode_in_store(GtkTreeStore *store, GNode *node,
439 189 hiro
                                            GtkTreeIter *parent)
440 1 hiro
{
441 189 hiro
        FolderItem *item;
442 189 hiro
        GtkTreeIter child;
443 189 hiro
        GNode *iter;
444 1 hiro
445 189 hiro
        g_return_if_fail(node != NULL);
446 189 hiro
        g_return_if_fail(node->data != NULL);
447 189 hiro
        g_return_if_fail(store != NULL);
448 189 hiro
449 189 hiro
        item = FOLDER_ITEM(node->data);
450 189 hiro
        foldersel_append_item(store, item, &child, parent);
451 189 hiro
452 189 hiro
        /* insert its children (this node as parent) */
453 189 hiro
        for (iter = node->children; iter != NULL; iter = iter->next)
454 189 hiro
                foldersel_insert_gnode_in_store(store, iter, &child);
455 1 hiro
}
456 1 hiro
457 389 hiro
static void foldersel_set_tree(Folder *cur_folder)
458 1 hiro
{
459 1 hiro
        Folder *folder;
460 1 hiro
        GList *list;
461 1 hiro
462 189 hiro
        for (list = folder_get_list(); list != NULL; list = list->next) {
463 1 hiro
                folder = FOLDER(list->data);
464 1 hiro
                g_return_if_fail(folder != NULL);
465 1 hiro
466 389 hiro
                if (sel_type != FOLDER_SEL_ALL) {
467 1 hiro
                        if (FOLDER_TYPE(folder) == F_NEWS)
468 1 hiro
                                continue;
469 1 hiro
                }
470 389 hiro
                if (sel_type == FOLDER_SEL_MOVE_FOLDER && folder != cur_folder)
471 389 hiro
                        continue;
472 1 hiro
473 189 hiro
                foldersel_insert_gnode_in_store(tree_store, folder->node, NULL);
474 1 hiro
        }
475 1 hiro
476 189 hiro
        gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tree_store),
477 189 hiro
                                             FOLDERSEL_FOLDERNAME,
478 189 hiro
                                             GTK_SORT_ASCENDING);
479 189 hiro
480 189 hiro
        gtk_tree_view_expand_all(GTK_TREE_VIEW(treeview));
481 1 hiro
}
482 1 hiro
483 189 hiro
static gboolean foldersel_selected(GtkTreeSelection *selection,
484 189 hiro
                                   GtkTreeModel *model, GtkTreePath *path,
485 189 hiro
                                   gboolean currently_selected, gpointer data)
486 1 hiro
{
487 189 hiro
        GtkTreeIter iter;
488 189 hiro
        FolderItem *item = NULL;
489 1 hiro
490 189 hiro
        if (currently_selected)
491 189 hiro
                return TRUE;
492 189 hiro
493 189 hiro
        if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path))
494 189 hiro
                return TRUE;
495 189 hiro
496 189 hiro
        gtk_tree_model_get(GTK_TREE_MODEL(tree_store), &iter,
497 189 hiro
                           FOLDERSEL_FOLDERITEM, &item, -1);
498 189 hiro
499 189 hiro
        selected_item = item;
500 389 hiro
        if (selected_item &&
501 817 hiro
            (sel_type == FOLDER_SEL_ALL || sel_type == FOLDER_SEL_MOVE_FOLDER ||
502 389 hiro
             (selected_item->path && !selected_item->no_select))) {
503 1 hiro
                gchar *id;
504 1 hiro
                id = folder_item_get_identifier(selected_item);
505 1 hiro
                gtk_entry_set_text(GTK_ENTRY(entry), id);
506 1 hiro
                g_free(id);
507 1 hiro
        } else
508 1 hiro
                gtk_entry_set_text(GTK_ENTRY(entry), "");
509 1 hiro
510 189 hiro
        return TRUE;
511 1 hiro
}
512 1 hiro
513 1 hiro
static void foldersel_ok(GtkButton *button, gpointer data)
514 1 hiro
{
515 1 hiro
        finished = TRUE;
516 1 hiro
}
517 1 hiro
518 1 hiro
static void foldersel_cancel(GtkButton *button, gpointer data)
519 1 hiro
{
520 1 hiro
        cancelled = TRUE;
521 1 hiro
        finished = TRUE;
522 1 hiro
}
523 1 hiro
524 1 hiro
static void foldersel_new_folder(GtkButton *button, gpointer data)
525 1 hiro
{
526 1 hiro
        FolderItem *new_item;
527 1 hiro
        gchar *new_folder;
528 1 hiro
        gchar *disp_name;
529 1 hiro
        gchar *p;
530 189 hiro
        GtkTreeIter selected, new_child;
531 189 hiro
        GtkTreePath *selected_p, *new_child_p;
532 189 hiro
        GtkTreeStore *store;
533 189 hiro
        GtkTreeModel *model;
534 189 hiro
        GtkTreeSelection *selection;
535 1 hiro
536 1 hiro
        if (!selected_item || FOLDER_TYPE(selected_item->folder) == F_NEWS)
537 1 hiro
                return;
538 1 hiro
539 189 hiro
        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
540 189 hiro
        if (!gtk_tree_selection_get_selected(selection, &model, &selected))
541 189 hiro
                return;
542 189 hiro
        store = GTK_TREE_STORE(model);
543 189 hiro
544 1 hiro
        new_folder = input_dialog(_("New folder"),
545 1 hiro
                                  _("Input the name of new folder:"),
546 1 hiro
                                  _("NewFolder"));
547 1 hiro
        if (!new_folder) return;
548 1 hiro
        AUTORELEASE_STR(new_folder, {g_free(new_folder); return;});
549 1 hiro
550 1 hiro
        p = strchr(new_folder, G_DIR_SEPARATOR);
551 1 hiro
        if ((p && FOLDER_TYPE(selected_item->folder) != F_IMAP) ||
552 1 hiro
            (p && FOLDER_TYPE(selected_item->folder) == F_IMAP &&
553 1 hiro
             *(p + 1) != '\0')) {
554 1 hiro
                alertpanel_error(_("`%c' can't be included in folder name."),
555 1 hiro
                                G_DIR_SEPARATOR);
556 1 hiro
                return;
557 1 hiro
        }
558 1 hiro
559 1 hiro
        disp_name = trim_string(new_folder, 32);
560 1 hiro
        AUTORELEASE_STR(disp_name, {g_free(disp_name); return;});
561 1 hiro
562 1 hiro
        /* find whether the directory already exists */
563 1 hiro
        if (folder_find_child_item_by_name(selected_item, new_folder)) {
564 1 hiro
                alertpanel_error(_("The folder `%s' already exists."),
565 1 hiro
                                 disp_name);
566 1 hiro
                return;
567 1 hiro
        }
568 1 hiro
569 1 hiro
        new_item = selected_item->folder->klass->create_folder
570 1 hiro
                (selected_item->folder, selected_item, new_folder);
571 1 hiro
        if (!new_item) {
572 1 hiro
                alertpanel_error(_("Can't create the folder `%s'."), disp_name);
573 1 hiro
                return;
574 1 hiro
        }
575 1 hiro
576 189 hiro
        /* add new child */
577 189 hiro
        foldersel_append_item(store, new_item, &new_child, &selected);
578 189 hiro
        selected_p = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &selected);
579 189 hiro
        new_child_p = gtk_tree_model_get_path(GTK_TREE_MODEL(store),
580 189 hiro
                                              &new_child);
581 1 hiro
582 189 hiro
        gtk_tree_view_expand_row(GTK_TREE_VIEW(treeview), selected_p, FALSE);
583 189 hiro
        gtk_tree_selection_select_iter(selection, &new_child);
584 189 hiro
        gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(treeview), new_child_p,
585 189 hiro
                                     NULL, TRUE, 0.5, 0.0);
586 189 hiro
        gtk_tree_path_free(new_child_p);
587 189 hiro
        gtk_tree_path_free(selected_p);
588 189 hiro
589 370 hiro
        folderview_append_item(folderview_get(), NULL, new_item, TRUE);
590 1 hiro
        folder_write_list();
591 1 hiro
}
592 1 hiro
593 189 hiro
static void foldersel_entry_activated(GtkEntry *entry, gpointer data)
594 1 hiro
{
595 1 hiro
        gtk_button_clicked(GTK_BUTTON(ok_button));
596 1 hiro
}
597 1 hiro
598 189 hiro
static void foldersel_tree_activated(GtkTreeView *treeview, GtkTreePath *path,
599 189 hiro
                                     GtkTreeViewColumn *column, gpointer data)
600 189 hiro
{
601 189 hiro
        gtk_button_clicked(GTK_BUTTON(ok_button));
602 189 hiro
}
603 189 hiro
604 1 hiro
static gint delete_event(GtkWidget *widget, GdkEventAny *event, gpointer data)
605 1 hiro
{
606 1 hiro
        foldersel_cancel(NULL, NULL);
607 1 hiro
        return TRUE;
608 1 hiro
}
609 1 hiro
610 1 hiro
static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
611 1 hiro
{
612 1 hiro
        if (event && event->keyval == GDK_Escape)
613 1 hiro
                foldersel_cancel(NULL, NULL);
614 1 hiro
        return FALSE;
615 1 hiro
}
616 1 hiro
617 189 hiro
static gint foldersel_folder_name_compare(GtkTreeModel *model, GtkTreeIter *a,
618 189 hiro
                                          GtkTreeIter *b, gpointer context)
619 1 hiro
{
620 189 hiro
        FolderItem *item_a = NULL, *item_b = NULL;
621 1 hiro
622 189 hiro
        gtk_tree_model_get(model, a, FOLDERSEL_FOLDERITEM, &item_a, -1);
623 189 hiro
        gtk_tree_model_get(model, b, FOLDERSEL_FOLDERITEM, &item_b, -1);
624 1 hiro
625 202 hiro
        return folder_item_compare(item_a, item_b);
626 1 hiro
}
627 189 hiro
628 189 hiro
static gboolean tree_view_folder_item_func(GtkTreeModel *model,
629 189 hiro
                                           GtkTreePath *path,
630 189 hiro
                                           GtkTreeIter *iter,
631 189 hiro
                                           FolderItemSearch *data)
632 189 hiro
{
633 189 hiro
        FolderItem *item = NULL;
634 189 hiro
635 189 hiro
        gtk_tree_model_get(model, iter, FOLDERSEL_FOLDERITEM, &item, -1);
636 189 hiro
637 189 hiro
        if (data->item == item) {
638 189 hiro
                data->path = gtk_tree_path_copy(path);
639 189 hiro
                data->iter = *iter;
640 189 hiro
                return TRUE;
641 189 hiro
        }
642 189 hiro
643 189 hiro
        return FALSE;
644 189 hiro
}