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