summaryrefslogtreecommitdiff
path: root/src/importcsv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/importcsv.c')
-rw-r--r--src/importcsv.c1008
1 files changed, 1008 insertions, 0 deletions
diff --git a/src/importcsv.c b/src/importcsv.c
new file mode 100644
index 0000000..0562495
--- /dev/null
+++ b/src/importcsv.c
@@ -0,0 +1,1008 @@
1/*
2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2017 Hiroyuki Yamamoto
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#ifdef HAVE_CONFIG_H
21# include "config.h"
22#endif
23
24#include "defs.h"
25
26#include <glib.h>
27#include <glib/gi18n.h>
28#include <gdk/gdkkeysyms.h>
29#include <gtk/gtkwindow.h>
30#include <gtk/gtksignal.h>
31#include <gtk/gtkvbox.h>
32#include <gtk/gtklabel.h>
33#include <gtk/gtkentry.h>
34#include <gtk/gtktable.h>
35#include <gtk/gtkbutton.h>
36#include <gtk/gtkradiobutton.h>
37#include <gtk/gtkhbbox.h>
38#include <gtk/gtkcheckbutton.h>
39#include <gtk/gtktogglebutton.h>
40#include <gtk/gtkstatusbar.h>
41#include <gtk/gtknotebook.h>
42#include <gtk/gtkstock.h>
43
44#include <stdio.h>
45
46#include "addrbook.h"
47#include "addressbook.h"
48#include "addressitem.h"
49#include "filesel.h"
50#include "gtkutils.h"
51#include "stock_pixmap.h"
52#include "prefs_common.h"
53#include "manage_window.h"
54#include "mgutils.h"
55#include "importcsv.h"
56#include "codeconv.h"
57#include "utils.h"
58
59#define IMPORTCSV_GUESS_NAME "CSV Import"
60
61#define PAGE_FILE_INFO 0
62#define PAGE_ATTRIBUTES 1
63#define PAGE_FINISH 2
64
65#define IMPORTCSV_WIDTH 480
66#define IMPORTCSV_HEIGHT 320
67
68#define FIELDS_N_COLS 3
69#define FIELDS_COL_WIDTH_SELECT 10
70#define FIELDS_COL_WIDTH_FIELD 140
71#define FIELDS_COL_WIDTH_ATTRIB 140
72
73typedef enum {
74 FIELD_COL_SELECT = 0,
75 FIELD_COL_FIELD = 1,
76 FIELD_COL_ATTRIB = 2
77} ImpCSV_FieldColPos;
78
79static struct _ImpCSVDlg {
80 GtkWidget *window;
81 GtkWidget *notebook;
82 GtkWidget *file_entry;
83 GtkWidget *name_entry;
84 GtkWidget *comma_radiobtn;
85 GtkWidget *tab_radiobtn;
86 GtkWidget *clist_field;
87 GtkWidget *check_select;
88 GtkWidget *labelBook;
89 GtkWidget *labelFile;
90 GtkWidget *labelRecords;
91 GtkWidget *btnPrev;
92 GtkWidget *btnNext;
93 GtkWidget *btnCancel;
94 GtkWidget *statusbar;
95 gint status_cid;
96 gint rowCount;
97 gchar *nameBook;
98 gchar *fileName;
99 gchar delimiter;
100 gboolean cancelled;
101} impcsv_dlg;
102
103typedef enum {
104 ATTR_FIRST_NAME,
105 ATTR_LAST_NAME,
106 ATTR_DISPLAY_NAME,
107 ATTR_NICK_NAME,
108 ATTR_EMAIL_ADDRESS,
109 ATTR_REMARKS,
110 ATTR_ALIAS,
111
112 N_CSV_ATTRIB
113} ImpCSVAttribIndex;
114
115static struct _ImpCSVAttrib {
116 gchar *name;
117 gchar *value;
118 gint col;
119 gboolean enabled;
120} imp_csv_attrib[] = {
121 {N_("First Name"), NULL, 0, TRUE},
122 {N_("Last Name"), NULL, 1, TRUE},
123 {N_("Display Name"), NULL, 2, TRUE},
124 {N_("Nick Name"), NULL, 3, TRUE},
125 {N_("E-Mail Address"), NULL, 4, TRUE},
126 {N_("Remarks"), NULL, 5, TRUE},
127 {N_("Alias"), NULL, 6, TRUE}
128};
129
130static AddressBookFile *_importedBook_;
131static AddressIndex *_imp_addressIndex_;
132static gint importCount = 0;
133static gint result;
134
135static GdkPixmap *markxpm;
136static GdkBitmap *markxpmmask;
137
138static void imp_csv_status_show( gchar *msg ) {
139 if( impcsv_dlg.statusbar != NULL ) {
140 gtk_statusbar_pop( GTK_STATUSBAR(impcsv_dlg.statusbar), impcsv_dlg.status_cid );
141 if( msg ) {
142 gtk_statusbar_push( GTK_STATUSBAR(impcsv_dlg.statusbar), impcsv_dlg.status_cid, msg );
143 }
144 }
145}
146
147static void imp_csv_message( void ) {
148 gchar *sMsg = NULL;
149 gint pageNum;
150
151 pageNum = gtk_notebook_get_current_page( GTK_NOTEBOOK(impcsv_dlg.notebook) );
152 if( pageNum == PAGE_FILE_INFO ) {
153 sMsg = _( "Please specify address book name and file to import." );
154 }
155 else if( pageNum == PAGE_ATTRIBUTES ) {
156 sMsg = _( "Select and reorder CSV field names to import." );
157 }
158 else if( pageNum == PAGE_FINISH ) {
159 sMsg = _( "File imported." );
160 }
161 imp_csv_status_show( sMsg );
162}
163
164static gchar *imp_csv_guess_file( AddressBookFile *abf ) {
165 gchar *newFile = NULL;
166 GList *fileList = NULL;
167 gint fileNum = 1;
168 fileList = addrbook_get_bookfile_list( abf );
169 if( fileList ) {
170 fileNum = 1 + abf->maxValue;
171 }
172 newFile = addrbook_gen_new_file_name( fileNum );
173 g_list_free( fileList );
174 fileList = NULL;
175 return newFile;
176}
177
178static gboolean imp_csv_load_fields( gchar *sFile ) {
179 GtkCList *clist = GTK_CLIST(impcsv_dlg.clist_field);
180 FILE *fp;
181 gchar buf[BUFFSIZE];
182 CharSet enc;
183
184 g_return_val_if_fail(sFile != NULL, FALSE);
185
186 impcsv_dlg.rowCount = 0;
187 gtk_clist_clear( clist );
188
189 enc = conv_check_file_encoding(sFile);
190
191 if ((fp = g_fopen(sFile, "rb")) == NULL) {
192 return FALSE;
193 }
194
195 if (fgets(buf, sizeof(buf), fp) != NULL) {
196 gchar *str;
197 gchar **strv;
198 gchar *text[ FIELDS_N_COLS ];
199 gint i;
200 guint fields_len;
201 guint data_len = 0;
202 guint len;
203 gint row;
204
205 strretchomp(buf);
206 if (enc == C_UTF_8)
207 str = g_strdup(buf);
208 else
209 str = conv_localetodisp(buf, NULL);
210 strv = strsplit_csv(str, impcsv_dlg.delimiter, 0);
211 fields_len = sizeof(imp_csv_attrib) / sizeof(imp_csv_attrib[0]);
212 while (strv[data_len])
213 ++data_len;
214 len = MAX(fields_len, data_len);
215
216 gtk_clist_freeze(clist);
217
218 for (i = 0; i < len; i++) {
219 text[ FIELD_COL_SELECT ] = "";
220 if (i < data_len)
221 text[ FIELD_COL_FIELD ] = strv[i];
222 else
223 text[ FIELD_COL_FIELD ] = "";
224 if (i < fields_len)
225 text[ FIELD_COL_ATTRIB ] =
226 gettext(imp_csv_attrib[i].name);
227 else
228 text[ FIELD_COL_ATTRIB ] = "";
229 row = gtk_clist_append(clist, text);
230 if (i < fields_len) {
231 imp_csv_attrib[i].value = NULL;
232 imp_csv_attrib[i].col = row;
233 gtk_clist_set_row_data
234 (clist, row, &imp_csv_attrib[i]);
235 if (imp_csv_attrib[i].enabled)
236 gtk_clist_set_pixmap(clist, row, FIELD_COL_SELECT, markxpm, markxpmmask);
237 }
238 }
239
240 gtk_clist_thaw(clist);
241 gtk_widget_queue_resize(GTK_WIDGET(clist));
242
243 g_strfreev(strv);
244 g_free(str);
245 }
246
247 fclose(fp);
248
249 return TRUE;
250}
251
252static void imp_csv_field_list_selected( GtkCList *clist, gint row, gint column, GdkEvent *event ) {
253 if (event && event->type == GDK_2BUTTON_PRESS)
254 return;
255
256 if (column == FIELD_COL_SELECT) {
257 struct _ImpCSVAttrib *attr;
258 attr = gtk_clist_get_row_data( clist, row );
259 if (attr) {
260 attr->enabled ^= TRUE;
261 if (attr->enabled)
262 gtk_clist_set_pixmap(clist, row, FIELD_COL_SELECT, markxpm, markxpmmask);
263 else
264 gtk_clist_set_text(clist, row, FIELD_COL_SELECT, "");
265 }
266 }
267}
268
269static void imp_csv_field_list_up( GtkWidget *button, gpointer data ) {
270 GtkCList *clist = GTK_CLIST(impcsv_dlg.clist_field);
271 gchar *text;
272 gint row;
273 struct _ImpCSVAttrib *src_attr;
274 struct _ImpCSVAttrib *dest_attr;
275 gchar *src_text;
276 gchar *dest_text;
277
278 if (!clist->selection) return;
279
280 row = GPOINTER_TO_INT( clist->selection->data );
281 if ( row > 0 && row < clist->rows ) {
282 gtk_clist_freeze( clist );
283
284 src_attr = gtk_clist_get_row_data( clist, row );
285 dest_attr = gtk_clist_get_row_data( clist, row - 1 );
286
287 gtk_clist_row_move( clist, row, row - 1 );
288
289 gtk_clist_get_text( clist, row, FIELD_COL_FIELD, &text );
290 src_text = g_strdup( text );
291 gtk_clist_get_text( clist, row - 1, FIELD_COL_FIELD, &text );
292 dest_text = g_strdup( text );
293 gtk_clist_set_text( clist, row - 1, FIELD_COL_FIELD, src_text );
294 gtk_clist_set_text( clist, row, FIELD_COL_FIELD, dest_text );
295 g_free( dest_text );
296 g_free( src_text );
297
298 if ( src_attr )
299 src_attr->col = row - 1;
300 if ( dest_attr )
301 dest_attr->col = row;
302
303 gtk_clist_thaw( clist );
304
305 if (gtk_clist_row_is_visible(clist, row - 1)
306 != GTK_VISIBILITY_FULL)
307 gtk_clist_moveto(clist, row - 1, 0, 0.5, 0);
308 }
309}
310
311static void imp_csv_field_list_down( GtkWidget *button, gpointer data ) {
312 GtkCList *clist = GTK_CLIST(impcsv_dlg.clist_field);
313 gchar *text;
314 gint row;
315 struct _ImpCSVAttrib *src_attr;
316 struct _ImpCSVAttrib *dest_attr;
317 gchar *src_text;
318 gchar *dest_text;
319
320 if (!clist->selection) return;
321
322 row = GPOINTER_TO_INT( clist->selection->data );
323 if ( row >= 0 && row < clist->rows - 1 ) {
324 gtk_clist_freeze( clist );
325
326 src_attr = gtk_clist_get_row_data( clist, row );
327 dest_attr = gtk_clist_get_row_data( clist, row + 1 );
328
329 gtk_clist_row_move( clist, row, row + 1 );
330
331 gtk_clist_get_text( clist, row, FIELD_COL_FIELD, &text );
332 src_text = g_strdup( text );
333 gtk_clist_get_text( clist, row + 1, FIELD_COL_FIELD, &text );
334 dest_text = g_strdup( text );
335 gtk_clist_set_text( clist, row + 1, FIELD_COL_FIELD, src_text );
336 gtk_clist_set_text( clist, row, FIELD_COL_FIELD, dest_text );
337 g_free( dest_text );
338 g_free( src_text );
339
340 if ( src_attr )
341 src_attr->col = row + 1;
342 if ( dest_attr )
343 dest_attr->col = row;
344
345 gtk_clist_thaw( clist );
346
347 if (gtk_clist_row_is_visible(clist, row + 1)
348 != GTK_VISIBILITY_FULL)
349 gtk_clist_moveto(clist, row + 1, 0, 0.5, 0);
350 }
351}
352
353static gint imp_csv_import_data( gchar *csvFile, AddressCache *cache ) {
354 FILE *fp;
355 gchar buf[BUFFSIZE];
356 gint i;
357 gchar **strv;
358 CharSet enc;
359 guint fields_len;
360 gchar *firstName = NULL;
361 gchar *lastName = NULL;
362 gchar *fullName = NULL;
363 gchar *nickName = NULL;
364 gchar *address = NULL;
365 gchar *remarks = NULL;
366 gchar *alias = NULL;
367 ItemPerson *person;
368 ItemEMail *email;
369 gint count = 0;
370
371 g_return_val_if_fail( csvFile != NULL, MGU_BAD_ARGS );
372
373 addrcache_clear( cache );
374 cache->dataRead = FALSE;
375
376 enc = conv_check_file_encoding(csvFile);
377
378 if ((fp = g_fopen(csvFile, "rb")) == NULL) {
379 return MGU_OPEN_FILE;
380 }
381
382 fields_len = sizeof(imp_csv_attrib) / sizeof(imp_csv_attrib[0]);
383
384 while (fgets(buf, sizeof(buf), fp) != NULL) {
385 gchar *str;
386 guint col, cols = 0;
387
388 strretchomp(buf);
389 if (enc == C_UTF_8)
390 str = g_strdup(buf);
391 else
392 str = conv_localetodisp(buf, NULL);
393 strv = strsplit_csv(str, impcsv_dlg.delimiter, 0);
394 while (strv[cols])
395 ++cols;
396
397 for (i = 0; i < fields_len; i++) {
398 if (!imp_csv_attrib[i].enabled)
399 continue;
400 col = imp_csv_attrib[i].col;
401 if (col >= cols || !*strv[col])
402 continue;
403 imp_csv_attrib[i].value = strv[col];
404 }
405
406 firstName = imp_csv_attrib[ATTR_FIRST_NAME].value;
407 lastName = imp_csv_attrib[ATTR_LAST_NAME].value;
408 fullName = imp_csv_attrib[ATTR_DISPLAY_NAME].value;
409 nickName = imp_csv_attrib[ATTR_NICK_NAME].value;
410 address = imp_csv_attrib[ATTR_EMAIL_ADDRESS].value;
411 remarks = imp_csv_attrib[ATTR_REMARKS].value;
412 alias = imp_csv_attrib[ATTR_ALIAS].value;
413
414 if (!fullName && !firstName && !lastName && address)
415 fullName = address;
416
417 person = addritem_create_item_person();
418 addritem_person_set_common_name( person, fullName );
419 addritem_person_set_first_name( person, firstName );
420 addritem_person_set_last_name( person, lastName );
421 addritem_person_set_nick_name( person, nickName );
422 addrcache_id_person( cache, person );
423 addrcache_add_person( cache, person );
424
425 if (address) {
426 email = addritem_create_item_email();
427 addritem_email_set_address( email, address );
428 addritem_email_set_remarks( email, remarks );
429 addritem_email_set_alias( email, alias );
430 addrcache_id_email( cache, email );
431 addrcache_person_add_email( cache, person, email );
432 }
433
434 for (i = 0; i < fields_len; i++)
435 imp_csv_attrib[i].value = NULL;
436 g_strfreev(strv);
437 g_free(str);
438
439 count++;
440 }
441
442 fclose(fp);
443
444 cache->modified = FALSE;
445 cache->dataRead = TRUE;
446 importCount = count;
447
448 return MGU_SUCCESS;
449}
450
451/*
452* Move off fields page.
453* return: TRUE if OK to move off page.
454*/
455static gboolean imp_csv_field_move() {
456 gboolean retVal = FALSE;
457 gchar *newFile;
458 AddressBookFile *abf = NULL;
459
460 if( _importedBook_ ) {
461 addrbook_free_book( _importedBook_ );
462 }
463
464 abf = addrbook_create_book();
465 addrbook_set_path( abf, _imp_addressIndex_->filePath );
466 addrbook_set_name( abf, impcsv_dlg.nameBook );
467 newFile = imp_csv_guess_file( abf );
468 addrbook_set_file( abf, newFile );
469 g_free( newFile );
470
471 /* Import data into file */
472 if( imp_csv_import_data( impcsv_dlg.fileName, abf->addressCache ) == MGU_SUCCESS ) {
473 addrbook_save_data( abf );
474 abf->dirtyFlag = TRUE;
475 _importedBook_ = abf;
476 retVal = TRUE;
477 }
478 else {
479 addrbook_free_book( abf );
480 }
481
482 return retVal;
483}
484
485/*
486* Move off fields page.
487* return: TRUE if OK to move off page.
488*/
489static gboolean imp_csv_file_move() {
490 gboolean retVal = FALSE;
491 gchar *sName;
492 gchar *sFile;
493 gchar *sMsg = NULL;
494 gboolean errFlag = FALSE;
495
496 sFile = gtk_editable_get_chars( GTK_EDITABLE(impcsv_dlg.file_entry), 0, -1 );
497 g_strchug( sFile ); g_strchomp( sFile );
498
499 sName = gtk_editable_get_chars( GTK_EDITABLE(impcsv_dlg.name_entry), 0, -1 );
500 g_strchug( sName ); g_strchomp( sName );
501
502 g_free( impcsv_dlg.nameBook );
503 g_free( impcsv_dlg.fileName );
504 impcsv_dlg.nameBook = sName;
505 impcsv_dlg.fileName = sFile;
506
507 gtk_entry_set_text( GTK_ENTRY(impcsv_dlg.file_entry), sFile );
508 gtk_entry_set_text( GTK_ENTRY(impcsv_dlg.name_entry), sName );
509
510 if (gtk_toggle_button_get_active
511 (GTK_TOGGLE_BUTTON(impcsv_dlg.comma_radiobtn))) {
512 impcsv_dlg.delimiter = ',';
513 } else {
514 impcsv_dlg.delimiter = '\t';
515 }
516
517 if( *sFile == '\0'|| strlen( sFile ) < 1 ) {
518 sMsg = _( "Please select a file." );
519 gtk_widget_grab_focus(impcsv_dlg.file_entry);
520 errFlag = TRUE;
521 }
522
523 if( *sName == '\0'|| strlen( sName ) < 1 ) {
524 if( ! errFlag ) sMsg = _( "Address book name must be supplied." );
525 gtk_widget_grab_focus(impcsv_dlg.name_entry);
526 errFlag = TRUE;
527 }
528
529 if( ! errFlag ) {
530 gchar *sFSFile;
531 sFSFile = conv_filename_from_utf8( sFile );
532 if ( ! imp_csv_load_fields( sFSFile ) ) {
533 sMsg = _( "Error reading CSV fields." );
534 } else {
535 retVal = TRUE;
536 }
537 g_free( sFSFile );
538 }
539 imp_csv_status_show( sMsg );
540
541 return retVal;
542}
543
544/*
545 * Display finish page.
546 */
547static void imp_csv_finish_show() {
548 gchar *sMsg;
549 gchar *name;
550
551 name = gtk_editable_get_chars( GTK_EDITABLE(impcsv_dlg.name_entry), 0, -1 );
552 gtk_label_set_text( GTK_LABEL(impcsv_dlg.labelBook), name );
553 g_free( name );
554 gtk_label_set_text( GTK_LABEL(impcsv_dlg.labelFile), impcsv_dlg.fileName );
555 gtk_label_set_text( GTK_LABEL(impcsv_dlg.labelRecords), itos( importCount ) );
556 gtk_widget_set_sensitive( impcsv_dlg.btnPrev, FALSE );
557 gtk_widget_set_sensitive( impcsv_dlg.btnNext, FALSE );
558 if( result == MGU_SUCCESS ) {
559 sMsg = _( "CSV file imported successfully." );
560 }
561 else {
562 sMsg = mgu_error2string( result );
563 }
564 imp_csv_status_show( sMsg );
565 gtk_button_set_label(GTK_BUTTON(impcsv_dlg.btnCancel), GTK_STOCK_CLOSE);
566 gtk_widget_grab_focus(impcsv_dlg.btnCancel);
567}
568
569static void imp_csv_prev( GtkWidget *widget ) {
570 gint pageNum;
571
572 pageNum = gtk_notebook_get_current_page( GTK_NOTEBOOK(impcsv_dlg.notebook) );
573 if( pageNum == PAGE_ATTRIBUTES ) {
574 /* Goto file page stuff */
575 gtk_notebook_set_current_page(
576 GTK_NOTEBOOK(impcsv_dlg.notebook), PAGE_FILE_INFO );
577 gtk_widget_set_sensitive( impcsv_dlg.btnPrev, FALSE );
578 }
579 imp_csv_message();
580}
581
582static void imp_csv_next( GtkWidget *widget ) {
583 gint pageNum;
584
585 pageNum = gtk_notebook_get_current_page( GTK_NOTEBOOK(impcsv_dlg.notebook) );
586 if( pageNum == PAGE_FILE_INFO ) {
587 /* Goto attributes stuff */
588 if( imp_csv_file_move() ) {
589 gtk_notebook_set_current_page(
590 GTK_NOTEBOOK(impcsv_dlg.notebook), PAGE_ATTRIBUTES );
591 imp_csv_message();
592 gtk_widget_set_sensitive( impcsv_dlg.btnPrev, TRUE );
593 }
594 else {
595 gtk_widget_set_sensitive( impcsv_dlg.btnPrev, FALSE );
596 }
597 }
598 else if( pageNum == PAGE_ATTRIBUTES ) {
599 /* Goto finish stuff */
600 if( imp_csv_field_move() ) {
601 gtk_notebook_set_current_page(
602 GTK_NOTEBOOK(impcsv_dlg.notebook), PAGE_FINISH );
603 imp_csv_finish_show();
604 }
605 }
606}
607
608static void imp_csv_cancel( GtkWidget *widget, gpointer data ) {
609 gint pageNum;
610
611 pageNum = gtk_notebook_get_current_page( GTK_NOTEBOOK(impcsv_dlg.notebook) );
612 if( pageNum != PAGE_FINISH ) {
613 impcsv_dlg.cancelled = TRUE;
614 }
615 gtk_main_quit();
616}
617
618static void imp_csv_file_select( void ) {
619 gchar *sSelFile;
620
621 sSelFile = filesel_select_file( _("Select CSV File"), NULL,
622 GTK_FILE_CHOOSER_ACTION_OPEN );
623 if (sSelFile) {
624 gchar *sUTF8File;
625 sUTF8File = conv_filename_to_utf8( sSelFile );
626 gtk_entry_set_text( GTK_ENTRY(impcsv_dlg.file_entry), sUTF8File );
627 g_free( sUTF8File );
628 g_free( sSelFile );
629 }
630}
631
632static gint imp_csv_delete_event( GtkWidget *widget, GdkEventAny *event, gpointer data ) {
633 imp_csv_cancel( widget, data );
634 return TRUE;
635}
636
637static gboolean imp_csv_key_pressed( GtkWidget *widget, GdkEventKey *event, gpointer data ) {
638 if (event && event->keyval == GDK_Escape) {
639 imp_csv_cancel( widget, data );
640 }
641 return FALSE;
642}
643
644static void imp_csv_page_file( gint pageNum, gchar *pageLbl ) {
645 GtkWidget *vbox;
646 GtkWidget *table;
647 GtkWidget *label;
648 GtkWidget *file_entry;
649 GtkWidget *name_entry;
650 GtkWidget *file_btn;
651 GtkWidget *hbox;
652 GtkWidget *comma_radiobtn;
653 GtkWidget *tab_radiobtn;
654 gint top;
655
656 vbox = gtk_vbox_new(FALSE, 4);
657 gtk_container_add( GTK_CONTAINER( impcsv_dlg.notebook ), vbox );
658 gtk_container_set_border_width( GTK_CONTAINER (vbox), 4 );
659
660 label = gtk_label_new( pageLbl );
661 gtk_widget_show( label );
662 gtk_notebook_set_tab_label(
663 GTK_NOTEBOOK( impcsv_dlg.notebook ),
664 gtk_notebook_get_nth_page(
665 GTK_NOTEBOOK( impcsv_dlg.notebook ), pageNum ),
666 label );
667
668 table = gtk_table_new(2, 3, FALSE);
669 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
670 gtk_container_set_border_width( GTK_CONTAINER(table), 6 );
671 gtk_table_set_row_spacings(GTK_TABLE(table), 8);
672 gtk_table_set_col_spacings(GTK_TABLE(table), 8);
673
674 /* First row */
675 top = 0;
676 label = gtk_label_new(_("Address Book"));
677 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1),
678 GTK_FILL, 0, 0, 0);
679 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
680
681 name_entry = gtk_entry_new();
682 gtk_table_attach(GTK_TABLE(table), name_entry, 1, 2, top, (top + 1),
683 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
684
685 /* Second row */
686 top = 1;
687 label = gtk_label_new(_("File Name"));
688 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1),
689 GTK_FILL, 0, 0, 0);
690 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
691
692 file_entry = gtk_entry_new();
693 gtk_table_attach(GTK_TABLE(table), file_entry, 1, 2, top, (top + 1),
694 GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
695
696 file_btn = gtk_button_new_with_label(_(" ... "));
697 gtk_table_attach(GTK_TABLE(table), file_btn, 2, 3, top, (top + 1),
698 GTK_FILL, 0, 3, 0);
699
700 hbox = gtk_hbox_new(FALSE, 8);
701 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
702 gtk_container_set_border_width( GTK_CONTAINER (hbox), 4 );
703
704 comma_radiobtn = gtk_radio_button_new_with_label
705 (NULL, _("Comma-separated"));
706 gtk_box_pack_start(GTK_BOX(hbox), comma_radiobtn, FALSE, FALSE, 0);
707
708 tab_radiobtn = gtk_radio_button_new_with_label_from_widget
709 (GTK_RADIO_BUTTON(comma_radiobtn), _("Tab-separated"));
710 gtk_box_pack_start(GTK_BOX(hbox), tab_radiobtn, FALSE, FALSE, 0);
711
712 gtk_widget_show_all(vbox);
713
714 /* Button handler */
715 g_signal_connect(G_OBJECT(file_btn), "clicked",
716 G_CALLBACK(imp_csv_file_select), NULL);
717
718 impcsv_dlg.file_entry = file_entry;
719 impcsv_dlg.name_entry = name_entry;
720 impcsv_dlg.comma_radiobtn = comma_radiobtn;
721 impcsv_dlg.tab_radiobtn = tab_radiobtn;
722}
723
724static void imp_csv_page_fields( gint pageNum, gchar *pageLbl ) {
725 GtkWidget *vbox;
726 GtkWidget *hbox;
727
728 GtkWidget *label;
729 GtkWidget *clist_swin;
730 GtkWidget *clist_field;
731
732 GtkWidget *btn_vbox;
733 GtkWidget *btn_vbox1;
734 GtkWidget *up_btn;
735 GtkWidget *down_btn;
736
737 gchar *titles[ FIELDS_N_COLS ];
738 gint i;
739
740 titles[ FIELD_COL_SELECT ] = _("S");
741 titles[ FIELD_COL_FIELD ] = _("CSV Field");
742 titles[ FIELD_COL_ATTRIB ] = _("Address Book Field");
743
744 vbox = gtk_vbox_new(FALSE, 4);
745 gtk_container_add( GTK_CONTAINER( impcsv_dlg.notebook ), vbox );
746 gtk_container_set_border_width( GTK_CONTAINER (vbox), 4 );
747
748 label = gtk_label_new( pageLbl );
749 gtk_widget_show( label );
750 gtk_notebook_set_tab_label(
751 GTK_NOTEBOOK( impcsv_dlg.notebook ),
752 gtk_notebook_get_nth_page(GTK_NOTEBOOK( impcsv_dlg.notebook ), pageNum ),
753 label );
754
755 hbox = gtk_hbox_new( FALSE, 0 );
756 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 4 );
757
758 label = gtk_label_new
759 ( _("Reorder address book fields with the Up and Down button.") );
760 gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 0 );
761 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
762 gtk_label_set_line_wrap( GTK_LABEL( label ), TRUE );
763
764 hbox = gtk_hbox_new( FALSE, 4 );
765 gtk_box_pack_start( GTK_BOX( vbox ), hbox, TRUE, TRUE, 0 );
766
767 clist_swin = gtk_scrolled_window_new( NULL, NULL );
768 gtk_box_pack_start( GTK_BOX(hbox), clist_swin, TRUE, TRUE, 0 );
769 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clist_swin),
770 GTK_POLICY_AUTOMATIC,
771 GTK_POLICY_ALWAYS);
772
773 clist_field = gtk_clist_new_with_titles( FIELDS_N_COLS, titles );
774 gtk_container_add( GTK_CONTAINER(clist_swin), clist_field );
775 gtk_clist_set_selection_mode( GTK_CLIST(clist_field), GTK_SELECTION_BROWSE );
776 gtk_clist_set_column_width(
777 GTK_CLIST(clist_field), FIELD_COL_SELECT, FIELDS_COL_WIDTH_SELECT );
778 gtk_clist_set_column_width(
779 GTK_CLIST(clist_field), FIELD_COL_FIELD, FIELDS_COL_WIDTH_FIELD );
780 gtk_clist_set_column_width(
781 GTK_CLIST(clist_field), FIELD_COL_ATTRIB, FIELDS_COL_WIDTH_ATTRIB );
782 gtkut_clist_set_redraw( GTK_CLIST(clist_field) );
783
784 for( i = 0; i < FIELDS_N_COLS; i++ )
785 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist_field)->column[i].button, GTK_CAN_FOCUS);
786
787 btn_vbox = gtk_vbox_new( FALSE, 0 );
788 gtk_box_pack_start( GTK_BOX( hbox ), btn_vbox, FALSE, FALSE, 0 );
789 gtk_container_set_border_width( GTK_CONTAINER (btn_vbox), 4 );
790
791 btn_vbox1 = gtk_vbox_new( FALSE, 8 );
792 gtk_box_pack_start( GTK_BOX( btn_vbox ), btn_vbox1, TRUE, FALSE, 0 );
793
794 up_btn = gtk_button_new_with_label( _("Up") );
795 gtk_box_pack_start( GTK_BOX( btn_vbox1 ), up_btn, FALSE, FALSE, 0 );
796 down_btn = gtk_button_new_with_label( _("Down") );
797 gtk_box_pack_start( GTK_BOX( btn_vbox1 ), down_btn, FALSE, FALSE, 0 );
798
799 gtk_widget_show_all(vbox);
800
801 g_signal_connect( G_OBJECT(clist_field), "select_row",
802 G_CALLBACK(imp_csv_field_list_selected), NULL );
803 g_signal_connect( G_OBJECT(up_btn), "clicked",
804 G_CALLBACK(imp_csv_field_list_up), NULL );
805 g_signal_connect( G_OBJECT(down_btn), "clicked",
806 G_CALLBACK(imp_csv_field_list_down), NULL );
807
808 impcsv_dlg.clist_field = clist_field;
809}
810
811static void imp_csv_page_finish( gint pageNum, gchar *pageLbl ) {
812 GtkWidget *vbox;
813 GtkWidget *table;
814 GtkWidget *label;
815 GtkWidget *labelBook;
816 GtkWidget *labelFile;
817 GtkWidget *labelRecs;
818 gint top;
819
820 vbox = gtk_vbox_new(FALSE, 8);
821 gtk_container_add( GTK_CONTAINER( impcsv_dlg.notebook ), vbox );
822 gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
823
824 label = gtk_label_new( pageLbl );
825 gtk_widget_show( label );
826 gtk_notebook_set_tab_label(
827 GTK_NOTEBOOK( impcsv_dlg.notebook ),
828 gtk_notebook_get_nth_page( GTK_NOTEBOOK( impcsv_dlg.notebook ), pageNum ), label );
829
830 table = gtk_table_new(3, 2, FALSE);
831 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
832 gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
833 gtk_table_set_row_spacings(GTK_TABLE(table), 8);
834 gtk_table_set_col_spacings(GTK_TABLE(table), 8 );
835
836 /* First row */
837 top = 0;
838 label = gtk_label_new(_("Address Book :"));
839 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
840 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
841
842 labelBook = gtk_label_new("");
843 gtk_table_attach(GTK_TABLE(table), labelBook, 1, 2, top, (top + 1), GTK_FILL, 0, 0, 0);
844 gtk_misc_set_alignment(GTK_MISC(labelBook), 0, 0.5);
845
846 /* Second row */
847 top++;
848 label = gtk_label_new(_("File Name :"));
849 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
850 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
851
852 labelFile = gtk_label_new("");
853 gtk_table_attach(GTK_TABLE(table), labelFile, 1, 2, top, (top + 1), GTK_FILL, 0, 0, 0);
854 gtk_misc_set_alignment(GTK_MISC(labelFile), 0, 0.5);
855 gtk_label_set_line_wrap(GTK_LABEL(labelFile), TRUE);
856
857 /* Third row */
858 top++;
859 label = gtk_label_new(_("Records :"));
860 gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
861 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
862
863 labelRecs = gtk_label_new("");
864 gtk_table_attach(GTK_TABLE(table), labelRecs, 1, 2, top, (top + 1), GTK_FILL, 0, 0, 0);
865 gtk_misc_set_alignment(GTK_MISC(labelRecs), 0, 0.5);
866
867 impcsv_dlg.labelBook = labelBook;
868 impcsv_dlg.labelFile = labelFile;
869 impcsv_dlg.labelRecords = labelRecs;
870}
871
872static void imp_csv_dialog_create() {
873 GtkWidget *window;
874 GtkWidget *vbox;
875 GtkWidget *vnbox;
876 GtkWidget *notebook;
877 GtkWidget *hbbox;
878 GtkWidget *btnPrev;
879 GtkWidget *btnNext;
880 GtkWidget *btnCancel;
881 GtkWidget *hsbox;
882 GtkWidget *statusbar;
883
884 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
885 gtk_widget_set_size_request(window, IMPORTCSV_WIDTH, IMPORTCSV_HEIGHT );
886 gtk_window_set_title( GTK_WINDOW(window), _("Import CSV file into Address Book") );
887 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
888 gtk_window_set_modal(GTK_WINDOW(window), TRUE);
889 g_signal_connect(G_OBJECT(window), "delete_event",
890 G_CALLBACK(imp_csv_delete_event), NULL);
891 g_signal_connect(G_OBJECT(window), "key_press_event",
892 G_CALLBACK(imp_csv_key_pressed), NULL);
893 MANAGE_WINDOW_SIGNALS_CONNECT(window);
894
895 vbox = gtk_vbox_new(FALSE, 4);
896 gtk_widget_show(vbox);
897 gtk_container_add(GTK_CONTAINER(window), vbox);
898
899 vnbox = gtk_vbox_new(FALSE, 4);
900 gtk_container_set_border_width(GTK_CONTAINER(vnbox), 4);
901 gtk_widget_show(vnbox);
902 gtk_box_pack_start(GTK_BOX(vbox), vnbox, TRUE, TRUE, 0);
903
904 /* Notebook */
905 notebook = gtk_notebook_new();
906 gtk_notebook_set_show_tabs( GTK_NOTEBOOK(notebook), FALSE );
907 gtk_widget_show(notebook);
908 gtk_box_pack_start(GTK_BOX(vnbox), notebook, TRUE, TRUE, 0);
909 gtk_container_set_border_width(GTK_CONTAINER(notebook), 6);
910
911 /* Status line */
912 hsbox = gtk_hbox_new(FALSE, 0);
913 gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, 0);
914 statusbar = gtk_statusbar_new();
915 gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, 0);
916
917 /* Button panel */
918 if (prefs_common.comply_gnome_hig) {
919 gtkut_stock_button_set_create(&hbbox, &btnNext, _("Next"),
920 &btnPrev, _("Prev"),
921 &btnCancel, GTK_STOCK_CANCEL);
922 } else {
923 gtkut_stock_button_set_create(&hbbox, &btnPrev, _("Prev"),
924 &btnNext, _("Next"),
925 &btnCancel, GTK_STOCK_CANCEL);
926 }
927 gtk_box_pack_end(GTK_BOX(vnbox), hbbox, FALSE, FALSE, 0);
928 gtk_widget_grab_default(btnNext);
929
930 /* Button handlers */
931 g_signal_connect(G_OBJECT(btnPrev), "clicked",
932 G_CALLBACK(imp_csv_prev), NULL);
933 g_signal_connect(G_OBJECT(btnNext), "clicked",
934 G_CALLBACK(imp_csv_next), NULL);
935 g_signal_connect(G_OBJECT(btnCancel), "clicked",
936 G_CALLBACK(imp_csv_cancel), NULL);
937
938 gtk_widget_show_all(vbox);
939
940 impcsv_dlg.window = window;
941 impcsv_dlg.notebook = notebook;
942 impcsv_dlg.btnPrev = btnPrev;
943 impcsv_dlg.btnNext = btnNext;
944 impcsv_dlg.btnCancel = btnCancel;
945 impcsv_dlg.statusbar = statusbar;
946 impcsv_dlg.status_cid = gtk_statusbar_get_context_id(
947 GTK_STATUSBAR(statusbar), "Import CSV Dialog" );
948
949}
950
951static void imp_csv_create() {
952 imp_csv_dialog_create();
953 imp_csv_page_file( PAGE_FILE_INFO, _( "File Info" ) );
954 imp_csv_page_fields( PAGE_ATTRIBUTES, _( "Fields" ) );
955 imp_csv_page_finish( PAGE_FINISH, _( "Finish" ) );
956 gtk_widget_show_all( impcsv_dlg.window );
957}
958
959AddressBookFile *addressbook_imp_csv( AddressIndex *addrIndex ) {
960 _importedBook_ = NULL;
961 _imp_addressIndex_ = addrIndex;
962
963 if( ! impcsv_dlg.window )
964 imp_csv_create();
965 impcsv_dlg.cancelled = FALSE;
966 manage_window_set_transient(GTK_WINDOW(impcsv_dlg.window));
967 gtk_widget_grab_default(impcsv_dlg.btnNext);
968
969 gtk_entry_set_text( GTK_ENTRY(impcsv_dlg.name_entry), IMPORTCSV_GUESS_NAME );
970 gtk_entry_set_text( GTK_ENTRY(impcsv_dlg.file_entry), "" );
971 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(impcsv_dlg.comma_radiobtn), TRUE );
972 gtk_clist_clear( GTK_CLIST(impcsv_dlg.clist_field) );
973 gtk_notebook_set_current_page( GTK_NOTEBOOK(impcsv_dlg.notebook), PAGE_FILE_INFO );
974 gtk_widget_set_sensitive( impcsv_dlg.btnPrev, FALSE );
975 gtk_widget_set_sensitive( impcsv_dlg.btnNext, TRUE );
976 gtk_button_set_label( GTK_BUTTON(impcsv_dlg.btnCancel), GTK_STOCK_CANCEL );
977 stock_pixmap_gdk( impcsv_dlg.window, STOCK_PIXMAP_MARK,
978 &markxpm, &markxpmmask );
979 imp_csv_message();
980 gtk_widget_grab_focus(impcsv_dlg.file_entry);
981
982 impcsv_dlg.rowCount = 0;
983 g_free( impcsv_dlg.nameBook );
984 g_free( impcsv_dlg.fileName );
985 impcsv_dlg.nameBook = NULL;
986 impcsv_dlg.fileName = NULL;
987 impcsv_dlg.delimiter = ',';
988 importCount = 0;
989
990 gtk_widget_show(impcsv_dlg.window);
991
992 gtk_main();
993 gtk_widget_hide(impcsv_dlg.window);
994 _imp_addressIndex_ = NULL;
995
996 g_free( impcsv_dlg.nameBook );
997 g_free( impcsv_dlg.fileName );
998 impcsv_dlg.nameBook = NULL;
999 impcsv_dlg.fileName = NULL;
1000
1001 if( impcsv_dlg.cancelled == TRUE ) return NULL;
1002 return _importedBook_;
1003}
1004
1005/*
1006* End of Source.
1007*/
1008