2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 2001-2022 the Claws Mail team and Match Grun
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Import LDIF address book data.
25 #include "claws-features.h"
31 #include <glib/gi18n.h>
32 #include <gdk/gdkkeysyms.h>
36 #include "addressbook.h"
37 #include "addressitem.h"
39 #include "stock_pixmap.h"
40 #include "prefs_common.h"
41 #include "manage_window.h"
47 #define IMPORTLDIF_GUESS_NAME "LDIF Import"
49 #define PAGE_FILE_INFO 0
50 #define PAGE_ATTRIBUTES 1
53 #define IMPORTLDIF_WIDTH 390
54 #define IMPORTLDIF_HEIGHT 300
56 #define FIELDS_COL_WIDTH_RESERVED 10
57 #define FIELDS_COL_WIDTH_SELECT 10
58 #define FIELDS_COL_WIDTH_FIELD 140
59 #define FIELDS_COL_WIDTH_ATTRIB 140
68 } ImpLdif_FieldColPos
;
71 * LDIF dialog definition.
73 static struct _ImpLdif_Dlg
{
78 GtkWidget
*view_fields
;
79 GtkWidget
*entryField
;
80 GtkWidget
*entryAttrib
;
81 GtkWidget
*checkSelect
;
85 GtkWidget
*labelRecords
;
88 GtkWidget
*btnProceed
;
98 static struct _AddressFileSelection _imp_ldif_file_selector_
;
99 static AddressBookFile
*_importedBook_
;
100 static AddressIndex
*_imp_addressIndex_
;
101 static LdifFile
*_ldifFile_
= NULL
;
103 static GdkPixbuf
*markxpm
;
106 * Structure of error message table.
108 typedef struct _ErrMsgTableEntry ErrMsgTableEntry
;
109 struct _ErrMsgTableEntry
{
114 static gchar
*_errMsgUnknown_
= N_( "Unknown" );
117 * Lookup table of error messages for general errors. Note that a NULL
118 * description signifies the end of the table.
120 static ErrMsgTableEntry _lutErrorsLDIF_
[] = {
121 { MGU_SUCCESS
, N_("Success") },
122 { MGU_BAD_ARGS
, N_("Bad arguments") },
123 { MGU_NO_FILE
, N_("File not specified") },
124 { MGU_OPEN_FILE
, N_("Error opening file") },
125 { MGU_ERROR_READ
, N_("Error reading file") },
126 { MGU_EOF
, N_("End of file encountered") },
127 { MGU_OO_MEMORY
, N_("Error allocating memory") },
128 { MGU_BAD_FORMAT
, N_("Bad file format") },
129 { MGU_ERROR_WRITE
, N_("Error writing to file") },
130 { MGU_OPEN_DIRECTORY
, N_("Error opening directory") },
131 { MGU_NO_PATH
, N_("No path specified") },
136 * Lookup message for specified error code.
137 * \param lut Lookup table.
138 * \param code Code to lookup.
139 * \return Description associated to code.
141 static gchar
*imp_ldif_err2string( ErrMsgTableEntry lut
[], gint code
) {
143 ErrMsgTableEntry entry
;
146 for( i
= 0; ; i
++ ) {
148 if( entry
.description
== NULL
) break;
149 if( entry
.code
== code
) {
150 desc
= entry
.description
;
155 desc
= _errMsgUnknown_
;
161 * Display message in status field.
162 * \param msg Message to display.
164 static void imp_ldif_status_show( gchar
*msg
) {
165 if( impldif_dlg
.statusbar
!= NULL
) {
166 gtk_statusbar_pop( GTK_STATUSBAR(impldif_dlg
.statusbar
),
167 impldif_dlg
.status_cid
);
170 GTK_STATUSBAR(impldif_dlg
.statusbar
),
171 impldif_dlg
.status_cid
, msg
);
177 * Select and display status message appropriate for the page being displayed.
179 static void imp_ldif_message( void ) {
183 pageNum
= gtk_notebook_get_current_page( GTK_NOTEBOOK(impldif_dlg
.notebook
) );
184 if( pageNum
== PAGE_FILE_INFO
) {
185 sMsg
= _( "Please specify address book name and file to import." );
187 else if( pageNum
== PAGE_ATTRIBUTES
) {
188 sMsg
= _( "Select and rename LDIF field names to import." );
190 else if( pageNum
== PAGE_FINISH
) {
191 sMsg
= _( "File imported." );
193 imp_ldif_status_show( sMsg
);
197 * Update the line (represented by the GtkTreeIter) with data
198 * from the Ldif_FieldRec.
200 static void _populate_iter(GtkListStore
*store
, GtkTreeIter
*iter
,
203 gtk_list_store_set(store
, iter
,
204 FIELD_COL_FIELD
, rec
->tagName
,
205 FIELD_COL_ATTRIB
, rec
->userName
,
208 gtk_list_store_set(store
, iter
,
209 FIELD_COL_SELECT
, rec
->selected
? markxpm
: NULL
, -1);
210 gtk_list_store_set(store
, iter
,
211 FIELD_COL_RESERVED
, rec
->reserved
? markxpm
: NULL
, -1);
215 * Load list with LDIF fields read from file.
216 * \param ldf LDIF control data.
218 static void imp_ldif_load_fields( LdifFile
*ldf
) {
219 GtkWidget
*view
= impldif_dlg
.view_fields
;
220 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(view
));
224 impldif_dlg
.rowCount
= 0;
226 if( ! ldf
->accessFlag
) return;
228 gtk_list_store_clear(GTK_LIST_STORE(model
));
230 list
= ldif_get_fieldlist( ldf
);
233 Ldif_FieldRec
*rec
= node
->data
;
235 gtk_list_store_append(GTK_LIST_STORE(model
), &iter
);
236 _populate_iter(GTK_LIST_STORE(model
), &iter
, rec
);
237 impldif_dlg
.rowCount
++;
238 node
= g_list_next( node
);
242 ldif_set_accessed( ldf
, FALSE
);
246 * Test whether we can move off fields page.
247 * \return <i>TRUE</i> if OK to move off page.
249 static gboolean
imp_ldif_field_move() {
250 gboolean retVal
= FALSE
;
252 AddressBookFile
*abf
= NULL
;
254 if( _importedBook_
) {
255 addrbook_free_book( _importedBook_
);
258 abf
= addrbook_create_book();
259 addrbook_set_path( abf
, _imp_addressIndex_
->filePath
);
260 addrbook_set_name( abf
, impldif_dlg
.nameBook
);
261 newFile
= addrbook_guess_next_file( abf
);
262 addrbook_set_file( abf
, newFile
);
265 /* Import data into file */
266 if( ldif_import_data( _ldifFile_
, abf
->addressCache
) == MGU_SUCCESS
) {
267 addrbook_save_data( abf
);
268 _importedBook_
= abf
;
272 addrbook_free_book( abf
);
278 static void _update_selected_row()
284 rec
= gtkut_tree_view_get_selected_pointer(
285 GTK_TREE_VIEW(impldif_dlg
.view_fields
), FIELD_COL_PTR
,
286 &model
, NULL
, &iter
);
290 ldif_field_set_name(rec
, gtk_entry_get_text(
291 GTK_ENTRY(impldif_dlg
.entryAttrib
)));
292 ldif_field_set_selected(rec
, gtk_toggle_button_get_active(
293 GTK_TOGGLE_BUTTON(impldif_dlg
.checkSelect
)));
295 _populate_iter(GTK_LIST_STORE(model
), &iter
, rec
);
298 static void imp_ldif_modify_pressed(GtkButton
*widget
, gpointer user_data
)
300 _update_selected_row();
303 static void imp_ldif_entryattrib_activate(GtkEntry
*entry
, gpointer user_data
)
305 _update_selected_row();
309 * Test whether we can move off file page.
310 * \return <i>TRUE</i> if OK to move off page.
312 static gboolean
imp_ldif_file_move() {
313 gboolean retVal
= FALSE
;
317 gboolean errFlag
= FALSE
;
319 sFile
= gtk_editable_get_chars( GTK_EDITABLE(impldif_dlg
.entryFile
), 0, -1 );
322 sName
= gtk_editable_get_chars( GTK_EDITABLE(impldif_dlg
.entryName
), 0, -1 );
325 g_free( impldif_dlg
.nameBook
);
326 g_free( impldif_dlg
.fileName
);
327 impldif_dlg
.nameBook
= sName
;
328 impldif_dlg
.fileName
= sFile
;
330 gtk_entry_set_text( GTK_ENTRY(impldif_dlg
.entryFile
), sFile
);
331 gtk_entry_set_text( GTK_ENTRY(impldif_dlg
.entryName
), sName
);
333 if( *sFile
== '\0' ) {
334 sMsg
= _( "Please select a file." );
335 gtk_widget_grab_focus(impldif_dlg
.entryFile
);
339 if( ! errFlag
&& *sName
== '\0' ) {
340 sMsg
= _( "Address book name must be supplied." );
341 gtk_widget_grab_focus(impldif_dlg
.entryName
);
346 /* Read attribute list */
347 ldif_set_file( _ldifFile_
, sFile
);
348 if( ldif_read_tags( _ldifFile_
) == MGU_SUCCESS
) {
350 /* ldif_print_file( _ldifFile_, stdout ); */
351 imp_ldif_load_fields( _ldifFile_
);
355 sMsg
= imp_ldif_err2string( _lutErrorsLDIF_
, _ldifFile_
->retVal
);
358 imp_ldif_status_show( sMsg
);
364 * Display finish page.
366 static void imp_ldif_finish_show() {
370 name
= gtk_editable_get_chars( GTK_EDITABLE(impldif_dlg
.entryName
), 0, -1 );
371 gtk_label_set_text( GTK_LABEL(impldif_dlg
.labelBook
), name
);
373 gtk_label_set_text( GTK_LABEL(impldif_dlg
.labelFile
), _ldifFile_
->path
);
374 gtk_label_set_text( GTK_LABEL(impldif_dlg
.labelRecords
), itos( _ldifFile_
->importCount
) );
375 gtk_widget_set_sensitive( impldif_dlg
.btnPrev
, FALSE
);
376 gtk_widget_hide( impldif_dlg
.btnNext
);
377 gtk_widget_show( impldif_dlg
.btnProceed
);
378 gtk_widget_set_sensitive( impldif_dlg
.btnProceed
, FALSE
);
379 if( _ldifFile_
->retVal
== MGU_SUCCESS
) {
380 sMsg
= _( "LDIF file imported successfully." );
383 sMsg
= imp_ldif_err2string( _lutErrorsLDIF_
, _ldifFile_
->retVal
);
385 imp_ldif_status_show( sMsg
);
386 gtk_widget_grab_focus(impldif_dlg
.btnCancel
);
390 * Callback function to select previous page.
391 * \param widget Widget (button).
393 static void imp_ldif_prev( GtkWidget
*widget
) {
396 pageNum
= gtk_notebook_get_current_page( GTK_NOTEBOOK(impldif_dlg
.notebook
) );
397 if( pageNum
== PAGE_ATTRIBUTES
) {
398 /* Goto file page stuff */
399 gtk_notebook_set_current_page(
400 GTK_NOTEBOOK(impldif_dlg
.notebook
), PAGE_FILE_INFO
);
401 gtk_widget_set_sensitive( impldif_dlg
.btnPrev
, FALSE
);
402 gtk_widget_hide( impldif_dlg
.btnProceed
);
403 gtk_widget_show( impldif_dlg
.btnNext
);
409 * Callback function to select next page.
410 * \param widget Widget (button).
412 static void imp_ldif_next( GtkWidget
*widget
) {
415 pageNum
= gtk_notebook_get_current_page( GTK_NOTEBOOK(impldif_dlg
.notebook
) );
416 if( pageNum
== PAGE_FILE_INFO
) {
417 /* Goto attributes stuff */
418 if( imp_ldif_file_move() ) {
419 gtk_notebook_set_current_page(
420 GTK_NOTEBOOK(impldif_dlg
.notebook
), PAGE_ATTRIBUTES
);
422 gtk_widget_set_sensitive( impldif_dlg
.btnPrev
, TRUE
);
423 gtk_widget_hide( impldif_dlg
.btnNext
);
424 gtk_widget_show( impldif_dlg
.btnProceed
);
425 gtk_widget_set_sensitive( impldif_dlg
.btnProceed
, TRUE
);
428 gtk_widget_set_sensitive( impldif_dlg
.btnPrev
, FALSE
);
429 _ldifFile_
->dirtyFlag
= TRUE
;
432 else if( pageNum
== PAGE_ATTRIBUTES
) {
433 /* Goto finish stuff */
434 if( imp_ldif_field_move() ) {
435 gtk_notebook_set_current_page(
436 GTK_NOTEBOOK(impldif_dlg
.notebook
), PAGE_FINISH
);
437 gtk_button_set_label(GTK_BUTTON(impldif_dlg
.btnCancel
),
439 gtk_button_set_image(GTK_BUTTON(impldif_dlg
.btnCancel
),
440 gtk_image_new_from_icon_name("window-close", GTK_ICON_SIZE_BUTTON
));
441 imp_ldif_finish_show();
447 * Callback function to cancel and close dialog.
448 * \param widget Widget (button).
449 * \param data User data.
451 static void imp_ldif_cancel( GtkWidget
*widget
, gpointer data
) {
454 pageNum
= gtk_notebook_get_current_page( GTK_NOTEBOOK(impldif_dlg
.notebook
) );
455 if( pageNum
!= PAGE_FINISH
) {
456 impldif_dlg
.cancelled
= TRUE
;
463 * Create LDIF file selection dialog.
464 * \param afs Address file selection data.
466 static void imp_ldif_file_select_create( AddressFileSelection
*afs
) {
467 gchar
*file
= filesel_select_file_open(_("Select LDIF File"), NULL
);
470 afs
->cancelled
= TRUE
;
472 afs
->cancelled
= FALSE
;
473 gtk_entry_set_text( GTK_ENTRY(impldif_dlg
.entryFile
), file
);
479 * Callback function to display LDIF file selection dialog.
481 static void imp_ldif_file_select( void ) {
482 imp_ldif_file_select_create( & _imp_ldif_file_selector_
);
486 * Callback function to handle dialog close event.
487 * \param widget Widget (dialog).
488 * \param event Event object.
489 * \param data User data.
491 static gint
imp_ldif_delete_event( GtkWidget
*widget
, GdkEventAny
*event
, gpointer data
) {
492 imp_ldif_cancel( widget
, data
);
497 * Callback function to respond to dialog key press events.
498 * \param widget Widget.
499 * \param event Event object.
500 * \param data User data.
502 static gboolean
imp_ldif_key_pressed( GtkWidget
*widget
, GdkEventKey
*event
, gpointer data
) {
503 if (event
&& event
->keyval
== GDK_KEY_Escape
) {
504 imp_ldif_cancel( widget
, data
);
510 * Format notebook "file" page.
511 * \param pageNum Page (tab) number.
512 * \param pageLbl Page (tab) label.
514 static void imp_ldif_page_file( gint pageNum
, gchar
*pageLbl
) {
518 GtkWidget
*entryFile
;
519 GtkWidget
*entryName
;
522 vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 8);
523 gtk_container_add( GTK_CONTAINER( impldif_dlg
.notebook
), vbox
);
524 gtk_container_set_border_width( GTK_CONTAINER (vbox
), BORDER_WIDTH
);
526 label
= gtk_label_new( pageLbl
);
527 gtk_widget_show( label
);
528 gtk_notebook_set_tab_label(
529 GTK_NOTEBOOK( impldif_dlg
.notebook
),
530 gtk_notebook_get_nth_page(
531 GTK_NOTEBOOK( impldif_dlg
.notebook
), pageNum
),
534 table
= gtk_grid_new();
535 gtk_box_pack_start(GTK_BOX(vbox
), table
, FALSE
, FALSE
, 0);
536 gtk_container_set_border_width( GTK_CONTAINER(table
), 8 );
537 gtk_grid_set_row_spacing(GTK_GRID(table
), 8);
538 gtk_grid_set_column_spacing(GTK_GRID(table
), 8);
541 label
= gtk_label_new(_("Address Book"));
542 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
543 gtk_grid_attach(GTK_GRID(table
), label
, 0, 0, 1, 1);
545 entryName
= gtk_entry_new();
546 gtk_grid_attach(GTK_GRID(table
), entryName
, 1, 0, 1, 1);
547 gtk_widget_set_hexpand(entryName
, TRUE
);
548 gtk_widget_set_halign(entryName
, GTK_ALIGN_FILL
);
550 CLAWS_SET_TIP(entryName
, _(
551 "Specify the name for the address book that will " \
552 "be created from the LDIF file data." ));
555 label
= gtk_label_new(_("File Name"));
556 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
557 gtk_grid_attach(GTK_GRID(table
), label
, 0, 1, 1, 1);
559 entryFile
= gtk_entry_new();
560 gtk_grid_attach(GTK_GRID(table
), entryFile
, 1, 1, 1, 1);
561 gtk_widget_set_hexpand(entryFile
, TRUE
);
562 gtk_widget_set_halign(entryFile
, GTK_ALIGN_FILL
);
564 CLAWS_SET_TIP(entryFile
,
565 _( "The full file specification of the LDIF file to import." ));
567 btnFile
= gtkut_get_browse_file_btn(_("B_rowse"));
568 gtk_grid_attach(GTK_GRID(table
), btnFile
, 2, 1, 1, 1);
570 CLAWS_SET_TIP(btnFile
,
571 _( "Select the LDIF file to import." ));
573 gtk_widget_show_all(vbox
);
576 g_signal_connect(G_OBJECT(btnFile
), "clicked",
577 G_CALLBACK(imp_ldif_file_select
), NULL
);
579 impldif_dlg
.entryFile
= entryFile
;
580 impldif_dlg
.entryName
= entryName
;
584 static void imp_ldif_field_list_cursor_changed(GtkTreeView
*view
,
589 gtk_entry_set_text( GTK_ENTRY(impldif_dlg
.entryAttrib
), "" );
591 rec
= gtkut_tree_view_get_selected_pointer(view
, FIELD_COL_PTR
,
595 /* Update widget contents */
597 GTK_LABEL(impldif_dlg
.entryField
), rec
->tagName
);
600 GTK_ENTRY(impldif_dlg
.entryAttrib
), rec
->userName
);
601 gtk_toggle_button_set_active(
602 GTK_TOGGLE_BUTTON(impldif_dlg
.checkSelect
),
605 /* Disable widgets for reserved fields */
606 gtk_widget_set_sensitive(
607 impldif_dlg
.entryAttrib
, ! rec
->reserved
);
608 gtk_widget_set_sensitive(
609 impldif_dlg
.checkSelect
, ! rec
->reserved
);
610 gtk_widget_set_sensitive(
611 impldif_dlg
.btnModify
, ! rec
->reserved
);
613 gtk_widget_grab_focus(impldif_dlg
.entryAttrib
);
616 static void imp_ldif_field_list_row_activated(GtkTreeView
*view
,
617 GtkTreePath
*path
, GtkTreeViewColumn
*col
,
620 GtkTreeModel
*model
= gtk_tree_view_get_model(view
);
625 ok
= gtk_tree_model_get_iter(model
, &iter
, path
);
630 gtk_tree_model_get(model
, &iter
, FIELD_COL_PTR
, &rec
, -1);
631 cm_return_if_fail(rec
!= NULL
);
633 /* Flip the "selected" state for the record, and update the
634 * "selected" column in the list view, as well as the
635 * "selected" checkbox. */
636 ldif_field_toggle(rec
);
637 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
,
638 FIELD_COL_SELECT
, rec
->selected
? markxpm
: NULL
, -1);
639 gtk_toggle_button_set_active(
640 GTK_TOGGLE_BUTTON(impldif_dlg
.checkSelect
),
645 * Format notebook fields page.
646 * \param pageNum Page (tab) number.
647 * \param pageLbl Page (tab) label.
649 static void imp_ldif_page_fields( gint pageNum
, gchar
*pageLbl
) {
655 GtkWidget
*scrollwin
;
656 GtkWidget
*view_fields
;
657 GtkWidget
*entryField
;
658 GtkWidget
*entryAttrib
;
659 GtkWidget
*checkSelect
;
660 GtkWidget
*btnModify
;
663 GtkCellRenderer
*rdr
;
664 GtkTreeViewColumn
*col
;
665 GtkTreeSelection
*sel
;
667 vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 8);
668 gtk_container_add( GTK_CONTAINER( impldif_dlg
.notebook
), vbox
);
669 gtk_container_set_border_width( GTK_CONTAINER (vbox
), 4 );
671 label
= gtk_label_new( pageLbl
);
672 gtk_widget_show( label
);
673 gtk_notebook_set_tab_label(
674 GTK_NOTEBOOK( impldif_dlg
.notebook
),
675 gtk_notebook_get_nth_page(GTK_NOTEBOOK( impldif_dlg
.notebook
), pageNum
),
678 /* Upper area - Field list */
679 vboxt
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 4 );
680 gtk_container_add( GTK_CONTAINER( vbox
), vboxt
);
682 scrollwin
= gtk_scrolled_window_new( NULL
, NULL
);
683 gtk_container_add( GTK_CONTAINER(vboxt
), scrollwin
);
684 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin
),
685 GTK_POLICY_AUTOMATIC
,
686 GTK_POLICY_AUTOMATIC
);
688 store
= gtk_list_store_new(FIELDS_N_COLS
,
689 GDK_TYPE_PIXBUF
, GDK_TYPE_PIXBUF
,
690 G_TYPE_STRING
, G_TYPE_STRING
,
694 view_fields
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
));
695 g_object_unref(store
);
696 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view_fields
), TRUE
);
697 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(view_fields
), FALSE
);
698 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(view_fields
));
699 gtk_tree_selection_set_mode(sel
, GTK_SELECTION_BROWSE
);
701 rdr
= gtk_cell_renderer_pixbuf_new();
702 col
= gtk_tree_view_column_new_with_attributes(_("R"), rdr
,
703 "pixbuf", FIELD_COL_RESERVED
, NULL
);
704 gtk_tree_view_column_set_min_width(col
, FIELD_COL_RESERVED
);
705 gtk_tree_view_append_column(GTK_TREE_VIEW(view_fields
), col
);
707 col
= gtk_tree_view_column_new_with_attributes(_("S"), rdr
,
708 "pixbuf", FIELD_COL_SELECT
, NULL
);
709 gtk_tree_view_column_set_min_width(col
, FIELD_COL_SELECT
);
710 gtk_tree_view_append_column(GTK_TREE_VIEW(view_fields
), col
);
712 rdr
= gtk_cell_renderer_text_new();
713 col
= gtk_tree_view_column_new_with_attributes(_("LDIF Field Name"), rdr
,
714 "markup", FIELD_COL_FIELD
, NULL
);
715 gtk_tree_view_column_set_min_width(col
, FIELD_COL_FIELD
);
716 gtk_tree_view_append_column(GTK_TREE_VIEW(view_fields
), col
);
718 col
= gtk_tree_view_column_new_with_attributes(_("Attribute Name"), rdr
,
719 "markup", FIELD_COL_ATTRIB
, NULL
);
720 gtk_tree_view_column_set_min_width(col
, FIELD_COL_ATTRIB
);
721 gtk_tree_view_append_column(GTK_TREE_VIEW(view_fields
), col
);
723 gtk_container_add( GTK_CONTAINER(scrollwin
), view_fields
);
725 /* Lower area - Edit area */
726 vboxb
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 4 );
727 gtk_box_pack_end(GTK_BOX(vbox
), vboxb
, FALSE
, FALSE
, 2);
729 /* Data entry area */
730 table
= gtk_grid_new();
731 gtk_box_pack_start(GTK_BOX(vboxb
), table
, FALSE
, FALSE
, 0);
732 gtk_grid_set_row_spacing(GTK_GRID(table
), 4);
733 gtk_grid_set_column_spacing(GTK_GRID(table
), 4);
736 label
= gtk_label_new(_("LDIF Field"));
737 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
738 gtk_grid_attach(GTK_GRID(table
), label
, 0, 0, 1, 1);
740 entryField
= gtk_label_new( "" );
741 gtk_label_set_xalign(GTK_LABEL(entryField
), 0.0);
742 gtk_grid_attach(GTK_GRID(table
), entryField
, 1, 0, 1, 1);
743 gtk_widget_set_hexpand(entryField
, TRUE
);
744 gtk_widget_set_halign(entryField
, GTK_ALIGN_FILL
);
747 label
= gtk_label_new(_("Attribute"));
749 * Use an event box to attach some help in the form of a tooltip.
750 * Tried this for the clist but it looked bad.
752 eventBox
= gtk_event_box_new();
753 gtk_container_add( GTK_CONTAINER(eventBox
), label
);
754 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
755 gtk_grid_attach(GTK_GRID(table
), eventBox
, 0, 1, 1, 1);
757 CLAWS_SET_TIP(eventBox
, _(
758 "Choose the LDIF field that will be renamed or selected " \
759 "for import in the list above. Reserved fields (marked " \
760 "with a tick in the \"R\" column), are automatically " \
761 "imported and cannot be renamed. A single click in the " \
762 "Select (\"S\") column will select the field for import " \
763 "with a tick. A single click anywhere in the row will " \
764 "select that field for rename in the input area below " \
765 "the list. A double click anywhere in the row will also " \
766 "select the field for import."));
768 entryAttrib
= gtk_entry_new();
769 gtk_grid_attach(GTK_GRID(table
), entryAttrib
, 1, 1, 1, 1);
770 gtk_widget_set_hexpand(entryAttrib
, TRUE
);
771 gtk_widget_set_halign(entryAttrib
, GTK_ALIGN_FILL
);
773 CLAWS_SET_TIP(entryAttrib
,
774 _( "The LDIF field can be renamed to the User Attribute name." ));
777 checkSelect
= gtk_check_button_new_with_label( _( "Select for Import" ) );
778 gtk_grid_attach(GTK_GRID(table
), checkSelect
, 1, 2, 1, 1);
780 CLAWS_SET_TIP(checkSelect
,
781 _( "Select the LDIF field for import into the address book." ));
783 btnModify
= gtk_button_new_with_label( _(" Modify "));
784 gtk_grid_attach(GTK_GRID(table
), btnModify
, 2, 2, 1, 1);
786 CLAWS_SET_TIP(btnModify
,
787 _( "This button will update the list above with the data supplied." ));
789 gtk_widget_show_all(vbox
);
792 g_signal_connect(G_OBJECT(view_fields
), "cursor-changed",
793 G_CALLBACK(imp_ldif_field_list_cursor_changed
), NULL
);
794 g_signal_connect(G_OBJECT(view_fields
), "row-activated",
795 G_CALLBACK(imp_ldif_field_list_row_activated
), NULL
);
796 g_signal_connect(G_OBJECT(btnModify
), "clicked",
797 G_CALLBACK(imp_ldif_modify_pressed
), NULL
);
798 g_signal_connect(G_OBJECT(entryAttrib
), "activate",
799 G_CALLBACK(imp_ldif_entryattrib_activate
), NULL
);
801 impldif_dlg
.view_fields
= view_fields
;
802 impldif_dlg
.entryField
= entryField
;
803 impldif_dlg
.entryAttrib
= entryAttrib
;
804 impldif_dlg
.checkSelect
= checkSelect
;
805 impldif_dlg
.btnModify
= btnModify
;
809 * Format notebook finish page.
810 * \param pageNum Page (tab) number.
811 * \param pageLbl Page (tab) label.
813 static void imp_ldif_page_finish( gint pageNum
, gchar
*pageLbl
) {
817 GtkWidget
*labelBook
;
818 GtkWidget
*labelFile
;
819 GtkWidget
*labelRecs
;
821 vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 8);
822 gtk_container_add( GTK_CONTAINER( impldif_dlg
.notebook
), vbox
);
823 gtk_container_set_border_width( GTK_CONTAINER (vbox
), BORDER_WIDTH
);
825 label
= gtk_label_new( pageLbl
);
826 gtk_widget_show( label
);
827 gtk_notebook_set_tab_label(
828 GTK_NOTEBOOK( impldif_dlg
.notebook
),
829 gtk_notebook_get_nth_page( GTK_NOTEBOOK( impldif_dlg
.notebook
), pageNum
),
832 table
= gtk_grid_new();
833 gtk_box_pack_start(GTK_BOX(vbox
), table
, FALSE
, FALSE
, 0);
834 gtk_container_set_border_width( GTK_CONTAINER(table
), 8 );
835 gtk_grid_set_row_spacing(GTK_GRID(table
), 8);
836 gtk_grid_set_column_spacing(GTK_GRID(table
), 8);
839 label
= gtk_label_new( _( "Address Book:" ) );
840 gtk_label_set_xalign(GTK_LABEL(label
), 1.0);
841 gtk_grid_attach(GTK_GRID(table
), label
, 0, 0, 1, 1);
843 labelBook
= gtk_label_new("");
844 gtk_label_set_xalign(GTK_LABEL(labelBook
), 0.0);
845 gtk_grid_attach(GTK_GRID(table
), labelBook
, 1, 0, 1, 1);
848 label
= gtk_label_new( _( "File Name:" ) );
849 gtk_label_set_xalign(GTK_LABEL(label
), 1.0);
850 gtk_grid_attach(GTK_GRID(table
), label
, 0, 1, 1, 1);
852 labelFile
= gtk_label_new("");
853 gtk_label_set_xalign(GTK_LABEL(labelFile
), 0.0);
854 gtk_grid_attach(GTK_GRID(table
), labelFile
, 1, 1, 1, 1);
857 label
= gtk_label_new( _("Records Imported:") );
858 gtk_label_set_xalign(GTK_LABEL(label
), 1.0);
859 gtk_grid_attach(GTK_GRID(table
), label
, 0, 2, 1, 1);
861 labelRecs
= gtk_label_new("");
862 gtk_label_set_xalign(GTK_LABEL(labelRecs
), 0.0);
863 gtk_grid_attach(GTK_GRID(table
), labelRecs
, 1, 2, 1, 1);
865 impldif_dlg
.labelBook
= labelBook
;
866 impldif_dlg
.labelFile
= labelFile
;
867 impldif_dlg
.labelRecords
= labelRecs
;
871 * Create main dialog decorations (excluding notebook pages).
873 static void imp_ldif_dialog_create() {
881 GtkWidget
*btnProceed
;
882 GtkWidget
*btnCancel
;
884 GtkWidget
*statusbar
;
886 window
= gtkut_window_new(GTK_WINDOW_TOPLEVEL
, "importldif");
887 gtk_widget_set_size_request(window
, IMPORTLDIF_WIDTH
, IMPORTLDIF_HEIGHT
);
888 gtk_container_set_border_width( GTK_CONTAINER(window
), 0 );
889 gtk_window_set_title( GTK_WINDOW(window
), _("Import LDIF file into Address Book") );
890 gtk_window_set_position(GTK_WINDOW(window
), GTK_WIN_POS_CENTER
);
891 gtk_window_set_type_hint(GTK_WINDOW(window
), GDK_WINDOW_TYPE_HINT_DIALOG
);
892 g_signal_connect(G_OBJECT(window
), "delete_event",
893 G_CALLBACK(imp_ldif_delete_event
),
895 g_signal_connect(G_OBJECT(window
), "key_press_event",
896 G_CALLBACK(imp_ldif_key_pressed
),
899 vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 4);
900 gtk_widget_show(vbox
);
901 gtk_container_add(GTK_CONTAINER(window
), vbox
);
903 vnbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 4);
904 gtk_container_set_border_width(GTK_CONTAINER(vnbox
), 4);
905 gtk_widget_show(vnbox
);
906 gtk_box_pack_start(GTK_BOX(vbox
), vnbox
, TRUE
, TRUE
, 0);
909 notebook
= gtk_notebook_new();
910 gtk_notebook_set_show_tabs( GTK_NOTEBOOK(notebook
), FALSE
);
911 gtk_widget_show(notebook
);
912 gtk_box_pack_start(GTK_BOX(vnbox
), notebook
, TRUE
, TRUE
, 0);
913 gtk_container_set_border_width(GTK_CONTAINER(notebook
), 6);
916 hsbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
917 gtk_box_pack_end(GTK_BOX(vbox
), hsbox
, FALSE
, FALSE
, BORDER_WIDTH
);
918 statusbar
= gtk_statusbar_new();
919 gtk_box_pack_start(GTK_BOX(hsbox
), statusbar
, TRUE
, TRUE
, BORDER_WIDTH
);
922 gtkut_stock_button_set_create(&hbbox
,
923 &btnPrev
, "go-previous", _("_Previous"),
924 &btnNext
, "go-next", _("_Next"),
925 &btnCancel
, NULL
, _("_Cancel"));
927 btnProceed
= gtk_button_new_with_mnemonic(_("Proceed"));
928 gtk_widget_set_can_default(btnProceed
, TRUE
);
929 gtk_box_pack_start(GTK_BOX(hbbox
), btnProceed
, TRUE
, TRUE
, 0);
930 gtk_widget_hide(btnProceed
);
932 gtk_box_pack_end(GTK_BOX(vbox
), hbbox
, FALSE
, FALSE
, 0);
933 gtk_container_set_border_width(GTK_CONTAINER(hbbox
), 2);
934 gtk_widget_grab_default(btnNext
);
936 /* Button handlers */
937 g_signal_connect(G_OBJECT(btnPrev
), "clicked",
938 G_CALLBACK(imp_ldif_prev
), NULL
);
939 g_signal_connect(G_OBJECT(btnNext
), "clicked",
940 G_CALLBACK(imp_ldif_next
), NULL
);
941 g_signal_connect(G_OBJECT(btnProceed
), "clicked",
942 G_CALLBACK(imp_ldif_next
), NULL
);
943 g_signal_connect(G_OBJECT(btnCancel
), "clicked",
944 G_CALLBACK(imp_ldif_cancel
), NULL
);
946 gtk_widget_show_all(vbox
);
948 impldif_dlg
.window
= window
;
949 impldif_dlg
.notebook
= notebook
;
950 impldif_dlg
.btnPrev
= btnPrev
;
951 impldif_dlg
.btnNext
= btnNext
;
952 impldif_dlg
.btnProceed
= btnProceed
;
953 impldif_dlg
.btnCancel
= btnCancel
;
954 impldif_dlg
.statusbar
= statusbar
;
955 impldif_dlg
.status_cid
= gtk_statusbar_get_context_id(
956 GTK_STATUSBAR(statusbar
), "Import LDIF Dialog" );
961 * Create import LDIF dialog.
963 static void imp_ldif_create() {
964 imp_ldif_dialog_create();
965 imp_ldif_page_file( PAGE_FILE_INFO
, _( "File Info" ) );
966 imp_ldif_page_fields( PAGE_ATTRIBUTES
, _( "Attributes" ) );
967 imp_ldif_page_finish( PAGE_FINISH
, _( "Finish" ) );
968 gtk_widget_show_all( impldif_dlg
.window
);
973 * \param addrIndex Address index.
974 * \return Address book file of imported data, or <i>NULL</i> if import
977 AddressBookFile
*addressbook_imp_ldif( AddressIndex
*addrIndex
) {
981 _importedBook_
= NULL
;
982 _imp_addressIndex_
= addrIndex
;
984 if( ! impldif_dlg
.window
)
987 view
= impldif_dlg
.view_fields
;
988 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(view
));
990 gtk_button_set_label(GTK_BUTTON(impldif_dlg
.btnCancel
),
992 gtk_widget_hide(impldif_dlg
.btnProceed
);
993 gtk_widget_show(impldif_dlg
.btnNext
);
995 impldif_dlg
.cancelled
= FALSE
;
996 gtk_widget_show(impldif_dlg
.window
);
997 manage_window_set_transient(GTK_WINDOW(impldif_dlg
.window
));
998 gtk_widget_grab_default(impldif_dlg
.btnNext
);
999 gtk_window_set_modal(GTK_WINDOW(impldif_dlg
.window
), TRUE
);
1001 gtk_entry_set_text( GTK_ENTRY(impldif_dlg
.entryName
), IMPORTLDIF_GUESS_NAME
);
1002 gtk_entry_set_text( GTK_ENTRY(impldif_dlg
.entryFile
), "" );
1003 gtk_label_set_text( GTK_LABEL(impldif_dlg
.entryField
), "" );
1004 gtk_entry_set_text( GTK_ENTRY(impldif_dlg
.entryAttrib
), "" );
1005 gtk_list_store_clear( GTK_LIST_STORE(model
) );
1006 gtk_notebook_set_current_page( GTK_NOTEBOOK(impldif_dlg
.notebook
), PAGE_FILE_INFO
);
1007 gtk_widget_set_sensitive( impldif_dlg
.btnPrev
, FALSE
);
1008 gtk_widget_set_sensitive( impldif_dlg
.btnNext
, TRUE
);
1009 stock_pixbuf_gdk(STOCK_PIXMAP_MARK
, &markxpm
);
1011 gtk_widget_grab_focus(impldif_dlg
.entryFile
);
1013 impldif_dlg
.rowCount
= 0;
1014 g_free( impldif_dlg
.nameBook
);
1015 g_free( impldif_dlg
.fileName
);
1016 impldif_dlg
.nameBook
= NULL
;
1017 impldif_dlg
.fileName
= NULL
;
1019 _ldifFile_
= ldif_create();
1021 gtk_widget_hide(impldif_dlg
.window
);
1022 gtk_window_set_modal(GTK_WINDOW(impldif_dlg
.window
), FALSE
);
1023 ldif_free( _ldifFile_
);
1025 _imp_addressIndex_
= NULL
;
1027 g_free( impldif_dlg
.nameBook
);
1028 g_free( impldif_dlg
.fileName
);
1029 impldif_dlg
.nameBook
= NULL
;
1030 impldif_dlg
.fileName
= NULL
;
1032 if( impldif_dlg
.cancelled
== TRUE
) return NULL
;
1033 return _importedBook_
;
1037 * ============================================================================
1039 * ============================================================================