212c01bfa8ce2958049076822de4a3a34d729f7f
[claws.git] / src / editldap.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2001-2002 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_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 void 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 }
210
211 static void edit_ldap_server_check( void ) {
212         gchar *sHost, *sBind, *sPass;
213         gint iPort, iTime;
214         gchar *sMsg;
215         gchar *sBaseDN = NULL;
216         gint iBaseDN = 0;
217         gboolean flg;
218         GList *baseDN = NULL;
219
220         edit_ldap_status_show( "" );
221         flg = FALSE;
222         sHost = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
223         sBind = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
224         sPass = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
225         iPort = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
226         iTime = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
227         g_strchomp( sHost ); g_strchug( sHost );
228         g_strchomp( sBind ); g_strchug( sBind );
229         g_strchomp( sPass ); g_strchug( sPass );
230         if( *sHost != '\0' ) {
231                 /* Test connection to server */
232                 if( ldaputil_test_connect( sHost, iPort ) ) {
233                         /* Attempt to read base DN */
234                         baseDN = ldaputil_read_basedn( sHost, iPort, sBind, sPass, iTime );
235                         if( baseDN ) {
236                                 GList *node = baseDN;
237                                 while( node ) {
238                                         ++iBaseDN;
239                                         if( ! sBaseDN ) {
240                                                 sBaseDN = g_strdup( node->data );
241                                         }
242                                         node = g_list_next( node );
243                                 }
244                                 mgu_free_dlist( baseDN );
245                                 baseDN = node = NULL;
246                         }
247                         flg = TRUE;
248                 }
249         }
250         g_free( sHost );
251         g_free( sBind );
252         g_free( sPass );
253
254         if( sBaseDN ) {
255                 /* Load search DN */
256                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), sBaseDN);
257                 g_free( sBaseDN );
258         }
259
260         /* Display appropriate message */
261         if( flg ) {
262                 sMsg = _( "Connected successfully to server" );
263         }
264         else {
265                 sMsg = _( "Could not connect to server" );
266         }
267         edit_ldap_status_show( sMsg );
268 }
269
270 static void edit_ldap_basedn_select( void ) {
271         gchar *sHost, *sBind, *sPass, *sBase;
272         gint iPort, iTime;
273         gchar *selectDN;
274
275         sHost = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
276         sBase = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_baseDN), 0, -1 );
277         sBind = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
278         sPass = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
279         iPort = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
280         iTime = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
281         g_strchomp( sHost ); g_strchug( sHost );
282         g_strchomp( sBind ); g_strchug( sBind );
283         g_strchomp( sPass ); g_strchug( sPass );
284         selectDN = edit_ldap_basedn_selection( sHost, iPort, sBase, iTime, sBind, sPass );
285         if( selectDN ) {
286                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), selectDN);
287                 g_free( selectDN );
288                 selectDN = NULL;
289         }
290         g_free( sHost );
291         g_free( sBase );
292         g_free( sBind );
293         g_free( sPass );
294 }
295
296 static void edit_ldap_search_reset( void ) {
297         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), LDAPCTL_DFL_ATTR_LIST );
298 }
299
300 static void addressbook_edit_ldap_dialog_create( gboolean *cancelled ) {
301         GtkWidget *window;
302         GtkWidget *vbox;
303         GtkWidget *notebook;
304         GtkWidget *hbbox;
305         GtkWidget *ok_btn;
306         GtkWidget *cancel_btn;
307         GtkWidget *hsbox;
308         GtkWidget *statusbar;
309
310         window = gtk_window_new(GTK_WINDOW_DIALOG);
311         gtk_widget_set_usize(window, 450, -1);
312         gtk_container_set_border_width(GTK_CONTAINER(window), 0);
313         gtk_window_set_title(GTK_WINDOW(window), _("Edit LDAP Server"));
314         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
315         gtk_window_set_modal(GTK_WINDOW(window), TRUE); 
316         gtk_signal_connect(GTK_OBJECT(window), "delete_event",
317                            GTK_SIGNAL_FUNC(edit_ldap_delete_event),
318                            cancelled);
319         gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
320                            GTK_SIGNAL_FUNC(edit_ldap_key_pressed),
321                            cancelled);
322
323         vbox = gtk_vbox_new( FALSE, 6 );
324         gtk_widget_show( vbox );
325         gtk_container_add( GTK_CONTAINER( window ), vbox );
326
327         /* Notebook */
328         notebook = gtk_notebook_new();
329         gtk_widget_show( notebook );
330         gtk_box_pack_start( GTK_BOX( vbox ), notebook, TRUE, TRUE, 0 );
331         gtk_container_set_border_width( GTK_CONTAINER( notebook ), 6 );
332
333         /* Status line */
334         hsbox = gtk_hbox_new(FALSE, 0);
335         gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
336         statusbar = gtk_statusbar_new();
337         gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
338
339         /* Button panel */
340         gtkut_button_set_create(&hbbox, &ok_btn, _("OK"),
341                                 &cancel_btn, _("Cancel"), NULL, NULL);
342         gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
343         gtk_widget_grab_default(ok_btn);
344
345         gtk_signal_connect(GTK_OBJECT(ok_btn), "clicked",
346                            GTK_SIGNAL_FUNC(edit_ldap_ok), cancelled);
347         gtk_signal_connect(GTK_OBJECT(cancel_btn), "clicked",
348                            GTK_SIGNAL_FUNC(edit_ldap_cancel), cancelled);
349
350         gtk_widget_show_all(vbox);
351
352         ldapedit.window     = window;
353         ldapedit.notebook   = notebook;
354         ldapedit.ok_btn     = ok_btn;
355         ldapedit.cancel_btn = cancel_btn;
356         ldapedit.statusbar  = statusbar;
357         ldapedit.status_cid =
358                 gtk_statusbar_get_context_id(
359                         GTK_STATUSBAR(statusbar), "Edit LDAP Server Dialog" );
360 }
361
362 static void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) {
363         GtkWidget *vbox;
364         GtkWidget *table;
365         GtkWidget *label;
366         GtkWidget *entry_name;
367         GtkWidget *entry_server;
368         GtkWidget *hbox_spin;
369         GtkObject *spinbtn_port_adj;
370         GtkWidget *spinbtn_port;
371         GtkWidget *entry_baseDN;
372         GtkWidget *check_btn;
373         GtkWidget *lookdn_btn;
374         gint top;
375
376         vbox = gtk_vbox_new( FALSE, 8 );
377         gtk_widget_show( vbox );
378         gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
379
380         label = gtk_label_new( pageLbl );
381         gtk_widget_show( label );
382         gtk_notebook_set_tab_label(
383                 GTK_NOTEBOOK( ldapedit.notebook ),
384                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
385
386         table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
387         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
388         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
389         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
390         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
391
392         /* First row */
393         top = 0;
394         label = gtk_label_new(_("Name"));
395         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
396         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
397
398         entry_name = gtk_entry_new();
399         gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1),
400                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
401
402         /* Next row */
403         ++top;
404         label = gtk_label_new(_("Hostname"));
405         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
406         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
407
408         entry_server = gtk_entry_new();
409         gtk_table_attach(GTK_TABLE(table), entry_server, 1, 2, top, (top + 1),
410                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
411
412         /* Next row */
413         ++top;
414         label = gtk_label_new(_("Port"));
415         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
416         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
417
418         hbox_spin = gtk_hbox_new (FALSE, 8);
419         spinbtn_port_adj = gtk_adjustment_new (389, 1, 65535, 100, 1000, 1000);
420         spinbtn_port = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_port_adj), 1, 0);
421         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_port, FALSE, FALSE, 0);
422         gtk_widget_set_usize (spinbtn_port, 64, -1);
423         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_port), TRUE);
424         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
425                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
426
427         check_btn = gtk_button_new_with_label( _(" Check Server "));
428         gtk_table_attach(GTK_TABLE(table), check_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
429
430         /* Next row */
431         ++top;
432         label = gtk_label_new(_("Search Base"));
433         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
434         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
435
436         entry_baseDN = gtk_entry_new();
437         gtk_table_attach(GTK_TABLE(table), entry_baseDN, 1, 2, top, (top + 1),
438                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
439
440         lookdn_btn = gtk_button_new_with_label( _(" ... "));
441         gtk_table_attach(GTK_TABLE(table), lookdn_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
442
443         /* Signal handlers */
444         gtk_signal_connect(GTK_OBJECT(check_btn), "clicked",
445                            GTK_SIGNAL_FUNC(edit_ldap_server_check), NULL);
446         gtk_signal_connect(GTK_OBJECT(lookdn_btn), "clicked",
447                            GTK_SIGNAL_FUNC(edit_ldap_basedn_select), NULL);
448
449         /* Done */
450         gtk_widget_show_all(vbox);
451
452         ldapedit.entry_name   = entry_name;
453         ldapedit.entry_server = entry_server;
454         ldapedit.spinbtn_port = spinbtn_port;
455         ldapedit.entry_baseDN = entry_baseDN;
456 }
457
458 static void addressbook_edit_ldap_page_search( gint pageNum, gchar *pageLbl ) {
459         GtkWidget *vbox;
460         GtkWidget *table;
461         GtkWidget *label;
462         GtkWidget *entry_criteria;
463         GtkWidget *hbox_spin;
464         GtkObject *spinbtn_queryage_adj;
465         GtkWidget *spinbtn_queryage;
466         GtkWidget *check_dynsearch;
467         GtkWidget *reset_btn;
468         gint top;
469
470         vbox = gtk_vbox_new( FALSE, 8 );
471         gtk_widget_show( vbox );
472         gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
473
474         label = gtk_label_new( pageLbl );
475         gtk_widget_show( label );
476         gtk_notebook_set_tab_label(
477                 GTK_NOTEBOOK( ldapedit.notebook ),
478                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
479
480         table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
481         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
482         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
483         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
484         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
485
486         /* First row */
487         top = 0;
488         label = gtk_label_new(_("Search Attributes"));
489         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
490         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
491
492         entry_criteria = gtk_entry_new();
493         gtk_table_attach(GTK_TABLE(table), entry_criteria, 1, 2, top, (top + 1),
494                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
495
496         reset_btn = gtk_button_new_with_label( _(" Defaults "));
497         gtk_table_attach(GTK_TABLE(table), reset_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
498
499         /* Next row */
500         ++top;
501         label = gtk_label_new(_("Max Query Age (secs)"));
502         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
503         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
504
505         hbox_spin = gtk_hbox_new (FALSE, 8);
506         spinbtn_queryage_adj = gtk_adjustment_new(
507                 LDAPCTL_DFL_QUERY_AGE, 1, LDAPCTL_MAX_QUERY_AGE, 10, 1000, 1000 );
508         spinbtn_queryage = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_queryage_adj), 1, 0);
509         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_queryage, FALSE, FALSE, 0);
510         gtk_widget_set_usize (spinbtn_queryage, 64, -1);
511         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_queryage), TRUE);
512         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
513                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
514
515         /* Next row */
516         ++top;
517         check_dynsearch = gtk_check_button_new_with_label(
518                                 _("Include server in dynamic search") );
519         gtk_table_attach(GTK_TABLE(table), check_dynsearch, 1, 3, top, (top + 1),
520                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
521
522         /* Signal handlers */
523         gtk_signal_connect(GTK_OBJECT(reset_btn), "clicked",
524                            GTK_SIGNAL_FUNC(edit_ldap_search_reset), NULL);
525
526         /* Done */
527         gtk_widget_show_all(vbox);
528
529         ldapedit.entry_criteria   = entry_criteria;
530         ldapedit.spinbtn_queryage = spinbtn_queryage;
531         ldapedit.check_dynsearch  = check_dynsearch;
532 }
533
534 static void addressbook_edit_ldap_page_extended( gint pageNum, gchar *pageLbl ) {
535         GtkWidget *vbox;
536         GtkWidget *table;
537         GtkWidget *label;
538         GtkWidget *entry_bindDN;
539         GtkWidget *entry_bindPW;
540         GtkWidget *hbox_spin;
541         GtkObject *spinbtn_timeout_adj;
542         GtkWidget *spinbtn_timeout;
543         GtkObject *spinbtn_maxentry_adj;
544         GtkWidget *spinbtn_maxentry;
545         gint top;
546
547         vbox = gtk_vbox_new( FALSE, 8 );
548         gtk_widget_show( vbox );
549         gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
550
551         label = gtk_label_new( pageLbl );
552         gtk_widget_show( label );
553         gtk_notebook_set_tab_label(
554                 GTK_NOTEBOOK( ldapedit.notebook ),
555                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
556
557         table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
558         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
559         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
560         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
561         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
562
563         /* Next row */
564         top = 0;
565         label = gtk_label_new(_("Bind DN"));
566         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
567         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
568
569         entry_bindDN = gtk_entry_new();
570         gtk_table_attach(GTK_TABLE(table), entry_bindDN, 1, 2, top, (top + 1),
571                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
572
573         /* Next row */
574         ++top;
575         label = gtk_label_new(_("Bind Password"));
576         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
577         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
578
579         entry_bindPW = gtk_entry_new();
580         gtk_table_attach(GTK_TABLE(table), entry_bindPW, 1, 2, top, (top + 1),
581                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
582
583         /* Next row */
584         ++top;
585         label = gtk_label_new(_("Timeout (secs)"));
586         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
587         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
588
589         hbox_spin = gtk_hbox_new (FALSE, 8);
590         spinbtn_timeout_adj = gtk_adjustment_new (0, 0, 300, 1, 10, 10);
591         spinbtn_timeout = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_timeout_adj), 1, 0);
592         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_timeout, FALSE, FALSE, 0);
593         gtk_widget_set_usize (spinbtn_timeout, 64, -1);
594         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_timeout), TRUE);
595         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
596                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
597
598         /* Next row */
599         ++top;
600         label = gtk_label_new(_("Maximum Entries"));
601         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
602         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
603
604         hbox_spin = gtk_hbox_new (FALSE, 8);
605         spinbtn_maxentry_adj = gtk_adjustment_new (0, 0, 500, 1, 10, 10);
606         spinbtn_maxentry = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_maxentry_adj), 1, 0);
607         gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_maxentry, FALSE, FALSE, 0);
608         gtk_widget_set_usize (spinbtn_maxentry, 64, -1);
609         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_maxentry), TRUE);
610         gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
611                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
612
613         /* Done */
614         gtk_widget_show_all(vbox);
615
616         ldapedit.entry_bindDN     = entry_bindDN;
617         ldapedit.entry_bindPW     = entry_bindPW;
618         ldapedit.spinbtn_timeout  = spinbtn_timeout;
619         ldapedit.spinbtn_maxentry = spinbtn_maxentry;
620 }
621
622 static void addressbook_edit_ldap_create( gboolean *cancelled ) {
623         gint page = 0;
624         addressbook_edit_ldap_dialog_create( cancelled );
625         addressbook_edit_ldap_page_basic( page++, _( "Basic" ) );
626         addressbook_edit_ldap_page_search( page++, _( "Search" ) );
627         addressbook_edit_ldap_page_extended( page++, _( "Extended" ) );
628         gtk_widget_show_all( ldapedit.window );
629 }
630
631 void edit_ldap_set_optmenu( GtkOptionMenu *optmenu, const gint value ) {
632         GList *cur;
633         GtkWidget *menu;
634         GtkWidget *menuitem;
635         gint menuVal;
636         gint n = 0;
637
638         g_return_if_fail(optmenu != NULL);
639
640         menu = gtk_option_menu_get_menu(optmenu);
641         for( cur = GTK_MENU_SHELL(menu)->children; cur != NULL; cur = cur->next ) {
642                 menuitem = GTK_WIDGET(cur->data);
643                 menuVal = GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(menuitem)));
644                 if( menuVal == value ) {
645                         gtk_option_menu_set_history(optmenu, n);
646                         return;
647                 }
648                 n++;
649         }
650         gtk_option_menu_set_history(optmenu, 0);
651 }
652
653 gint edit_ldap_get_optmenu( GtkOptionMenu *optmenu ) {
654         GtkWidget *menu;
655         GtkWidget *menuitem;
656
657         g_return_val_if_fail(optmenu != NULL, -1);
658
659         menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu));
660         menuitem = gtk_menu_get_active(GTK_MENU(menu));
661         return GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(menuitem)));
662 }
663
664 /**
665  * Format criteria list for display.
666  * \param ctl Control object.
667  * \return Formatted string, or <i>NULL</i> if no attributes found.
668  */
669 static gchar *editldap_build_criteria_list( const LdapControl *ctl ) {
670         gchar *str = NULL;
671         gchar *tmp = NULL;
672         GList *node;
673
674         node = ldapctl_get_criteria_list( ctl );
675         while( node ) {
676                 gchar *attr = node->data;
677                 if( str ) {
678                         tmp = g_strdup_printf( "%s, %s", str, attr );
679                         g_free( str );
680                         str = tmp;
681                         tmp = NULL;
682                 }
683                 else {
684                         str = g_strdup( attr );
685                 }
686                 node = g_list_next( node );
687         }
688
689         return str;
690 }
691
692 /**
693  * Parse out individual attribute names from criteria string.
694  * \param criteria Criteria string.
695  * \ctl   Control object.
696  */
697 static void editldap_parse_criteria( gchar *criteria, LdapControl *ctl ) {
698         gchar *ptr;
699         gchar **splitStr;
700         gint i;
701
702         /* Replace delimiters with spaces */
703         ptr = criteria;
704         while( *ptr ) {
705                 if( *ptr == ',' || *ptr == ';' || *ptr == '|' )
706                         *ptr = ' ';
707                 ptr++;
708         }
709
710         /* Parse string */
711         ldapctl_criteria_list_clear( ctl );
712         splitStr = g_strsplit( criteria, " ", 0 );
713         i = 0;
714         while( TRUE ) {
715                 if( splitStr[i] ) {
716                         if( *splitStr[i] ) {
717                                 ldapctl_criteria_list_add( ctl, splitStr[i] );
718                         }
719                 }
720                 else {
721                         break;
722                 }
723                 i++;
724         }
725         g_strfreev( splitStr );
726 }
727
728 /**
729  * Clear entry fields to reasonable defaults (for a new server entry).
730  */
731 static void edit_ldap_clear_fields( void ) {
732         gtk_entry_set_text(
733                 GTK_ENTRY(ldapedit.entry_name), ADDRESSBOOK_GUESS_LDAP_NAME );
734         gtk_entry_set_text(
735                 GTK_ENTRY(ldapedit.entry_server), ADDRESSBOOK_GUESS_LDAP_SERVER );
736         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), "");
737         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindDN), "");
738         gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindPW), "");
739         gtk_spin_button_set_value(
740                 GTK_SPIN_BUTTON( ldapedit.spinbtn_port ), LDAPCTL_DFL_PORT );
741         gtk_spin_button_set_value(
742                 GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ), LDAPCTL_DFL_TIMEOUT );
743         gtk_spin_button_set_value(
744                 GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ), LDAPCTL_DFL_TIMEOUT );
745         gtk_entry_set_text(
746                 GTK_ENTRY(ldapedit.entry_criteria), LDAPCTL_DFL_ATTR_LIST );
747         gtk_spin_button_set_value(
748                 GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), LDAPCTL_DFL_QUERY_AGE );
749         gtk_toggle_button_set_active(
750                 GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), TRUE );
751 }
752
753 /**
754  * Load entry fields from server control data.
755  * \param server Server object.
756  */
757 static void edit_ldap_set_fields( LdapServer *server ) {
758         LdapControl *ctl;
759         gchar *crit;
760
761         if( ldapsvr_get_name( server ) )
762                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_name),
763                 ldapsvr_get_name( server ) );
764
765         ctl = server->control;
766         if( ctl->hostName )
767                 gtk_entry_set_text(
768                         GTK_ENTRY(ldapedit.entry_server), ctl->hostName);
769         if( ctl->baseDN )
770                 gtk_entry_set_text(
771                         GTK_ENTRY(ldapedit.entry_baseDN), ctl->baseDN );
772         if( ctl->bindDN )
773                 gtk_entry_set_text(
774                         GTK_ENTRY(ldapedit.entry_bindDN), ctl->bindDN );
775         if( ctl->bindPass )
776                 gtk_entry_set_text(
777                         GTK_ENTRY(ldapedit.entry_bindPW), ctl->bindPass );
778         gtk_spin_button_set_value(
779                 GTK_SPIN_BUTTON(ldapedit.spinbtn_port), ctl->port );
780         gtk_spin_button_set_value(
781                 GTK_SPIN_BUTTON(ldapedit.spinbtn_timeout), ctl->timeOut );
782         gtk_spin_button_set_value(
783                 GTK_SPIN_BUTTON(ldapedit.spinbtn_maxentry), ctl->maxEntries );
784
785         /* Format criteria */
786         crit = editldap_build_criteria_list( ctl );
787         if( crit ) {
788                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), crit );
789                 g_free( crit );
790         }
791         else {
792                 gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), "" );
793         }
794         gtk_spin_button_set_value(
795                 GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), ctl->maxQueryAge );
796         gtk_toggle_button_set_active(
797                 GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), server->searchFlag );
798 }
799
800 AdapterDSource *addressbook_edit_ldap( AddressIndex *addrIndex, AdapterDSource *ads ) {
801         static gboolean cancelled;
802         gchar *sName, *sHost, *sBase, *sBind, *sPass, *sCrit;
803         gint iPort, iMaxE, iTime, iAge;
804         gboolean bSrch;
805         AddressDataSource *ds = NULL;
806         LdapServer *server = NULL;
807         LdapControl *ctl = NULL;
808         gboolean fin;
809
810         if (!ldapedit.window)
811                 addressbook_edit_ldap_create(&cancelled);
812         gtk_notebook_set_page( GTK_NOTEBOOK(ldapedit.notebook), PAGE_BASIC );
813         gtk_widget_grab_focus(ldapedit.ok_btn);
814         gtk_widget_grab_focus(ldapedit.entry_name);
815         gtk_widget_show(ldapedit.window);
816         manage_window_set_transient(GTK_WINDOW(ldapedit.window));
817
818         edit_ldap_status_show( "" );
819         if( ads ) {
820                 ds = ads->dataSource;
821                 server = ds->rawDataSource;
822                 edit_ldap_set_fields( server );
823                 gtk_window_set_title(
824                         GTK_WINDOW(ldapedit.window), _("Edit LDAP Server"));
825         }
826         else {
827                 edit_ldap_clear_fields();
828                 gtk_window_set_title(
829                         GTK_WINDOW(ldapedit.window), _("Add New LDAP Server"));
830         }
831
832         gtk_main();
833         gtk_widget_hide(ldapedit.window);
834         if (cancelled == TRUE) return NULL;
835
836         sName = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_name), 0, -1 );
837         sHost = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
838         sBase = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_baseDN), 0, -1 );
839         sCrit = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_criteria), 0, -1 );
840         sBind = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
841         sPass = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
842         iPort = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
843         iTime = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
844         iMaxE = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ) );
845         iAge  = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_queryage ) );
846         bSrch = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch ) );
847
848         fin = FALSE;
849         if( *sName == '\0' ) fin = TRUE;
850         if( *sHost == '\0' ) fin = TRUE;
851
852         if( ! fin ) {
853                 /* Save changes */
854                 if( ! ads ) {
855                         /* New server */
856                         server = ldapsvr_create();
857                         ds = addrindex_index_add_datasource( addrIndex, ADDR_IF_LDAP, server );
858                         ads = addressbook_create_ds_adapter( ds, ADDR_LDAP, NULL );
859                 }
860                 ctl = server->control;
861                 addressbook_ads_set_name( ads, sName );
862                 ldapsvr_set_name( server, sName );
863                 ldapsvr_set_search_flag( server, bSrch );
864                 ldapctl_set_host( ctl, sHost );
865                 ldapctl_set_base_dn( ctl, sBase );
866                 ldapctl_set_bind_dn( ctl, sBind );
867                 ldapctl_set_bind_password( ctl, sPass );
868                 ldapctl_set_port( ctl, iPort );
869                 ldapctl_set_max_entries( ctl, iMaxE );
870                 ldapctl_set_timeout( ctl, iTime );
871                 ldapctl_set_max_query_age( ctl, iAge );
872
873                 /* Save attributes */
874                 editldap_parse_criteria( sCrit, ctl );
875
876         }
877         g_free( sName );
878         g_free( sHost );
879         g_free( sBase );
880         g_free( sBind );
881         g_free( sPass );
882         g_free( sCrit );
883
884         return ads;
885 }
886
887 #endif /* USE_LDAP */
888
889 /*
890 * End of Source.
891 */