never commit before coffee
[claws.git] / src / exphtmldlg.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2002-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  * Export address book to HTML file.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27
28 #include "defs.h"
29
30 #include <glib.h>
31 #include <gdk/gdkkeysyms.h>
32 #include <gtk/gtkwindow.h>
33 #include <gtk/gtksignal.h>
34 #include <gtk/gtklabel.h>
35 #include <gtk/gtkentry.h>
36 #include <gtk/gtktable.h>
37 #include <gtk/gtkbutton.h>
38
39 #include "intl.h"
40 #include "gtkutils.h"
41 #include "prefs_common.h"
42 #include "alertpanel.h"
43 #include "mgutils.h"
44 #include "addrcache.h"
45 #include "addressitem.h"
46 #include "exporthtml.h"
47 #include "utils.h"
48 #include "manage_window.h"
49
50 #define PAGE_FILE_INFO             0
51 #define PAGE_FORMAT                1
52 #define PAGE_FINISH                2
53
54 #define EXPORTHTML_WIDTH           480
55 #define EXPORTHTML_HEIGHT          -1
56
57 /**
58  * Dialog object.
59  */
60 static struct _ExpHtml_Dlg {
61         GtkWidget *window;
62         GtkWidget *notebook;
63         GtkWidget *labelBook;
64         GtkWidget *entryHtml;
65         GtkWidget *optmenuCSS;
66         GtkWidget *optmenuName;
67         GtkWidget *checkBanding;
68         GtkWidget *checkLinkEMail;
69         GtkWidget *checkAttributes;
70         GtkWidget *labelOutBook;
71         GtkWidget *labelOutFile;
72         GtkWidget *btnPrev;
73         GtkWidget *btnNext;
74         GtkWidget *btnCancel;
75         GtkWidget *statusbar;
76         gint      status_cid;
77         gboolean  cancelled;
78 } exphtml_dlg;
79
80 static struct _AddressFileSelection _exp_html_file_selector_;
81
82 static ExportHtmlCtl *_exportCtl_ = NULL;
83 static AddressCache *_addressCache_ = NULL;
84
85 /**
86  * Display message in status field.
87  * \param msg Message to display.
88  */
89 static void export_html_status_show( gchar *msg ) {
90         if( exphtml_dlg.statusbar != NULL ) {
91                 gtk_statusbar_pop(
92                         GTK_STATUSBAR(exphtml_dlg.statusbar),
93                         exphtml_dlg.status_cid );
94                 if( msg ) {
95                         gtk_statusbar_push(
96                                 GTK_STATUSBAR(exphtml_dlg.statusbar),
97                                 exphtml_dlg.status_cid, msg );
98                 }
99         }
100 }
101
102 /**
103  * Select and display status message appropriate for the page being displayed.
104  */
105 static void export_html_message( void ) {
106         gchar *sMsg = NULL;
107         gint pageNum;
108
109         pageNum = gtk_notebook_current_page( GTK_NOTEBOOK(exphtml_dlg.notebook) );
110         if( pageNum == PAGE_FILE_INFO ) {
111                 sMsg = _( "Please specify output directory and file to create." );
112         }
113         else if( pageNum == PAGE_FORMAT ) {
114                 sMsg = _( "Select stylesheet and formatting." );
115         }
116         else if( pageNum == PAGE_FINISH ) {
117                 sMsg = _( "File exported successfully." );
118         }
119         export_html_status_show( sMsg );
120 }
121
122 /**
123  * Callback function to cancel HTML file selection dialog.
124  * \param widget Widget (button).
125  * \param data   User data.
126  */
127 static void export_html_cancel( GtkWidget *widget, gpointer data ) {
128         gint pageNum;
129
130         pageNum = gtk_notebook_current_page( GTK_NOTEBOOK(exphtml_dlg.notebook) );
131         if( pageNum != PAGE_FINISH ) {
132                 exphtml_dlg.cancelled = TRUE;
133         }
134         gtk_main_quit();
135 }
136
137 /**
138  * Callback function to handle dialog close event.
139  * \param widget Widget (dialog).
140  * \param event  Event object.
141  * \param data   User data.
142  */
143 static gint export_html_delete_event( GtkWidget *widget, GdkEventAny *event, gpointer data ) {
144         export_html_cancel( widget, data );
145         return TRUE;
146 }
147
148 /**
149  * Callback function to respond to dialog key press events.
150  * \param widget Widget.
151  * \param event  Event object.
152  * \param data   User data.
153  */
154 static gboolean export_html_key_pressed( GtkWidget *widget, GdkEventKey *event, gpointer data ) {
155         if (event && event->keyval == GDK_Escape) {
156                 export_html_cancel( widget, data );
157         }
158         return FALSE;
159 }
160
161 /**
162  * Test whether we can move off file page.
163  * \return <i>TRUE</i> if OK to move off page.
164  */
165 static gboolean exp_html_move_file( void ) {
166         gchar *sFile, *msg, *reason;
167         AlertValue aval;
168
169         sFile = gtk_editable_get_chars( GTK_EDITABLE(exphtml_dlg.entryHtml), 0, -1 );
170         g_strchug( sFile ); g_strchomp( sFile );
171         gtk_entry_set_text( GTK_ENTRY(exphtml_dlg.entryHtml), sFile );
172         exporthtml_parse_filespec( _exportCtl_, sFile );
173         g_free( sFile );
174
175         /* Test for directory */
176         if( exporthtml_test_dir( _exportCtl_ ) ) {
177                 return TRUE;
178         }
179
180         /* Prompt to create */
181         msg = g_strdup_printf( _(
182                 "HTML Output Directory '%s'\n" \
183                 "does not exist. OK to create new directory?" ),
184                 _exportCtl_->dirOutput );
185         aval = alertpanel( _("Create Directory" ),
186                 msg, _( "Yes" ), _( "No" ), NULL );
187         g_free( msg );
188         if( aval != G_ALERTDEFAULT ) return FALSE;
189
190         /* Create directory */
191         if( ! exporthtml_create_dir( _exportCtl_ ) ) {
192                 reason = exporthtml_get_create_msg( _exportCtl_ );
193                 msg = g_strdup_printf( _(
194                         "Could not create output directory for HTML file:\n%s" ),
195                         reason );
196                 aval = alertpanel_with_type( _( "Failed to Create Directory" ),
197                         msg, _( "Close" ), NULL, NULL, NULL, ALERT_ERROR );
198                 g_free( msg );
199                 return FALSE;
200         }
201
202         return TRUE;
203 }
204
205 /**
206  * Test whether we can move off format page.
207  * \return <i>TRUE</i> if OK to move off page.
208  */
209 static gboolean exp_html_move_format( void ) {
210         gboolean retVal = FALSE;
211         GtkWidget *menu, *menuItem;
212         gint id;
213
214         /* Set stylesheet */
215         menu = gtk_option_menu_get_menu( GTK_OPTION_MENU( exphtml_dlg.optmenuCSS ) );
216         menuItem = gtk_menu_get_active( GTK_MENU( menu ) );
217         id = GPOINTER_TO_INT( gtk_object_get_user_data(GTK_OBJECT(menuItem)) );
218         exporthtml_set_stylesheet( _exportCtl_, id );
219
220         /* Set name format */
221         menu = gtk_option_menu_get_menu( GTK_OPTION_MENU( exphtml_dlg.optmenuName ) );
222         menuItem = gtk_menu_get_active( GTK_MENU( menu ) );
223         id = GPOINTER_TO_INT( gtk_object_get_user_data(GTK_OBJECT(menuItem)) );
224         exporthtml_set_name_format( _exportCtl_, id );
225
226         exporthtml_set_banding( _exportCtl_,
227                 gtk_toggle_button_get_active(
228                         GTK_TOGGLE_BUTTON( exphtml_dlg.checkBanding ) ) );
229         exporthtml_set_link_email( _exportCtl_,
230                 gtk_toggle_button_get_active(
231                         GTK_TOGGLE_BUTTON( exphtml_dlg.checkLinkEMail ) ) );
232         exporthtml_set_attributes( _exportCtl_,
233                 gtk_toggle_button_get_active(
234                         GTK_TOGGLE_BUTTON( exphtml_dlg.checkAttributes ) ) );
235
236         /* Process export */
237         exporthtml_process( _exportCtl_, _addressCache_ );
238         if( _exportCtl_->retVal == MGU_SUCCESS ) {
239                 retVal = TRUE;
240         }
241         else {
242                 export_html_status_show( _( "Error creating HTML file" ) );
243         }
244         return retVal;
245 }
246
247 /**
248  * Display finish page.
249  */
250 static void exp_html_finish_show( void ) {
251         gtk_label_set_text( GTK_LABEL(exphtml_dlg.labelOutFile), _exportCtl_->path );
252         gtk_widget_set_sensitive( exphtml_dlg.btnNext, FALSE );
253         gtk_widget_grab_focus( exphtml_dlg.btnCancel );
254 }
255
256 /**
257  * Callback function to select previous page.
258  * \param widget Widget (button).
259  */
260 static void export_html_prev( GtkWidget *widget ) {
261         gint pageNum;
262
263         pageNum = gtk_notebook_current_page( GTK_NOTEBOOK(exphtml_dlg.notebook) );
264         if( pageNum == PAGE_FORMAT ) {
265                 /* Goto file page stuff */
266                 gtk_notebook_set_page(
267                         GTK_NOTEBOOK(exphtml_dlg.notebook), PAGE_FILE_INFO );
268                 gtk_widget_set_sensitive( exphtml_dlg.btnPrev, FALSE );
269         }
270         else if( pageNum == PAGE_FINISH ) {
271                 /* Goto format page */
272                 gtk_notebook_set_page(
273                         GTK_NOTEBOOK(exphtml_dlg.notebook), PAGE_FORMAT );
274                 gtk_widget_set_sensitive( exphtml_dlg.btnNext, TRUE );
275         }
276         export_html_message();
277 }
278
279 /**
280  * Callback function to select previous page.
281  * \param widget Widget (button).
282  */
283 static void export_html_next( GtkWidget *widget ) {
284         gint pageNum;
285
286         pageNum = gtk_notebook_current_page( GTK_NOTEBOOK(exphtml_dlg.notebook) );
287         if( pageNum == PAGE_FILE_INFO ) {
288                 /* Goto format page */
289                 if( exp_html_move_file() ) {
290                         gtk_notebook_set_page(
291                                 GTK_NOTEBOOK(exphtml_dlg.notebook), PAGE_FORMAT );
292                         gtk_widget_set_sensitive( exphtml_dlg.btnPrev, TRUE );
293                 }
294                 export_html_message();
295         }
296         else if( pageNum == PAGE_FORMAT ) {
297                 /* Goto finish page */
298                 if( exp_html_move_format() ) {
299                         gtk_notebook_set_page(
300                                 GTK_NOTEBOOK(exphtml_dlg.notebook), PAGE_FINISH );
301                         exp_html_finish_show();
302                         exporthtml_save_settings( _exportCtl_ );
303                         export_html_message();
304                 }
305         }
306 }
307
308 /**
309  * Open file with web browser.
310  * \param widget Widget (button).
311  * \param data   User data.
312  */
313 static void export_html_browse( GtkWidget *widget, gpointer data ) {
314         gchar *uri;
315
316         uri = g_strconcat( "file://", _exportCtl_->path, NULL );
317         open_uri( uri, prefs_common.uri_cmd );
318         g_free( uri );
319 }
320
321 /**
322  * Callback function to accept HTML file selection.
323  * \param widget Widget (button).
324  * \param data   User data.
325  */
326 static void exp_html_file_ok( GtkWidget *widget, gpointer data ) {
327         const gchar *sFile;
328         AddressFileSelection *afs;
329         GtkWidget *fileSel;
330
331         afs = ( AddressFileSelection * ) data;
332         fileSel = afs->fileSelector;
333         sFile = gtk_file_selection_get_filename( GTK_FILE_SELECTION(fileSel) );
334
335         afs->cancelled = FALSE;
336         gtk_entry_set_text( GTK_ENTRY(exphtml_dlg.entryHtml), sFile );
337         gtk_widget_hide( afs->fileSelector );
338         gtk_grab_remove( afs->fileSelector );
339         gtk_widget_grab_focus( exphtml_dlg.entryHtml );
340 }
341
342 /**
343  * Callback function to cancel HTML file selection dialog.
344  * \param widget Widget (button).
345  * \param data   User data.
346  */
347 static void exp_html_file_cancel( GtkWidget *widget, gpointer data ) {
348         AddressFileSelection *afs = ( AddressFileSelection * ) data;
349         afs->cancelled = TRUE;
350         gtk_widget_hide( afs->fileSelector );
351         gtk_grab_remove( afs->fileSelector );
352         gtk_widget_grab_focus( exphtml_dlg.entryHtml );
353 }
354
355 /**
356  * Create HTML file selection dialog.
357  * \param afs Address file selection data.
358  */
359 static void exp_html_file_select_create( AddressFileSelection *afs ) {
360         GtkWidget *fileSelector;
361
362         fileSelector = gtk_file_selection_new( _("Select HTML Output File") );
363         gtk_file_selection_hide_fileop_buttons( GTK_FILE_SELECTION(fileSelector) );
364         gtk_file_selection_complete( GTK_FILE_SELECTION(fileSelector), "*.html" );
365         g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(fileSelector)->ok_button),
366                          "clicked", 
367                          G_CALLBACK(exp_html_file_ok), (gpointer)afs);
368         g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(fileSelector)->cancel_button),
369                          "clicked", 
370                          G_CALLBACK(exp_html_file_cancel), (gpointer)afs);
371         afs->fileSelector = fileSelector;
372         afs->cancelled = TRUE;
373 }
374
375 /**
376  * Callback function to display HTML file selection dialog.
377  */
378 static void exp_html_file_select( void ) {
379         gchar *sFile;
380         if( ! _exp_html_file_selector_.fileSelector )
381                 exp_html_file_select_create( & _exp_html_file_selector_ );
382
383         sFile = gtk_editable_get_chars( GTK_EDITABLE(exphtml_dlg.entryHtml), 0, -1 );
384         gtk_file_selection_set_filename(
385                 GTK_FILE_SELECTION( _exp_html_file_selector_.fileSelector ),
386                 sFile );
387         g_free( sFile );
388         gtk_widget_show( _exp_html_file_selector_.fileSelector );
389         gtk_grab_add( _exp_html_file_selector_.fileSelector );
390 }
391
392 /**
393  * Format notebook file specification page.
394  * \param pageNum Page (tab) number.
395  * \param pageLbl Page (tab) label.
396  */
397 static void export_html_page_file( gint pageNum, gchar *pageLbl ) {
398         GtkWidget *vbox;
399         GtkWidget *table;
400         GtkWidget *label;
401         GtkWidget *labelBook;
402         GtkWidget *entryHtml;
403         GtkWidget *btnFile;
404         gint top;
405
406         vbox = gtk_vbox_new(FALSE, 8);
407         gtk_container_add( GTK_CONTAINER( exphtml_dlg.notebook ), vbox );
408         gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
409
410         label = gtk_label_new( pageLbl );
411         gtk_widget_show( label );
412         gtk_notebook_set_tab_label(
413                 GTK_NOTEBOOK( exphtml_dlg.notebook ),
414                 gtk_notebook_get_nth_page(
415                         GTK_NOTEBOOK( exphtml_dlg.notebook ), pageNum ),
416                 label );
417
418         table = gtk_table_new( 3, 3, FALSE );
419         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
420         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
421         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
422         gtk_table_set_col_spacings(GTK_TABLE(table), 8 );
423
424         /* First row */
425         top = 0;
426         label = gtk_label_new( _( "Address Book" ) );
427         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1),
428                 GTK_FILL, 0, 0, 0);
429         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
430
431         labelBook = gtk_label_new( "Address book name goes here" );
432         gtk_table_attach(GTK_TABLE(table), labelBook, 1, 2, top, (top + 1),
433                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
434         gtk_misc_set_alignment(GTK_MISC(labelBook), 0, 0.5);
435
436         /* Second row */
437         top++;
438         label = gtk_label_new( _( "HTML Output File" ) );
439         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1),
440                 GTK_FILL, 0, 0, 0);
441         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
442
443         entryHtml = gtk_entry_new();
444         gtk_table_attach(GTK_TABLE(table), entryHtml, 1, 2, top, (top + 1),
445                 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
446
447         btnFile = gtk_button_new_with_label( _(" ... "));
448         gtk_table_attach(GTK_TABLE(table), btnFile, 2, 3, top, (top + 1),
449                 GTK_FILL, 0, 3, 0);
450
451         gtk_widget_show_all(vbox);
452
453         /* Button handler */
454         g_signal_connect(G_OBJECT(btnFile), "clicked",
455                          G_CALLBACK(exp_html_file_select), NULL);
456
457         exphtml_dlg.labelBook = labelBook;
458         exphtml_dlg.entryHtml = entryHtml;
459 }
460
461 /**
462  * Format notebook format page.
463  * \param pageNum Page (tab) number.
464  * \param pageLbl Page (tab) label.
465  */
466 static void export_html_page_format( gint pageNum, gchar *pageLbl ) {
467         GtkWidget *vbox;
468         GtkWidget *table;
469         GtkWidget *label;
470         GtkWidget *optmenuCSS;
471         GtkWidget *optmenuName;
472         GtkWidget *menu;
473         GtkWidget *menuItem;
474         GtkWidget *checkBanding;
475         GtkWidget *checkLinkEMail;
476         GtkWidget *checkAttributes;
477         gint top;
478
479         vbox = gtk_vbox_new(FALSE, 8);
480         gtk_container_add( GTK_CONTAINER( exphtml_dlg.notebook ), vbox );
481         gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
482
483         label = gtk_label_new( pageLbl );
484         gtk_widget_show( label );
485         gtk_notebook_set_tab_label(
486                 GTK_NOTEBOOK( exphtml_dlg.notebook ),
487                 gtk_notebook_get_nth_page(
488                         GTK_NOTEBOOK( exphtml_dlg.notebook ), pageNum ),
489                 label );
490
491         table = gtk_table_new( 5, 3, FALSE );
492         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
493         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
494         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
495         gtk_table_set_col_spacings(GTK_TABLE(table), 8 );
496
497         /* First row */
498         top = 0;
499         label = gtk_label_new( _( "Stylesheet" ) );
500         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1),
501                 GTK_FILL, 0, 0, 0);
502         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
503
504         menu = gtk_menu_new();
505
506         menuItem = gtk_menu_item_new_with_label( _( "None" ) );
507         gtk_object_set_user_data( GTK_OBJECT( menuItem ),
508                         GINT_TO_POINTER( EXPORT_HTML_ID_NONE ) );
509         gtk_menu_append( GTK_MENU(menu), menuItem );
510         gtk_widget_show( menuItem );
511
512         menuItem = gtk_menu_item_new_with_label( _( "Default" ) );
513         gtk_object_set_user_data( GTK_OBJECT( menuItem ),
514                         GINT_TO_POINTER( EXPORT_HTML_ID_DEFAULT ) );
515         gtk_menu_append( GTK_MENU(menu), menuItem );
516         gtk_widget_show( menuItem );
517
518         menuItem = gtk_menu_item_new_with_label( _( "Full" ) );
519         gtk_object_set_user_data( GTK_OBJECT( menuItem ),
520                         GINT_TO_POINTER( EXPORT_HTML_ID_FULL ) );
521         gtk_menu_append( GTK_MENU(menu), menuItem );
522         gtk_widget_show( menuItem );
523
524         menuItem = gtk_menu_item_new_with_label( _( "Custom" ) );
525         gtk_object_set_user_data( GTK_OBJECT( menuItem ),
526                         GINT_TO_POINTER( EXPORT_HTML_ID_CUSTOM ) );
527         gtk_menu_append( GTK_MENU(menu), menuItem );
528         gtk_widget_show( menuItem );
529
530         menuItem = gtk_menu_item_new_with_label( _( "Custom-2" ) );
531         gtk_object_set_user_data( GTK_OBJECT( menuItem ),
532                         GINT_TO_POINTER( EXPORT_HTML_ID_CUSTOM2 ) );
533         gtk_menu_append( GTK_MENU(menu), menuItem );
534         gtk_widget_show( menuItem );
535
536         menuItem = gtk_menu_item_new_with_label( _( "Custom-3" ) );
537         gtk_object_set_user_data( GTK_OBJECT( menuItem ),
538                         GINT_TO_POINTER( EXPORT_HTML_ID_CUSTOM3 ) );
539         gtk_menu_append( GTK_MENU(menu), menuItem );
540         gtk_widget_show( menuItem );
541
542         menuItem = gtk_menu_item_new_with_label( _( "Custom-4" ) );
543         gtk_object_set_user_data( GTK_OBJECT( menuItem ),
544                         GINT_TO_POINTER( EXPORT_HTML_ID_CUSTOM4 ) );
545         gtk_menu_append( GTK_MENU(menu), menuItem );
546         gtk_widget_show( menuItem );
547
548         optmenuCSS = gtk_option_menu_new();
549         gtk_option_menu_set_menu( GTK_OPTION_MENU( optmenuCSS ), menu );
550
551         gtk_table_attach(GTK_TABLE(table), optmenuCSS, 1, 2, top, (top + 1),
552                 GTK_FILL, 0, 0, 0);
553
554         /* Second row */
555         top++;
556         label = gtk_label_new( _( "Full Name Format" ) );
557         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1),
558                 GTK_FILL, 0, 0, 0);
559         gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
560
561         menu = gtk_menu_new();
562
563         menuItem = gtk_menu_item_new_with_label( _( "First Name, Last Name" ) );
564         gtk_object_set_user_data( GTK_OBJECT( menuItem ),
565                         GINT_TO_POINTER( EXPORT_HTML_FIRST_LAST ) );
566         gtk_menu_append( GTK_MENU(menu), menuItem );
567         gtk_widget_show( menuItem );
568
569         menuItem = gtk_menu_item_new_with_label( _( "Last Name, First Name" ) );
570         gtk_object_set_user_data( GTK_OBJECT( menuItem ),
571                         GINT_TO_POINTER( EXPORT_HTML_LAST_FIRST ) );
572         gtk_menu_append( GTK_MENU(menu), menuItem );
573         gtk_widget_show( menuItem );
574
575         optmenuName = gtk_option_menu_new();
576         gtk_option_menu_set_menu( GTK_OPTION_MENU( optmenuName ), menu );
577
578         gtk_table_attach(GTK_TABLE(table), optmenuName, 1, 2, top, (top + 1),
579                 GTK_FILL, 0, 0, 0);
580
581         /* Third row */
582         top++;
583         checkBanding = gtk_check_button_new_with_label( _( "Color Banding" ) );
584         gtk_table_attach(GTK_TABLE(table), checkBanding, 1, 2, top, (top + 1),
585                 GTK_FILL, 0, 0, 0);
586
587         /* Fourth row */
588         top++;
589         checkLinkEMail = gtk_check_button_new_with_label( _( "Format E-Mail Links" ) );
590         gtk_table_attach(GTK_TABLE(table), checkLinkEMail, 1, 2, top, (top + 1),
591                 GTK_FILL, 0, 0, 0);
592
593         /* Fifth row */
594         top++;
595         checkAttributes = gtk_check_button_new_with_label( _( "Format User Attributes" ) );
596         gtk_table_attach(GTK_TABLE(table), checkAttributes, 1, 2, top, (top + 1),
597                 GTK_FILL, 0, 0, 0);
598
599         gtk_widget_show_all(vbox);
600
601         exphtml_dlg.optmenuCSS      = optmenuCSS;
602         exphtml_dlg.optmenuName     = optmenuName;
603         exphtml_dlg.checkBanding    = checkBanding;
604         exphtml_dlg.checkLinkEMail  = checkLinkEMail;
605         exphtml_dlg.checkAttributes = checkAttributes;
606 }
607
608 /**
609  * Format notebook finish page.
610  * \param pageNum Page (tab) number.
611  * \param pageLbl Page (tab) label.
612  */
613 static void export_html_page_finish( gint pageNum, gchar *pageLbl ) {
614         GtkWidget *vbox;
615         GtkWidget *table;
616         GtkWidget *label;
617         GtkWidget *labelBook;
618         GtkWidget *labelFile;
619         GtkWidget *btnBrowse;
620         gint top;
621
622         vbox = gtk_vbox_new(FALSE, 8);
623         gtk_container_add( GTK_CONTAINER( exphtml_dlg.notebook ), vbox );
624         gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
625
626         label = gtk_label_new( pageLbl );
627         gtk_widget_show( label );
628         gtk_notebook_set_tab_label(
629                 GTK_NOTEBOOK( exphtml_dlg.notebook ),
630                 gtk_notebook_get_nth_page( GTK_NOTEBOOK( exphtml_dlg.notebook ), pageNum ), label );
631
632         table = gtk_table_new( 3, 3, FALSE );
633         gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
634         gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
635         gtk_table_set_row_spacings(GTK_TABLE(table), 8);
636         gtk_table_set_col_spacings(GTK_TABLE(table), 8 );
637
638         /* First row */
639         top = 0;
640         label = gtk_label_new( _( "Address Book :" ) );
641         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
642         gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
643
644         labelBook = gtk_label_new("Full name of address book goes here");
645         gtk_table_attach(GTK_TABLE(table), labelBook, 1, 2, top, (top + 1), GTK_FILL, 0, 0, 0);
646         gtk_misc_set_alignment(GTK_MISC(labelBook), 0, 0.5);
647
648         /* Second row */
649         top++;
650         label = gtk_label_new( _( "File Name :" ) );
651         gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
652         gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
653
654         labelFile = gtk_label_new("File name goes here");
655         gtk_table_attach(GTK_TABLE(table), labelFile, 1, 2, top, (top + 1), GTK_FILL, 0, 0, 0);
656         gtk_misc_set_alignment(GTK_MISC(labelFile), 0, 0.5);
657
658         /* Third row */
659         top++;
660         btnBrowse = gtk_button_new_with_label( _( "Open with Web Browser" ) );
661         gtk_table_attach(GTK_TABLE(table), btnBrowse, 1, 2, top, (top + 1), GTK_FILL, 0, 0, 0);
662
663         gtk_widget_show_all(vbox);
664
665         /* Button handlers */
666         g_signal_connect(G_OBJECT(btnBrowse), "clicked",
667                          G_CALLBACK(export_html_browse), NULL);
668
669         exphtml_dlg.labelOutBook = labelBook;
670         exphtml_dlg.labelOutFile = labelFile;
671 }
672
673 /**
674  * Create main dialog decorations (excluding notebook pages).
675  */
676 static void export_html_dialog_create( void ) {
677         GtkWidget *window;
678         GtkWidget *vbox;
679         GtkWidget *vnbox;
680         GtkWidget *notebook;
681         GtkWidget *hbbox;
682         GtkWidget *btnPrev;
683         GtkWidget *btnNext;
684         GtkWidget *btnCancel;
685         GtkWidget *hsbox;
686         GtkWidget *statusbar;
687
688         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
689         gtk_widget_set_usize(window, EXPORTHTML_WIDTH, EXPORTHTML_HEIGHT );
690         gtk_container_set_border_width( GTK_CONTAINER(window), 0 );
691         gtk_window_set_title( GTK_WINDOW(window),
692                 _("Export Address Book to HTML File") );
693         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
694         gtk_window_set_modal(GTK_WINDOW(window), TRUE); 
695         g_signal_connect(G_OBJECT(window), "delete_event",
696                          G_CALLBACK(export_html_delete_event),
697                          NULL );
698         g_signal_connect(G_OBJECT(window), "key_press_event",
699                          G_CALLBACK(export_html_key_pressed),
700                          NULL );
701
702         vbox = gtk_vbox_new(FALSE, 4);
703         gtk_widget_show(vbox);
704         gtk_container_add(GTK_CONTAINER(window), vbox);
705
706         vnbox = gtk_vbox_new(FALSE, 4);
707         gtk_container_set_border_width(GTK_CONTAINER(vnbox), 4);
708         gtk_widget_show(vnbox);
709         gtk_box_pack_start(GTK_BOX(vbox), vnbox, TRUE, TRUE, 0);
710
711         /* Notebook */
712         notebook = gtk_notebook_new();
713         gtk_notebook_set_show_tabs( GTK_NOTEBOOK(notebook), FALSE ); /* Hide */
714         /* gtk_notebook_set_show_tabs( GTK_NOTEBOOK(notebook), TRUE ); */
715         gtk_widget_show(notebook);
716         gtk_box_pack_start(GTK_BOX(vnbox), notebook, TRUE, TRUE, 0);
717         gtk_container_set_border_width(GTK_CONTAINER(notebook), 6);
718
719         /* Status line */
720         hsbox = gtk_hbox_new(FALSE, 0);
721         gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
722         statusbar = gtk_statusbar_new();
723         gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
724
725         /* Button panel */
726         gtkut_button_set_create(&hbbox, &btnPrev, _( "Prev" ),
727                                 &btnNext, _( "Next" ),
728                                 &btnCancel, _( "Cancel" ) );
729         gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
730         gtk_container_set_border_width(GTK_CONTAINER(hbbox), 2);
731         gtk_widget_grab_default(btnNext);
732
733         /* Button handlers */
734         g_signal_connect(G_OBJECT(btnPrev), "clicked",
735                          G_CALLBACK(export_html_prev), NULL);
736         g_signal_connect(G_OBJECT(btnNext), "clicked",
737                          G_CALLBACK(export_html_next), NULL);
738         g_signal_connect(G_OBJECT(btnCancel), "clicked",
739                          G_CALLBACK(export_html_cancel), NULL);
740
741         gtk_widget_show_all(vbox);
742
743         exphtml_dlg.window     = window;
744         exphtml_dlg.notebook   = notebook;
745         exphtml_dlg.btnPrev    = btnPrev;
746         exphtml_dlg.btnNext    = btnNext;
747         exphtml_dlg.btnCancel  = btnCancel;
748         exphtml_dlg.statusbar  = statusbar;
749         exphtml_dlg.status_cid = gtk_statusbar_get_context_id(
750                         GTK_STATUSBAR(statusbar), "Export HTML Dialog" );
751 }
752
753 /**
754  * Create export HTML dialog.
755  */
756 static void export_html_create( void ) {
757         export_html_dialog_create();
758         export_html_page_file( PAGE_FILE_INFO, _( "File Info" ) );
759         export_html_page_format( PAGE_FORMAT, _( "Format" ) );
760         export_html_page_finish( PAGE_FINISH, _( "Finish" ) );
761         gtk_widget_show_all( exphtml_dlg.window );
762 }
763
764 /**
765  * Populate fields from control data.
766  * \param ctl Export control data.
767  */
768 static void export_html_fill_fields( ExportHtmlCtl *ctl ) {
769         gtk_entry_set_text( GTK_ENTRY(exphtml_dlg.entryHtml), "" );
770         if( ctl->path ) {
771                 gtk_entry_set_text( GTK_ENTRY(exphtml_dlg.entryHtml),
772                         ctl->path );
773         }
774
775         gtk_option_menu_set_history(
776                 GTK_OPTION_MENU( exphtml_dlg.optmenuCSS ), ctl->stylesheet );
777         gtk_option_menu_set_history(
778                 GTK_OPTION_MENU( exphtml_dlg.optmenuName ), ctl->nameFormat );
779         gtk_toggle_button_set_active(
780                 GTK_TOGGLE_BUTTON( exphtml_dlg.checkBanding ), ctl->banding );
781         gtk_toggle_button_set_active(
782                 GTK_TOGGLE_BUTTON( exphtml_dlg.checkLinkEMail ), ctl->linkEMail );
783         gtk_toggle_button_set_active(
784                 GTK_TOGGLE_BUTTON( exphtml_dlg.checkAttributes ), ctl->showAttribs );
785 }
786
787 /**
788  * Process export address dialog.
789  * \param cache Address book/data source cache.
790  */
791 void addressbook_exp_html( AddressCache *cache ) {
792         /* Set references to control data */
793         _addressCache_ = cache;
794
795         _exportCtl_ = exporthtml_create();
796         exporthtml_load_settings( _exportCtl_ );
797
798         /* Setup GUI */
799         if( ! exphtml_dlg.window )
800                 export_html_create();
801         exphtml_dlg.cancelled = FALSE;
802         gtk_widget_show(exphtml_dlg.window);
803         manage_window_set_transient(GTK_WINDOW(exphtml_dlg.window));
804
805         gtk_label_set_text( GTK_LABEL(exphtml_dlg.labelBook), cache->name );
806         gtk_label_set_text( GTK_LABEL(exphtml_dlg.labelOutBook), cache->name );
807         export_html_fill_fields( _exportCtl_ );
808
809         gtk_widget_grab_default(exphtml_dlg.btnNext);
810         gtk_notebook_set_page( GTK_NOTEBOOK(exphtml_dlg.notebook), PAGE_FILE_INFO );
811         gtk_widget_set_sensitive( exphtml_dlg.btnPrev, FALSE );
812         gtk_widget_set_sensitive( exphtml_dlg.btnNext, TRUE );
813
814         export_html_message();
815         gtk_widget_grab_focus(exphtml_dlg.entryHtml);
816
817         gtk_main();
818         gtk_widget_hide(exphtml_dlg.window);
819         exporthtml_free( _exportCtl_ );
820         _exportCtl_ = NULL;
821
822         _addressCache_ = NULL;
823 }
824
825 /*
826  * ============================================================================
827  * End of Source.
828  * ============================================================================
829  */
830