Statistics
| Revision:

root / src / foldersel.c @ 880

History | View | Annotate | Download (17.6 kB)

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