inital gtk2 patch
[claws.git] / src / editldap.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2001-2003 Match Grun
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 /*
21  * Edit LDAP address book data.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27
28 #ifdef USE_LDAP
29
30 #include "defs.h"
31
32 #include <glib.h>
33 #include <gdk/gdkkeysyms.h>
34 #include <gtk/gtkwindow.h>
35 #include <gtk/gtksignal.h>
36 #include <gtk/gtklabel.h>
37 #include <gtk/gtkentry.h>
38 #include <gtk/gtktable.h>
39 #include <gtk/gtkbutton.h>
40
41 #include "intl.h"
42 #include "addressbook.h"
43 #include "prefs_common.h"
44 #include "addressitem.h"
45 #include "mgutils.h"
46 #include "ldapserver.h"
47 #include "ldapctrl.h"
48 #include "ldaputil.h"
49 #include "editldap_basedn.h"
50 #include "manage_window.h"
51 #include "gtkutils.h"
52
53 #define PAGE_BASIC      0
54 #define PAGE_SEARCH     1
55 #define PAGE_EXTENDED   2
56
57 #define ADDRESSBOOK_GUESS_LDAP_NAME     "MyServer"
58 #define ADDRESSBOOK_GUESS_LDAP_SERVER   "localhost"
59
60 #define LDAPEDIT_TABLE_ROWS     6
61 #define LDAPEDIT_TABLE_COLS     3
62
63 static struct _LDAPEdit {
64         GtkWidget *window;
65         GtkWidget *notebook;
66         GtkWidget *ok_btn;
67         GtkWidget *cancel_btn;
68         GtkWidget *statusbar;
69         gint status_cid;
70         GtkWidget *entry_name;
71         GtkWidget *entry_server;
72         GtkWidget *spinbtn_port;
73         GtkWidget *entry_baseDN;
74         GtkWidget *spinbtn_timeout;
75         GtkWidget *entry_bindDN;
76         GtkWidget *entry_bindPW;
77         GtkWidget *spinbtn_maxentry;
78         GtkWidget *entry_criteria;
79         GtkWidget *spinbtn_queryage;
80         GtkWidget *check_dynsearch;
81 } ldapedit;
82
83 /**
84  * Parse out individual attribute names from criteria string.
85  * \param criteria Criteria string.
86  * \ctl   Control object.
87  */
88 static gboolean editldap_validate_criteria( gchar *criteria ) {
89         gchar *ptr;
90         gchar **splitStr;
91         gint i;
92         gboolean errorFlag;
93
94         errorFlag = TRUE;
95
96         /* Replace delimiters with spaces */
97         ptr = criteria;
98         while( *ptr ) {
99                 if( *ptr == ',' || *ptr == ';' || *ptr == '|' )
100                         *ptr = ' ';
101                 ptr++;
102         }
103
104         /* Parse string */
105         splitStr = g_strsplit( criteria, " ", 0 );
106         i = 0;
107         while( TRUE ) {
108                 if( splitStr[i] ) {
109                         if( *splitStr[i] ) {
110                                 errorFlag = FALSE;
111                                 break;
112                         }
113                 }
114                 else {
115                         break;
116                 }
117                 i++;
118         }
119         g_strfreev( splitStr );
120         return errorFlag;
121 }
122
123 /*
124 * Edit functions.
125 */
126 static void edit_ldap_status_show( gchar *msg ) {
127         if( ldapedit.statusbar != NULL ) {
128                 gtk_statusbar_pop( GTK_STATUSBAR(ldapedit.statusbar), ldapedit.status_cid );
129                 if( msg ) {
130                         gtk_statusbar_push( GTK_STATUSBAR(ldapedit.statusbar),
131                                 ldapedit.status_cid, msg );
132                 }
133         }
134 }
135
136 static gboolean edit_ldap_validate( void ) {
137         gchar *str;
138         gboolean errorFlag;
139         gint page;
140
141         errorFlag = FALSE;
142         str = gtk_editable_get_chars(
143                         GTK_EDITABLE(ldapedit.entry_name), 0, -1 );
144         if( *str == '\0' ) {
145                 page = PAGE_BASIC;
146                 gtk_widget_grab_focus( ldapedit.entry_name );
147                 edit_ldap_status_show( _( "A Name must be supplied." ) );
148                 errorFlag = TRUE;
149         }
150         g_free( str );
151
152         if( ! errorFlag ) {
153                 str = gtk_editable_get_chars(
154                                 GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
155                 if( *str == '\0' ) {
156                         page = PAGE_BASIC;
157                         gtk_widget_grab_focus( ldapedit.entry_server );
158                         edit_ldap_status_show(
159                                 _( "A Hostname must be supplied for the server." ) );
160                         errorFlag = TRUE;
161                 }
162                 g_free( str );
163         }
164
165         if( ! errorFlag ) {
166                 str = gtk_editable_get_chars(
167                                 GTK_EDITABLE(ldapedit.entry_criteria), 0, -1 );
168                 if( editldap_validate_criteria( str ) ) {
169                         page = PAGE_SEARCH;
170                         gtk_widget_grab_focus( ldapedit.entry_criteria );
171                         edit_ldap_status_show(
172                                 _( "At least one LDAP search attribute should be supplied." ) );
173                         errorFlag = TRUE;
174                 }
175                 g_free( str );
176         }
177
178         /* Switch to page with error */
179         if( errorFlag ) {
180                 gtk_notebook_set_current_page( GTK_NOTEBOOK(ldapedit.notebook), page );
181         }
182
183         return errorFlag;
184 }
185
186 static void edit_ldap_ok( GtkWidget *widget, gboolean *cancelled ) {
187         if( ! edit_ldap_validate() ) {
188                 *cancelled = FALSE;
189                 gtk_main_quit();
190         }
191 }
192
193 static void edit_ldap_cancel( GtkWidget *widget, gboolean *cancelled ) {
194         *cancelled = TRUE;
195         gtk_main_quit();
196 }
197
198 static gint edit_ldap_delete_event( GtkWidget *widget, GdkEventAny *event, gboolean *cancelled ) {
199         *cancelled = TRUE;
200         gtk_main_quit();
201         return TRUE;
202 }
203
204 static gboolean edit_ldap_key_pressed( GtkWidget *widget, GdkEventKey *event, gboolean *cancelled ) {
205         if (event && event->keyval == GDK_Escape) {
206                 *cancelled = TRUE;
207                 gtk_main_quit();
208         }
209         return FALSE;
210 }
211
212 static void edit_ldap_server_check( void ) {
213         gchar *sHost, *sBind, *sPass;
214         gint iPort, iTime;
215         gchar *sMsg;
216         gchar *sBaseDN = NULL;
217         gint iBaseDN = 0;
218         gboolean flg;
219         GList *baseDN = NULL;
220
221         edit_ldap_status_show( "" );
222         flg = FALSE;
223         sHost = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
224         sBind = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
225         sPass = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
226         iPort = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
227         iTime = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
228         g_strchomp( sHost ); g_strchug( sHost );
229         g_strchomp( sBind ); g_strchug( sBind );
230         g_strchomp( sPass ); g_strchug( sPass );
231         if( *sHost != '\0' ) {
232                 /* Test connection to server */
233                 if( ldaputil_test_connect( sHost, iPort ) ) {
234                         /* Attempt to read base DN */
235                         baseDN = ldaputil_read_basedn( sHost, iPort, sBind, sPass, iTime );
236                         if( baseDN ) {
237                                 GList *node = baseDN;
238                                 while( node ) {
239                                         ++iBaseDN;
240                                         if( ! sBaseDN ) {
241                                                 sBaseDN = g_strdup( node->data );
242                                         }
243                                         node = g_list_next( node );
244                                 }
245                                 mgu_free_dlist( baseDN );
246                                 baseDN = node = NULL;
247                         }
248                         flg = TRUE;
249                 }
250         }
251         g_free( sHost );
252         g_free( sBind );
253         g_free( sPass );
254
255         if( sBaseDN ) {
256                 /* Load search DN */
257                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), sBaseDN);
258                 g_free( sBaseDN );
259         }
260
261         /* Display appropriate message */
262         if( flg ) {
263                 sMsg = _( "Connected successfully to server" );
264         }
265         else {
266                 sMsg = _( "Could not connect to server" );
267         }
268         edit_ldap_status_show( sMsg );
269 }
270
271 static void edit_ldap_basedn_select( void ) {
272         gchar *sHost, *sBind, *sPass, *sBase;
273         gint iPort, iTime;
274         gchar *selectDN;
275
276         sHost = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
277         sBase = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_baseDN), 0, -1 );
278         sBind = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
279         sPass = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
280         iPort = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
281         iTime = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
282         g_strchomp( sHost ); g_strchug( sHost );
283         g_strchomp( sBind ); g_strchug( sBind );
284         g_strchomp( sPass ); g_strchug( sPass );
285         selectDN = edit_ldap_basedn_selection( sHost, iPort, sBase, iTime, sBind, sPass );
286         if( selectDN ) {
287                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), selectDN);
288                 g_free( selectDN );
289                 selectDN = NULL;
290         }
291         g_free( sHost );
292         g_free( sBase );
293         g_free( sBind );
294         g_free( sPass );
295 }
296
297 static void edit_ldap_search_reset( void ) {
298         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), LDAPCTL_DFL_ATTR_LIST );
299 }
300
301 static void addressbook_edit_ldap_dialog_create( gboolean *cancelled ) {
302         GtkWidget *window;
303         GtkWidget *vbox;
304         GtkWidget *notebook;
305         GtkWidget *hbbox;
306         GtkWidget *ok_btn;
307         GtkWidget *cancel_btn;
308         GtkWidget *hsbox;
309         GtkWidget *statusbar;
310
311         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
312         gtk_widget_set_size_request(window, 450, -1);
313         gtk_container_set_border_width(GTK_CONTAINER(window), 0);
314         gtk_window_set_title(GTK_WINDOW(window), _("Edit LDAP Server"));
315         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
316         gtk_window_set_modal(GTK_WINDOW(window), TRUE); 
317         g_signal_connect(G_OBJECT(window), "delete_event",
318                          G_CALLBACK(edit_ldap_delete_event),
319                          cancelled);
320         g_signal_connect(G_OBJECT(window), "key_press_event",
321                          G_CALLBACK(edit_ldap_key_pressed),
322                          cancelled);
323
324         vbox = gtk_vbox_new( FALSE, 6 );
325         gtk_widget_show( vbox );
326         gtk_container_add( GTK_CONTAINER( window ), vbox );
327
328         /* Notebook */
329         notebook = gtk_notebook_new();
330         gtk_widget_show( notebook );
331         gtk_box_pack_start( GTK_BOX( vbox ), notebook, TRUE, TRUE, 0 );
332         gtk_container_set_border_width( GTK_CONTAINER( notebook ), 6 );
333
334         /* Status line */
335         hsbox = gtk_hbox_new(FALSE, 0);
336         gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
337         statusbar = gtk_statusbar_new();
338         gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
339
340         /* Button panel */
341         gtkut_button_set_create(&hbbox, &ok_btn, _("OK"),
342                                 &cancel_btn, _("Cancel"), NULL, NULL);
343         gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
344         gtk_widget_grab_default(ok_btn);
345
346         g_signal_connect(G_OBJECT(ok_btn), "clicked",
347                          G_CALLBACK(edit_ldap_ok), cancelled);
348         g_signal_connect(G_OBJECT(cancel_btn), "clicked",
349                          G_CALLBACK(edit_ldap_cancel), cancelled);
350
351         gtk_widget_show_all(vbox);
352
353         ldapedit.window     = window;
354         ldapedit.notebook   = notebook;
355         ldapedit.ok_btn     = ok_btn;
356         ldapedit.cancel_btn = cancel_btn;
357         ldapedit.statusbar  = statusbar;
358         ldapedit.status_cid =
359                 gtk_statusbar_get_context_id(
360                         GTK_STATUSBAR(statusbar), "Edit LDAP Server Dialog" );
361 }
362
363 static void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) {
364         GtkWidget *vbox;
365         GtkWidget *table;
366         GtkWidget *label;
367         GtkWidget *entry_name;
368         GtkWidget *entry_server;
369         GtkWidget *hbox_spin;
370         GtkObject *spinbtn_port_adj;
371         GtkWidget *spinbtn_port;
372         GtkWidget *entry_baseDN;
373         GtkWidget *check_btn;
374         GtkWidget *lookdn_btn;
375         gint top;
376
377         vbox = gtk_vbox_new( FALSE, 8 );
378         gtk_widget_show( vbox );
379         gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
380
381         label = gtk_label_new( pageLbl );
382         gtk_widget_show( label );
383         gtk_notebook_set_tab_label(
384                 GTK_NOTEBOOK( ldapedit.notebook ),
385                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
386
387         table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
388         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
389         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
390         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
391         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
392
393         /* First row */
394         top = 0;
395         label = gtk_label_new(_("Name"));
396         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
397         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
398
399         entry_name = gtk_entry_new();
400         gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1),
401                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
402
403         /* Next row */
404         ++top;
405         label = gtk_label_new(_("Hostname"));
406         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
407         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
408
409         entry_server = gtk_entry_new();
410         gtk_table_attach(GTK_TABLE(table), entry_server, 1, 2, top, (top + 1),
411                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
412
413         /* Next row */
414         ++top;
415         label = gtk_label_new(_("Port"));
416         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
417         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
418
419         hbox_spin = gtk_hbox_new (FALSE, 8);
420         spinbtn_port_adj = gtk_adjustment_new (389, 1, 65535, 100, 1000, 1000);
421         spinbtn_port = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_port_adj), 1, 0);
422         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_port, FALSE, FALSE, 0);
423         gtk_widget_set_size_request (spinbtn_port, 64, -1);
424         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_port), TRUE);
425         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
426                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
427
428         check_btn = gtk_button_new_with_label( _(" Check Server "));
429         gtk_table_attach(GTK_TABLE(table), check_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
430
431         /* Next row */
432         ++top;
433         label = gtk_label_new(_("Search Base"));
434         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
435         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
436
437         entry_baseDN = gtk_entry_new();
438         gtk_table_attach(GTK_TABLE(table), entry_baseDN, 1, 2, top, (top + 1),
439                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
440
441         lookdn_btn = gtk_button_new_with_label( _(" ... "));
442         gtk_table_attach(GTK_TABLE(table), lookdn_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
443
444         /* Signal handlers */
445         g_signal_connect(G_OBJECT(check_btn), "clicked",
446                          G_CALLBACK(edit_ldap_server_check), NULL);
447         g_signal_connect(G_OBJECT(lookdn_btn), "clicked",
448                          G_CALLBACK(edit_ldap_basedn_select), NULL);
449
450         /* Done */
451         gtk_widget_show_all(vbox);
452
453         ldapedit.entry_name   = entry_name;
454         ldapedit.entry_server = entry_server;
455         ldapedit.spinbtn_port = spinbtn_port;
456         ldapedit.entry_baseDN = entry_baseDN;
457 }
458
459 static void addressbook_edit_ldap_page_search( gint pageNum, gchar *pageLbl ) {
460         GtkWidget *vbox;
461         GtkWidget *table;
462         GtkWidget *label;
463         GtkWidget *entry_criteria;
464         GtkWidget *hbox_spin;
465         GtkObject *spinbtn_queryage_adj;
466         GtkWidget *spinbtn_queryage;
467         GtkWidget *check_dynsearch;
468         GtkWidget *reset_btn;
469         gint top;
470
471         vbox = gtk_vbox_new( FALSE, 8 );
472         gtk_widget_show( vbox );
473         gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
474
475         label = gtk_label_new( pageLbl );
476         gtk_widget_show( label );
477         gtk_notebook_set_tab_label(
478                 GTK_NOTEBOOK( ldapedit.notebook ),
479                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
480
481         table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
482         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
483         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
484         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
485         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
486
487         /* First row */
488         top = 0;
489         label = gtk_label_new(_("Search Attributes"));
490         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
491         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
492
493         entry_criteria = gtk_entry_new();
494         gtk_table_attach(GTK_TABLE(table), entry_criteria, 1, 2, top, (top + 1),
495                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
496
497         reset_btn = gtk_button_new_with_label( _(" Defaults "));
498         gtk_table_attach(GTK_TABLE(table), reset_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
499
500         /* Next row */
501         ++top;
502         label = gtk_label_new(_("Max Query Age (secs)"));
503         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
504         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
505
506         hbox_spin = gtk_hbox_new (FALSE, 8);
507         spinbtn_queryage_adj = gtk_adjustment_new(
508                 LDAPCTL_DFL_QUERY_AGE, 1, LDAPCTL_MAX_QUERY_AGE, 10, 1000, 1000 );
509         spinbtn_queryage = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_queryage_adj), 1, 0);
510         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_queryage, FALSE, FALSE, 0);
511         gtk_widget_set_size_request (spinbtn_queryage, 64, -1);
512         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_queryage), TRUE);
513         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
514                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
515
516         /* Next row */
517         ++top;
518         check_dynsearch = gtk_check_button_new_with_label(
519                                 _("Include server in dynamic search") );
520         gtk_table_attach(GTK_TABLE(table), check_dynsearch, 1, 3, top, (top + 1),
521                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
522
523         /* Signal handlers */
524         g_signal_connect(G_OBJECT(reset_btn), "clicked",
525                          G_CALLBACK(edit_ldap_search_reset), NULL);
526
527         /* Done */
528         gtk_widget_show_all(vbox);
529
530         ldapedit.entry_criteria   = entry_criteria;
531         ldapedit.spinbtn_queryage = spinbtn_queryage;
532         ldapedit.check_dynsearch  = check_dynsearch;
533 }
534
535 static void addressbook_edit_ldap_page_extended( gint pageNum, gchar *pageLbl ) {
536         GtkWidget *vbox;
537         GtkWidget *table;
538         GtkWidget *label;
539         GtkWidget *entry_bindDN;
540         GtkWidget *entry_bindPW;
541         GtkWidget *hbox_spin;
542         GtkObject *spinbtn_timeout_adj;
543         GtkWidget *spinbtn_timeout;
544         GtkObject *spinbtn_maxentry_adj;
545         GtkWidget *spinbtn_maxentry;
546         gint top;
547
548         vbox = gtk_vbox_new( FALSE, 8 );
549         gtk_widget_show( vbox );
550         gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
551
552         label = gtk_label_new( pageLbl );
553         gtk_widget_show( label );
554         gtk_notebook_set_tab_label(
555                 GTK_NOTEBOOK( ldapedit.notebook ),
556                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
557
558         table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
559         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
560         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
561         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
562         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
563
564         /* Next row */
565         top = 0;
566         label = gtk_label_new(_("Bind DN"));
567         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
568         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
569
570         entry_bindDN = gtk_entry_new();
571         gtk_table_attach(GTK_TABLE(table), entry_bindDN, 1, 2, top, (top + 1),
572                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
573
574         /* Next row */
575         ++top;
576         label = gtk_label_new(_("Bind Password"));
577         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
578         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
579
580         entry_bindPW = gtk_entry_new();
581         gtk_table_attach(GTK_TABLE(table), entry_bindPW, 1, 2, top, (top + 1),
582                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
583
584         /* Next row */
585         ++top;
586         label = gtk_label_new(_("Timeout (secs)"));
587         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
588         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
589
590         hbox_spin = gtk_hbox_new (FALSE, 8);
591         spinbtn_timeout_adj = gtk_adjustment_new (0, 0, 300, 1, 10, 10);
592         spinbtn_timeout = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_timeout_adj), 1, 0);
593         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_timeout, FALSE, FALSE, 0);
594         gtk_widget_set_size_request (spinbtn_timeout, 64, -1);
595         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_timeout), TRUE);
596         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
597                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
598
599         /* Next row */
600         ++top;
601         label = gtk_label_new(_("Maximum Entries"));
602         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
603         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
604
605         hbox_spin = gtk_hbox_new (FALSE, 8);
606         spinbtn_maxentry_adj = gtk_adjustment_new (0, 0, 500, 1, 10, 10);
607         spinbtn_maxentry = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_maxentry_adj), 1, 0);
608         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_maxentry, FALSE, FALSE, 0);
609         gtk_widget_set_size_request (spinbtn_maxentry, 64, -1);
610         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_maxentry), TRUE);
611         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
612                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
613
614         /* Done */
615         gtk_widget_show_all(vbox);
616
617         ldapedit.entry_bindDN     = entry_bindDN;
618         ldapedit.entry_bindPW     = entry_bindPW;
619         ldapedit.spinbtn_timeout  = spinbtn_timeout;
620         ldapedit.spinbtn_maxentry = spinbtn_maxentry;
621 }
622
623 static void addressbook_edit_ldap_create( gboolean *cancelled ) {
624         gint page = 0;
625         addressbook_edit_ldap_dialog_create( cancelled );
626         addressbook_edit_ldap_page_basic( page++, _( "Basic" ) );
627         addressbook_edit_ldap_page_search( page++, _( "Search" ) );
628         addressbook_edit_ldap_page_extended( page++, _( "Extended" ) );
629         gtk_widget_show_all( ldapedit.window );
630 }
631
632 void edit_ldap_set_optmenu( GtkOptionMenu *optmenu, const gint value ) {
633         GList *cur;
634         GtkWidget *menu;
635         GtkWidget *menuitem;
636         gint menuVal;
637         gint n = 0;
638
639         g_return_if_fail(optmenu != NULL);
640
641         menu = gtk_option_menu_get_menu(optmenu);
642         for( cur = GTK_MENU_SHELL(menu)->children; cur != NULL; cur = cur->next ) {
643                 menuitem = GTK_WIDGET(cur->data);
644                 menuVal = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem), "user_data"));
645                 if( menuVal == value ) {
646                         gtk_option_menu_set_history(optmenu, n);
647                         return;
648                 }
649                 n++;
650         }
651         gtk_option_menu_set_history(optmenu, 0);
652 }
653
654 gint edit_ldap_get_optmenu( GtkOptionMenu *optmenu ) {
655         GtkWidget *menu;
656         GtkWidget *menuitem;
657
658         g_return_val_if_fail(optmenu != NULL, -1);
659
660         menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu));
661         menuitem = gtk_menu_get_active(GTK_MENU(menu));
662         return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem), "user_data"));
663 }
664
665 /**
666  * Format criteria list for display.
667  * \param ctl Control object.
668  * \return Formatted string, or <i>NULL</i> if no attributes found.
669  */
670 static gchar *editldap_build_criteria_list( const LdapControl *ctl ) {
671         gchar *str = NULL;
672         gchar *tmp = NULL;
673         GList *node;
674
675         node = ldapctl_get_criteria_list( ctl );
676         while( node ) {
677                 gchar *attr = node->data;
678                 if( str ) {
679                         tmp = g_strdup_printf( "%s, %s", str, attr );
680                         g_free( str );
681                         str = tmp;
682                         tmp = NULL;
683                 }
684                 else {
685                         str = g_strdup( attr );
686                 }
687                 node = g_list_next( node );
688         }
689
690         return str;
691 }
692
693 /**
694  * Parse out individual attribute names from criteria string.
695  * \param criteria Criteria string.
696  * \ctl   Control object.
697  */
698 static void editldap_parse_criteria( gchar *criteria, LdapControl *ctl ) {
699         gchar *ptr;
700         gchar **splitStr;
701         gint i;
702
703         /* Replace delimiters with spaces */
704         ptr = criteria;
705         while( *ptr ) {
706                 if( *ptr == ',' || *ptr == ';' || *ptr == '|' )
707                         *ptr = ' ';
708                 ptr++;
709         }
710
711         /* Parse string */
712         ldapctl_criteria_list_clear( ctl );
713         splitStr = g_strsplit( criteria, " ", 0 );
714         i = 0;
715         while( TRUE ) {
716                 if( splitStr[i] ) {
717                         if( *splitStr[i] ) {
718                                 ldapctl_criteria_list_add( ctl, splitStr[i] );
719                         }
720                 }
721                 else {
722                         break;
723                 }
724                 i++;
725         }
726         g_strfreev( splitStr );
727 }
728
729 /**
730  * Clear entry fields to reasonable defaults (for a new server entry).
731  */
732 static void edit_ldap_clear_fields( void ) {
733         gtk_entry_set_text(
734                 GTK_ENTRY(ldapedit.entry_name), ADDRESSBOOK_GUESS_LDAP_NAME );
735         gtk_entry_set_text(
736                 GTK_ENTRY(ldapedit.entry_server), ADDRESSBOOK_GUESS_LDAP_SERVER );
737         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), "");
738         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindDN), "");
739         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindPW), "");
740         gtk_spin_button_set_value(
741                 GTK_SPIN_BUTTON( ldapedit.spinbtn_port ), LDAPCTL_DFL_PORT );
742         gtk_spin_button_set_value(
743                 GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ), LDAPCTL_DFL_TIMEOUT );
744         gtk_spin_button_set_value(
745                 GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ), LDAPCTL_DFL_TIMEOUT );
746         gtk_entry_set_text(
747                 GTK_ENTRY(ldapedit.entry_criteria), LDAPCTL_DFL_ATTR_LIST );
748         gtk_spin_button_set_value(
749                 GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), LDAPCTL_DFL_QUERY_AGE );
750         gtk_toggle_button_set_active(
751                 GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), TRUE );
752 }
753
754 /**
755  * Load entry fields from server control data.
756  * \param server Server object.
757  */
758 static void edit_ldap_set_fields( LdapServer *server ) {
759         LdapControl *ctl;
760         gchar *crit;
761
762         if( ldapsvr_get_name( server ) )
763                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_name),
764                 ldapsvr_get_name( server ) );
765
766         ctl = server->control;
767         if( ctl->hostName )
768                 gtk_entry_set_text(
769                         GTK_ENTRY(ldapedit.entry_server), ctl->hostName);
770         if( ctl->baseDN )
771                 gtk_entry_set_text(
772                         GTK_ENTRY(ldapedit.entry_baseDN), ctl->baseDN );
773         if( ctl->bindDN )
774                 gtk_entry_set_text(
775                         GTK_ENTRY(ldapedit.entry_bindDN), ctl->bindDN );
776         if( ctl->bindPass )
777                 gtk_entry_set_text(
778                         GTK_ENTRY(ldapedit.entry_bindPW), ctl->bindPass );
779         gtk_spin_button_set_value(
780                 GTK_SPIN_BUTTON(ldapedit.spinbtn_port), ctl->port );
781         gtk_spin_button_set_value(
782                 GTK_SPIN_BUTTON(ldapedit.spinbtn_timeout), ctl->timeOut );
783         gtk_spin_button_set_value(
784                 GTK_SPIN_BUTTON(ldapedit.spinbtn_maxentry), ctl->maxEntries );
785
786         /* Format criteria */
787         crit = editldap_build_criteria_list( ctl );
788         if( crit ) {
789                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), crit );
790                 g_free( crit );
791         }
792         else {
793                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), "" );
794         }
795         gtk_spin_button_set_value(
796                 GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), ctl->maxQueryAge );
797         gtk_toggle_button_set_active(
798                 GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), server->searchFlag );
799 }
800
801 AdapterDSource *addressbook_edit_ldap( AddressIndex *addrIndex, AdapterDSource *ads ) {
802         static gboolean cancelled;
803         gchar *sName, *sHost, *sBase, *sBind, *sPass, *sCrit;
804         gint iPort, iMaxE, iTime, iAge;
805         gboolean bSrch;
806         AddressDataSource *ds = NULL;
807         LdapServer *server = NULL;
808         LdapControl *ctl = NULL;
809         gboolean fin;
810
811         if (!ldapedit.window)
812                 addressbook_edit_ldap_create(&cancelled);
813         gtk_notebook_set_current_page( GTK_NOTEBOOK(ldapedit.notebook), PAGE_BASIC );
814         gtk_widget_grab_focus(ldapedit.ok_btn);
815         gtk_widget_grab_focus(ldapedit.entry_name);
816         gtk_widget_show(ldapedit.window);
817         manage_window_set_transient(GTK_WINDOW(ldapedit.window));
818
819         edit_ldap_status_show( "" );
820         if( ads ) {
821                 ds = ads->dataSource;
822                 server = ds->rawDataSource;
823                 edit_ldap_set_fields( server );
824                 gtk_window_set_title(
825                         GTK_WINDOW(ldapedit.window), _("Edit LDAP Server"));
826         }
827         else {
828                 edit_ldap_clear_fields();
829                 gtk_window_set_title(
830                         GTK_WINDOW(ldapedit.window), _("Add New LDAP Server"));
831         }
832
833         gtk_main();
834         gtk_widget_hide(ldapedit.window);
835         if (cancelled == TRUE) return NULL;
836
837         sName = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_name), 0, -1 );
838         sHost = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
839         sBase = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_baseDN), 0, -1 );
840         sCrit = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_criteria), 0, -1 );
841         sBind = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
842         sPass = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
843         iPort = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
844         iTime = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
845         iMaxE = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ) );
846         iAge  = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_queryage ) );
847         bSrch = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch ) );
848
849         fin = FALSE;
850         if( *sName == '\0' ) fin = TRUE;
851         if( *sHost == '\0' ) fin = TRUE;
852
853         if( ! fin ) {
854                 /* Save changes */
855                 if( ! ads ) {
856                         /* New server */
857                         server = ldapsvr_create();
858                         ds = addrindex_index_add_datasource( addrIndex, ADDR_IF_LDAP, server );
859                         ads = addressbook_create_ds_adapter( ds, ADDR_LDAP, NULL );
860                 }
861                 ctl = server->control;
862                 addressbook_ads_set_name( ads, sName );
863                 ldapsvr_set_name( server, sName );
864                 ldapsvr_set_search_flag( server, bSrch );
865                 ldapctl_set_host( ctl, sHost );
866                 ldapctl_set_base_dn( ctl, sBase );
867                 ldapctl_set_bind_dn( ctl, sBind );
868                 ldapctl_set_bind_password( ctl, sPass );
869                 ldapctl_set_port( ctl, iPort );
870                 ldapctl_set_max_entries( ctl, iMaxE );
871                 ldapctl_set_timeout( ctl, iTime );
872                 ldapctl_set_max_query_age( ctl, iAge );
873
874                 /* Save attributes */
875                 editldap_parse_criteria( sCrit, ctl );
876
877         }
878         g_free( sName );
879         g_free( sHost );
880         g_free( sBase );
881         g_free( sBind );
882         g_free( sPass );
883         g_free( sCrit );
884
885         return ads;
886 }
887
888 #endif /* USE_LDAP */
889
890 /*
891 * End of Source.
892 */