2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2001 Hiroyuki Yamamoto
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.
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.
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.
23 #include <gdk/gdkkeysyms.h>
24 #include <gtk/gtkmain.h>
25 #include <gtk/gtkwidget.h>
26 #include <gtk/gtkctree.h>
27 #include <gtk/gtkwindow.h>
28 #include <gtk/gtkvbox.h>
29 #include <gtk/gtkscrolledwindow.h>
30 #include <gtk/gtkentry.h>
31 #include <gtk/gtkhbbox.h>
32 #include <gtk/gtksignal.h>
37 #include <sys/types.h>
45 #include "foldersel.h"
46 #include "alertpanel.h"
47 #include "manage_window.h"
50 #include "pixmaps/dir-close.xpm"
51 #include "pixmaps/dir-open.xpm"
53 static GdkPixmap
*folderxpm
;
54 static GdkBitmap
*folderxpmmask
;
55 static GdkPixmap
*folderopenxpm
;
56 static GdkBitmap
*folderopenxpmmask
;
58 static GtkWidget
*window
;
59 static GtkWidget
*ctree
;
60 static GtkWidget
*entry
;
61 static GtkWidget
*ok_button
;
62 static GtkWidget
*cancel_button
;
64 static FolderItem
*folder_item
;
66 static gboolean cancelled
;
68 static void foldersel_create(void);
69 static void foldersel_init(void);
70 static void foldersel_set_tree(Folder
*cur_folder
);
71 static void foldersel_selected(GtkCList
*clist
, gint row
, gint column
,
72 GdkEvent
*event
, gpointer data
);
74 static void foldersel_ok(GtkButton
*button
, gpointer data
);
75 static void foldersel_cancel(GtkButton
*button
, gpointer data
);
76 static void foldersel_activated(void);
77 static gint
delete_event(GtkWidget
*widget
, GdkEventAny
*event
, gpointer data
);
78 static void key_pressed(GtkWidget
*widget
, GdkEventKey
*event
, gpointer data
);
80 FolderItem
*foldersel_folder_sel(Folder
*cur_folder
,
81 const gchar
*default_folder
)
89 gtk_widget_show(window
);
90 manage_window_set_transient(GTK_WINDOW(window
));
92 foldersel_set_tree(cur_folder
);
95 node
= gtk_ctree_find_by_row_data
96 (GTK_CTREE(ctree
), NULL
, folder_item
);
100 row
= gtkut_ctree_get_nth_from_node
101 (GTK_CTREE(ctree
), node
);
102 gtk_clist_select_row(GTK_CLIST(ctree
), row
, -1);
103 gtkut_clist_set_focus_row(GTK_CLIST(ctree
), row
);
104 gtk_ctree_node_moveto(GTK_CTREE(ctree
), node
, -1,
108 gtk_widget_grab_focus(ok_button
);
109 gtk_widget_grab_focus(ctree
);
115 gtk_widget_hide(window
);
116 gtk_entry_set_text(GTK_ENTRY(entry
), "");
117 gtk_clist_clear(GTK_CLIST(ctree
));
119 if (!cancelled
&& folder_item
&& folder_item
->path
)
125 static void foldersel_create(void)
128 GtkWidget
*scrolledwin
;
129 GtkWidget
*confirm_area
;
131 window
= gtk_window_new(GTK_WINDOW_DIALOG
);
132 gtk_window_set_title(GTK_WINDOW(window
), _("Select folder"));
133 gtk_widget_set_usize(window
, 300, 400);
134 gtk_container_set_border_width(GTK_CONTAINER(window
), BORDER_WIDTH
);
135 gtk_window_set_position(GTK_WINDOW(window
), GTK_WIN_POS_CENTER
);
136 gtk_window_set_modal(GTK_WINDOW(window
), TRUE
);
137 gtk_window_set_policy(GTK_WINDOW(window
), TRUE
, TRUE
, TRUE
);
138 gtk_signal_connect(GTK_OBJECT(window
), "delete_event",
139 GTK_SIGNAL_FUNC(delete_event
), NULL
);
140 gtk_signal_connect(GTK_OBJECT(window
), "key_press_event",
141 GTK_SIGNAL_FUNC(key_pressed
), NULL
);
142 gtk_signal_connect(GTK_OBJECT(window
), "focus_in_event",
143 GTK_SIGNAL_FUNC(manage_window_focus_in
), NULL
);
144 gtk_signal_connect(GTK_OBJECT(window
), "focus_out_event",
145 GTK_SIGNAL_FUNC(manage_window_focus_out
), NULL
);
147 vbox
= gtk_vbox_new(FALSE
, 4);
148 gtk_container_add(GTK_CONTAINER(window
), vbox
);
150 scrolledwin
= gtk_scrolled_window_new(NULL
, NULL
);
151 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin
),
152 GTK_POLICY_NEVER
, GTK_POLICY_ALWAYS
);
153 gtk_box_pack_start(GTK_BOX(vbox
), scrolledwin
, TRUE
, TRUE
, 0);
155 ctree
= gtk_ctree_new(1, 0);
156 gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(scrolledwin
),
157 GTK_CLIST(ctree
)->vadjustment
);
158 gtk_container_add(GTK_CONTAINER(scrolledwin
), ctree
);
159 gtk_clist_set_selection_mode(GTK_CLIST(ctree
), GTK_SELECTION_BROWSE
);
160 gtk_ctree_set_line_style(GTK_CTREE(ctree
), GTK_CTREE_LINES_DOTTED
);
161 gtk_ctree_set_expander_style(GTK_CTREE(ctree
),
162 GTK_CTREE_EXPANDER_SQUARE
);
163 gtk_ctree_set_indent(GTK_CTREE(ctree
), CTREE_INDENT
);
164 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(ctree
)->column
[0].button
,
167 gtk_signal_connect(GTK_OBJECT(ctree), "tree_select_row",
168 GTK_SIGNAL_FUNC(foldersel_selected), NULL);
169 gtk_signal_connect(GTK_OBJECT(ctree), "select_row",
170 GTK_SIGNAL_FUNC(foldersel_selected), NULL);
173 entry
= gtk_entry_new();
174 gtk_box_pack_start(GTK_BOX(vbox
), entry
, FALSE
, FALSE
, 0);
175 gtk_signal_connect(GTK_OBJECT(entry
), "activate",
176 GTK_SIGNAL_FUNC(foldersel_activated
), NULL
);
178 gtkut_button_set_create(&confirm_area
,
180 &cancel_button
, _("Cancel"),
183 gtk_box_pack_end(GTK_BOX(vbox
), confirm_area
, FALSE
, FALSE
, 0);
184 gtk_widget_grab_default(ok_button
);
186 gtk_signal_connect(GTK_OBJECT(ok_button
), "clicked",
187 GTK_SIGNAL_FUNC(foldersel_ok
), NULL
);
188 gtk_signal_connect(GTK_OBJECT(cancel_button
), "clicked",
189 GTK_SIGNAL_FUNC(foldersel_cancel
), NULL
);
191 gtk_widget_show_all(window
);
194 static void foldersel_init(void)
196 PIXMAP_CREATE(ctree
, folderxpm
, folderxpmmask
, DIRECTORY_CLOSE_XPM
);
197 PIXMAP_CREATE(ctree
, folderopenxpm
, folderopenxpmmask
,
201 static gboolean
foldersel_gnode_func(GtkCTree
*ctree
, guint depth
,
202 GNode
*gnode
, GtkCTreeNode
*cnode
,
205 FolderItem
*item
= FOLDER_ITEM(gnode
->data
);
207 gtk_ctree_node_set_row_data(ctree
, cnode
, item
);
208 gtk_ctree_set_node_info(ctree
, cnode
, item
->name
,
210 folderxpm
, folderxpmmask
,
211 folderopenxpm
, folderopenxpmmask
,
217 static void foldersel_expand_func(GtkCTree
*ctree
, GtkCTreeNode
*node
,
220 if (GTK_CTREE_ROW(node
)->children
)
221 gtk_ctree_expand(ctree
, node
);
224 static void foldersel_set_tree(Folder
*cur_folder
)
230 list
= folder_get_list();
232 gtk_clist_freeze(GTK_CLIST(ctree
));
234 for (; list
!= NULL
; list
= list
->next
) {
235 folder
= FOLDER(list
->data
);
236 g_return_if_fail(folder
!= NULL
);
238 if (folder
->type
== F_NEWS
) continue;
240 if (cur_folder
->type
!= folder
->type
) continue;
241 if (cur_folder
->type
== F_IMAP
) {
242 if (cur_folder
->account
!= folder
->account
)
247 node
= gtk_ctree_insert_gnode(GTK_CTREE(ctree
), NULL
, NULL
,
249 foldersel_gnode_func
,
251 gtk_ctree_sort_recursive(GTK_CTREE(ctree
), node
);
252 gtk_ctree_pre_recursive(GTK_CTREE(ctree
), node
,
253 foldersel_expand_func
,
257 gtk_clist_thaw(GTK_CLIST(ctree
));
260 static void foldersel_selected(GtkCList
*clist
, gint row
, gint column
,
261 GdkEvent
*event
, gpointer data
)
264 GdkEventButton
*ev
= (GdkEventButton
*)event
;
266 item
= gtk_clist_get_row_data(clist
, row
);
267 if (item
) gtk_entry_set_text(GTK_ENTRY(entry
),
268 item
->path
? item
->path
: "");
270 if (ev
&& GDK_2BUTTON_PRESS
== ev
->type
)
271 gtk_button_clicked(GTK_BUTTON(ok_button
));
274 static void foldersel_ok(GtkButton
*button
, gpointer data
)
278 list
= GTK_CLIST(ctree
)->selection
;
280 folder_item
= gtk_ctree_node_get_row_data
281 (GTK_CTREE(ctree
), GTK_CTREE_NODE(list
->data
));
286 static void foldersel_cancel(GtkButton
*button
, gpointer data
)
292 static void foldersel_activated(void)
294 gtk_button_clicked(GTK_BUTTON(ok_button
));
297 static gint
delete_event(GtkWidget
*widget
, GdkEventAny
*event
, gpointer data
)
299 foldersel_cancel(NULL
, NULL
);
303 static void key_pressed(GtkWidget
*widget
, GdkEventKey
*event
, gpointer data
)
305 if (event
&& event
->keyval
== GDK_Escape
)
306 foldersel_cancel(NULL
, NULL
);