2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 2001-2022 the Claws Mail team and Match Grun
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 3 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, see <http://www.gnu.org/licenses/>.
21 * Add address to address book dialog.
26 #include "claws-features.h"
32 #include <glib/gi18n.h>
33 #include <gdk/gdkkeysyms.h>
37 #include "stock_pixmap.h"
38 #include "prefs_common.h"
39 #include "addressadd.h"
42 #include "addrindex.h"
43 #include "manage_window.h"
53 AddressBookFile
*book
;
57 static struct _AddressBookFolderSel_dlg
{
59 GtkWidget
*view_folder
;
61 GtkWidget
*cancel_btn
;
63 FolderInfo
*fiSelected
;
64 } addressbook_foldersel_dlg
;
66 static GdkPixbuf
*folderXpm
;
67 static GdkPixbuf
*bookXpm
;
69 static gboolean addressbook_foldersel_cancelled
;
71 static FolderInfo
*addressbook_foldersel_create_folderinfo( AddressBookFile
*abf
, ItemFolder
*folder
)
73 FolderInfo
*fi
= g_new0( FolderInfo
, 1 );
79 static void addressbook_foldersel_free_folderinfo( FolderInfo
*fi
) {
85 static gint
addressbook_foldersel_delete_event( GtkWidget
*widget
, GdkEventAny
*event
, gboolean
*cancelled
)
87 addressbook_foldersel_cancelled
= TRUE
;
92 static gboolean
addressbook_foldersel_key_pressed( GtkWidget
*widget
, GdkEventKey
*event
, gboolean
*cancelled
)
94 if ( event
&& event
->keyval
== GDK_KEY_Escape
) {
95 addressbook_foldersel_cancelled
= TRUE
;
101 static void set_selected_ptr()
103 GtkWidget
*view
= addressbook_foldersel_dlg
.view_folder
;
105 addressbook_foldersel_dlg
.fiSelected
=
106 gtkut_tree_view_get_selected_pointer(GTK_TREE_VIEW(view
), COL_PTR
,
110 static void addressbook_foldersel_ok( GtkWidget
*widget
, gboolean
*cancelled
)
113 addressbook_foldersel_cancelled
= FALSE
;
117 static void addressbook_foldersel_cancel( GtkWidget
*widget
, gboolean
*cancelled
)
120 addressbook_foldersel_cancelled
= TRUE
;
124 static void addressbook_foldersel_row_activated(GtkTreeView
*view
,
125 GtkTreePath
*path
, GtkTreeViewColumn
*col
,
128 addressbook_foldersel_ok(NULL
, NULL
);
131 static void addressbook_foldersel_size_allocate_cb(GtkWidget
*widget
,
132 GtkAllocation
*allocation
)
134 cm_return_if_fail(allocation
!= NULL
);
136 gtk_window_get_size(GTK_WINDOW(widget
),
137 &prefs_common
.addressbook_folderselwin_width
, &prefs_common
.addressbook_folderselwin_height
);
140 static void addressbook_foldersel_create( void )
149 GtkWidget
*cancel_btn
;
150 static GdkGeometry geometry
;
152 GtkTreeSelection
*sel
;
153 GtkCellRenderer
*rdr
;
154 GtkTreeViewColumn
*col
;
156 window
= gtkut_window_new(GTK_WINDOW_TOPLEVEL
, "addressbook_foldersel" );
157 gtk_container_set_border_width( GTK_CONTAINER(window
), 0 );
158 gtk_window_set_title( GTK_WINDOW(window
), _("Select Address Book Folder") );
159 gtk_window_set_position( GTK_WINDOW(window
), GTK_WIN_POS_MOUSE
);
160 gtk_window_set_type_hint(GTK_WINDOW(window
), GDK_WINDOW_TYPE_HINT_DIALOG
);
161 g_signal_connect( G_OBJECT(window
), "delete_event",
162 G_CALLBACK(addressbook_foldersel_delete_event
), NULL
);
163 g_signal_connect( G_OBJECT(window
), "key_press_event",
164 G_CALLBACK(addressbook_foldersel_key_pressed
), NULL
);
165 g_signal_connect(G_OBJECT(window
), "size_allocate",
166 G_CALLBACK(addressbook_foldersel_size_allocate_cb
), NULL
);
168 vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 8);
169 gtk_container_add(GTK_CONTAINER(window
), vbox
);
170 gtk_container_set_border_width( GTK_CONTAINER(vbox
), 8 );
172 /* Address book/folder tree */
173 vlbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 8);
174 gtk_box_pack_start(GTK_BOX(vbox
), vlbox
, TRUE
, TRUE
, 0);
175 gtk_container_set_border_width( GTK_CONTAINER(vlbox
), 8 );
177 tree_win
= gtk_scrolled_window_new( NULL
, NULL
);
178 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(tree_win
),
179 GTK_POLICY_AUTOMATIC
,
180 GTK_POLICY_AUTOMATIC
);
181 gtk_box_pack_start( GTK_BOX(vlbox
), tree_win
, TRUE
, TRUE
, 0 );
183 store
= gtk_tree_store_new(N_COLS
,
184 GDK_TYPE_PIXBUF
, G_TYPE_STRING
, G_TYPE_POINTER
);
186 view
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
));
187 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store
), COL_NAME
, GTK_SORT_ASCENDING
);
188 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(view
), prefs_common
.use_stripes_everywhere
);
189 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view
), TRUE
);
190 gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW(view
), FALSE
);
191 gtk_tree_view_set_search_column(GTK_TREE_VIEW(view
), COL_NAME
);
193 col
= gtk_tree_view_column_new();
194 rdr
= gtk_cell_renderer_pixbuf_new();
195 gtk_cell_renderer_set_padding(rdr
, 0, 0);
196 gtk_tree_view_column_pack_start(col
, rdr
, FALSE
);
197 gtk_tree_view_column_set_attributes(col
, rdr
,
198 "pixbuf", COL_ICON
, NULL
);
199 rdr
= gtk_cell_renderer_text_new();
200 gtk_tree_view_column_pack_start(col
, rdr
, TRUE
);
201 gtk_tree_view_column_set_attributes(col
, rdr
,
202 "markup", COL_NAME
, NULL
);
203 gtk_tree_view_column_set_title(col
, _("Address Book"));
204 gtk_tree_view_append_column(GTK_TREE_VIEW(view
), col
);
206 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(view
));
207 gtk_tree_selection_set_mode(sel
, GTK_SELECTION_BROWSE
);
209 gtk_container_add( GTK_CONTAINER(tree_win
), view
);
212 gtkut_stock_button_set_create( &hbbox
, &cancel_btn
, NULL
, _("_Cancel"),
213 &ok_btn
, NULL
, _("_OK"),
215 gtk_box_pack_end( GTK_BOX(vbox
), hbbox
, FALSE
, FALSE
, 0 );
216 gtk_container_set_border_width( GTK_CONTAINER(hbbox
), 0 );
217 gtk_widget_grab_default( ok_btn
);
219 g_signal_connect( G_OBJECT(view
), "row-activated",
220 G_CALLBACK(addressbook_foldersel_row_activated
), NULL
);
221 g_signal_connect( G_OBJECT(ok_btn
), "clicked",
222 G_CALLBACK(addressbook_foldersel_ok
), NULL
);
223 g_signal_connect( G_OBJECT(cancel_btn
), "clicked",
224 G_CALLBACK(addressbook_foldersel_cancel
), NULL
);
226 if ( !geometry
.min_height
) {
227 geometry
.min_width
= 300;
228 geometry
.min_height
= 350;
231 gtk_window_set_geometry_hints( GTK_WINDOW(window
), NULL
, &geometry
,
233 gtk_window_set_default_size( GTK_WINDOW(window
),
234 prefs_common
.addressbook_folderselwin_width
,
235 prefs_common
.addressbook_folderselwin_height
);
237 gtk_widget_show_all( vbox
);
239 addressbook_foldersel_dlg
.window
= window
;
240 addressbook_foldersel_dlg
.view_folder
= view
;
241 addressbook_foldersel_dlg
.ok_btn
= ok_btn
;
242 addressbook_foldersel_dlg
.cancel_btn
= cancel_btn
;
244 gtk_widget_show_all( window
);
246 stock_pixbuf_gdk(STOCK_PIXMAP_BOOK
, &bookXpm
);
247 stock_pixbuf_gdk(STOCK_PIXMAP_DIR_OPEN
, &folderXpm
);
250 static gboolean
tree_clear_foreach_func(GtkTreeModel
*model
,
251 GtkTreePath
*path
, GtkTreeIter
*iter
,
256 gtk_tree_model_get(model
, iter
, COL_PTR
, &fi
, -1);
258 addressbook_foldersel_free_folderinfo(fi
);
260 gtk_tree_store_set(GTK_TREE_STORE(model
), iter
, COL_PTR
, NULL
, -1);
264 static void addressbook_foldersel_tree_clear()
266 GtkWidget
*view
= addressbook_foldersel_dlg
.view_folder
;
267 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(view
));
269 gtk_tree_model_foreach(model
, tree_clear_foreach_func
, NULL
);
270 gtk_tree_store_clear(GTK_TREE_STORE(model
));
273 static void addressbook_foldersel_load_folder( GtkTreeIter
*parent_iter
,
274 ItemFolder
*parentFolder
, FolderInfo
*fiParent
)
276 GtkWidget
*view
= addressbook_foldersel_dlg
.view_folder
;
277 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(view
));
284 list
= parentFolder
->listFolder
;
287 name
= g_strdup( ADDRITEM_NAME(folder
) );
289 fi
= addressbook_foldersel_create_folderinfo( fiParent
->book
, folder
);
291 debug_print("adding folder '%s'\n", name
);
292 gtk_tree_store_append(GTK_TREE_STORE(model
), &iter
, parent_iter
);
293 gtk_tree_store_set(GTK_TREE_STORE(model
), &iter
,
300 addressbook_foldersel_load_folder( parent_iter
, folder
, fi
);
301 list
= g_list_next( list
);
305 static void addressbook_foldersel_load_data( AddressIndex
*addrIndex
)
307 AddressDataSource
*ds
;
308 GList
*list
, *nodeDS
;
310 ItemFolder
*rootFolder
;
311 AddressBookFile
*abf
;
313 GtkWidget
*view
= addressbook_foldersel_dlg
.view_folder
;
314 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(view
));
315 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(view
));
318 addressbook_foldersel_tree_clear();
320 list
= addrindex_get_interface_list( addrIndex
);
322 AddressInterface
*interface
= list
->data
;
323 if ( interface
->type
== ADDR_IF_BOOK
) {
324 nodeDS
= interface
->listSource
;
327 name
= g_strdup( addrindex_ds_get_name( ds
) );
329 /* Read address book */
330 if( ! addrindex_ds_get_read_flag( ds
) ) {
331 addrindex_ds_read_data( ds
);
334 /* Add node for address book */
335 abf
= ds
->rawDataSource
;
336 fi
= addressbook_foldersel_create_folderinfo( abf
, NULL
);
338 debug_print("adding AB '%s'\n", name
);
339 gtk_tree_store_append(GTK_TREE_STORE(model
), &iter
, NULL
);
340 gtk_tree_store_set(GTK_TREE_STORE(model
), &iter
,
347 rootFolder
= addrindex_ds_get_root_folder( ds
);
348 addressbook_foldersel_load_folder( &iter
, rootFolder
, fi
);
350 nodeDS
= g_list_next( nodeDS
);
353 list
= g_list_next( list
);
356 if (gtk_tree_model_get_iter_first(model
, &iter
))
357 gtk_tree_selection_select_iter(sel
, &iter
);
360 gboolean
addressbook_foldersel_selection( AddressIndex
*addrIndex
,
361 AddressBookFile
**book
, ItemFolder
**folder
,
364 gboolean retVal
= FALSE
;
365 addressbook_foldersel_cancelled
= FALSE
;
367 if ( ! addressbook_foldersel_dlg
.window
)
368 addressbook_foldersel_create();
369 gtk_widget_grab_focus(addressbook_foldersel_dlg
.ok_btn
);
370 gtk_widget_show(addressbook_foldersel_dlg
.window
);
371 manage_window_set_transient(GTK_WINDOW(addressbook_foldersel_dlg
.window
));
372 gtk_window_set_modal(GTK_WINDOW(addressbook_foldersel_dlg
.window
), TRUE
);
374 addressbook_foldersel_dlg
.fiSelected
= NULL
;
376 addressbook_foldersel_load_data( addrIndex
);
378 gtk_widget_show(addressbook_foldersel_dlg
.window
);
381 gtk_widget_hide( addressbook_foldersel_dlg
.window
);
382 gtk_window_set_modal(GTK_WINDOW(addressbook_foldersel_dlg
.window
), FALSE
);
383 if ( ! addressbook_foldersel_cancelled
) {
388 if ( addressbook_foldersel_dlg
.fiSelected
) {
389 *book
= addressbook_foldersel_dlg
.fiSelected
->book
;
390 *folder
= addressbook_foldersel_dlg
.fiSelected
->folder
;
395 addressbook_foldersel_tree_clear();