import homebank-5.1.7
[chaz/homebank] / src / ui-assist-import.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2018 Maxime DOYEN
3 *
4 * This file is part of HomeBank.
5 *
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "homebank.h"
21
22 #include "hb-import.h"
23 #include "ui-assist-import.h"
24
25 #include "list_account.h"
26 #include "list_operation.h"
27
28 #include "ui-account.h"
29 #include "dsp_mainwindow.h"
30
31
32
33 /****************************************************************************/
34 /* Debug macros */
35 /****************************************************************************/
36 #define MYDEBUG 0
37
38 #if MYDEBUG
39 #define DB(x) (x);
40 #else
41 #define DB(x);
42 #endif
43
44 #define FORCE_SIZE 1
45 #define HEAD_IMAGE 0
46 #define SIDE_IMAGE 0
47
48
49 /* our global datas */
50 extern struct HomeBank *GLOBALS;
51 extern struct Preferences *PREFS;
52
53
54 static gchar *page_titles[] =
55 {
56 N_("Welcome"),
57 N_("Select file"),
58 N_("Import"),
59 N_("Properties"),
60 N_("Account"),
61 N_("Transaction"),
62 N_("Confirmation")
63 };
64
65
66 extern gchar *CYA_IMPORT_DATEORDER[];
67
68
69 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
70 /* account affect listview */
71 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
72
73
74 static guint32
75 ui_acc_affect_listview_get_selected_key(GtkTreeView *treeview)
76 {
77 GtkTreeSelection *selection;
78 GtkTreeModel *model;
79 GtkTreeIter iter;
80
81 selection = gtk_tree_view_get_selection(treeview);
82 if (gtk_tree_selection_get_selected(selection, &model, &iter))
83 {
84 Account *item;
85
86 gtk_tree_model_get(model, &iter, 0, &item, -1);
87
88 if( item!= NULL )
89 return item->key;
90 }
91 return 0;
92 }
93
94
95 static void
96 ui_acc_affect_listview_srcname_cell_data_function (GtkTreeViewColumn *col,
97 GtkCellRenderer *renderer,
98 GtkTreeModel *model,
99 GtkTreeIter *iter,
100 gpointer user_data)
101 {
102 Account *entry;
103 gchar *name;
104 gchar *string;
105
106 gtk_tree_model_get(model, iter, 0, &entry, -1);
107
108 name = entry->imp_name;
109
110 #if MYDEBUG
111 string = g_markup_printf_escaped("<i>[%d] %s</i>", entry->key, name );
112 #else
113 string = g_markup_printf_escaped("<i>%s</i>", name);
114 #endif
115 g_object_set(renderer, "markup", string, NULL);
116 g_free(string);
117 }
118
119 static void
120 ui_acc_affect_listview_new_cell_data_function (GtkTreeViewColumn *col,
121 GtkCellRenderer *renderer,
122 GtkTreeModel *model,
123 GtkTreeIter *iter,
124 gpointer user_data)
125 {
126 Account *entry;
127 gchar *name;
128
129 gtk_tree_model_get(model, iter, 0, &entry, -1);
130 name = NULL;
131 if(entry->imp_key == 0)
132 name = _("create new");
133 else
134 name = _("use existing");
135
136 g_object_set(renderer, "markup", name, NULL);
137
138 }
139
140 static void
141 ui_acc_affect_listview_dstname_cell_data_function (GtkTreeViewColumn *col,
142 GtkCellRenderer *renderer,
143 GtkTreeModel *model,
144 GtkTreeIter *iter,
145 gpointer user_data)
146 {
147 Account *entry, *dst_entry;
148 gchar *name;
149 #if MYDEBUG
150 gchar *string;
151 #endif
152
153 gtk_tree_model_get(model, iter, 0, &entry, -1);
154 name = NULL;
155 if(entry->imp_key == 0)
156 name = entry->name;
157 else
158 {
159 dst_entry = da_acc_get(entry->imp_key);
160 if( dst_entry != NULL )
161 name = dst_entry->name;
162 }
163
164 #if MYDEBUG
165 string = g_strdup_printf ("[%d] %s", entry->imp_key, name );
166 g_object_set(renderer, "text", string, NULL);
167 g_free(string);
168 #else
169 g_object_set(renderer, "text", name, NULL);
170 #endif
171
172 }
173
174 static void
175 ui_acc_affect_listview_add(GtkTreeView *treeview, Account *item)
176 {
177 if( item->name != NULL )
178 {
179 GtkTreeModel *model;
180 GtkTreeIter iter;
181
182 model = gtk_tree_view_get_model(treeview);
183
184 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
185 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
186 0, item,
187 -1);
188
189 //gtk_tree_selection_select_iter (gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), &iter);
190
191 }
192 }
193
194
195 static GtkWidget *
196 ui_acc_affect_listview_new(void)
197 {
198 GtkListStore *store;
199 GtkWidget *treeview;
200 GtkCellRenderer *renderer;
201 GtkTreeViewColumn *column;
202
203 // create list store
204 store = gtk_list_store_new(1,
205 G_TYPE_POINTER
206 );
207
208 // treeview
209 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
210 g_object_unref(store);
211
212 // column: import account
213 renderer = gtk_cell_renderer_text_new ();
214 column = gtk_tree_view_column_new();
215 gtk_tree_view_column_pack_start(column, renderer, TRUE);
216 gtk_tree_view_column_set_title(column, _("Name in the file"));
217 gtk_tree_view_column_set_cell_data_func(column, renderer, ui_acc_affect_listview_srcname_cell_data_function, NULL, NULL);
218 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
219
220 // column: target account
221 renderer = gtk_cell_renderer_text_new ();
222 column = gtk_tree_view_column_new();
223 gtk_tree_view_column_pack_start(column, renderer, TRUE);
224 gtk_tree_view_column_set_title(column, _("Action"));
225 gtk_tree_view_column_set_cell_data_func(column, renderer, ui_acc_affect_listview_new_cell_data_function, NULL, NULL);
226 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
227
228 // column: target account
229 renderer = gtk_cell_renderer_text_new ();
230 column = gtk_tree_view_column_new();
231 gtk_tree_view_column_pack_start(column, renderer, TRUE);
232 gtk_tree_view_column_set_title(column, _("Name in HomeBank"));
233 gtk_tree_view_column_set_cell_data_func(column, renderer, ui_acc_affect_listview_dstname_cell_data_function, NULL, NULL);
234 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
235
236
237
238 // treeviewattribute
239 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), TRUE);
240
241 //gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), ui_acc_listview_compare_func, NULL, NULL);
242 //gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
243
244 return treeview;
245 }
246
247
248
249 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
250
251 //old stuf for transition waiting import rewrite
252 static void da_obsolete_transaction_destroy(GList *list)
253 {
254 GList *tmplist = g_list_first(list);
255
256 while (tmplist != NULL)
257 {
258 Transaction *item = tmplist->data;
259 da_transaction_free(item);
260 tmplist = g_list_next(tmplist);
261 }
262 g_list_free(list);
263 }
264
265 static GQueue *da_obsolete_transaction_get_partial(guint32 minjulian)
266 {
267 GList *lst_acc, *lnk_acc;
268 GList *lnk_txn;
269 GQueue *txn_queue;
270
271 txn_queue = g_queue_new ();
272
273 lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
274 lnk_acc = g_list_first(lst_acc);
275 while (lnk_acc != NULL)
276 {
277 Account *acc = lnk_acc->data;
278
279 lnk_txn = g_queue_peek_tail_link(acc->txn_queue);
280 while (lnk_txn != NULL)
281 {
282 Transaction *txn = lnk_txn->data;
283
284 if( txn->date < minjulian ) //no need to go below mindate
285 break;
286
287 g_queue_push_head (txn_queue, txn);
288
289 lnk_txn = g_list_previous(lnk_txn);
290 }
291
292 lnk_acc = g_list_next(lnk_acc);
293 }
294 g_list_free(lst_acc);
295
296 return txn_queue;
297 }
298
299
300
301
302 /* count account to be imported */
303 static void _import_context_count(struct import_data *data)
304 {
305 ImportContext *ictx = &data->ictx;
306 GList *lacc, *list;
307
308 DB( g_print("\n[import] context count\n") );
309
310 ictx->nb_src_acc = ictx->nb_new_acc = 0;
311
312 ictx->cnt_new_ope = 0;
313
314 /* count account */
315 lacc = list = g_hash_table_get_values(GLOBALS->h_acc);
316 while (list != NULL)
317 {
318 Account *item = list->data;
319
320 if( item->imported == TRUE )
321 {
322 ictx->nb_src_acc++;
323 if( item->imp_key == 0 )
324 ictx->nb_new_acc++;
325 }
326 list = g_list_next(list);
327 }
328 g_list_free(lacc);
329
330 /* count transaction */
331 ictx->cnt_new_ope = g_list_length(ictx->trans_list);
332
333 }
334
335
336 static void _import_context_clear(ImportContext *ictx)
337 {
338 DB( g_print("\n[import] context clear\n") );
339
340 if(ictx->trans_list)
341 da_obsolete_transaction_destroy(ictx->trans_list);
342 ictx->trans_list = NULL;
343 ictx->next_acc_key = da_acc_length();
344 ictx->datefmt = PREFS->dtex_datefmt;
345 ictx->encoding = NULL;
346
347 ictx->cnt_err_date = 0;
348 ictx->cnt_new_pay = 0;
349 ictx->cnt_new_cat = 0;
350 }
351
352
353 #if MYDEBUG
354 static void _import_context_debug(ImportContext *ictx)
355 {
356 DB( g_print("\n[import] context debug\n") );
357
358 DB( g_print(
359 " -> txnlist=%p, maxacckey=%d\n"
360 " -> nb-acc=%d, nb-newacc=%d\n"
361 " -> ntxn=%d, npay=%d, ncat=%d\n"
362 " -> datefmt=%d, encoding='%s', errdate=%d, ndup=%d\n",
363 ictx->trans_list, ictx->next_acc_key,
364 ictx->nb_src_acc, ictx->nb_new_acc,
365 ictx->cnt_new_ope,
366 ictx->cnt_new_pay,
367 ictx->cnt_new_cat,
368 ictx->datefmt,
369 ictx->encoding,
370 ictx->cnt_err_date,
371 ictx->nb_duplicate
372 )
373 );
374 }
375 #endif
376
377
378
379
380
381
382
383 static GList *homebank_qif_import(gchar *filename, ImportContext *ictx)
384 {
385 GList *list = NULL;
386
387 DB( g_print("\n[import] homebank QIF\n") );
388
389 //todo: context ?
390 list = account_import_qif(filename, ictx);
391
392 return list;
393 }
394
395
396
397
398 static void import_clearall(struct import_data *data)
399 {
400 GList *lxxx, *list;
401 GtkTreeModel *model;
402
403 DB( g_print("\n[import] clear all\n") );
404
405 // clear account & transactions
406 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_acc));
407 gtk_list_store_clear (GTK_LIST_STORE(model));
408 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->imported_ope));
409 gtk_list_store_clear (GTK_LIST_STORE(model));
410 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->duplicat_ope));
411 gtk_list_store_clear (GTK_LIST_STORE(model));
412
413
414 // 1: delete imported accounts
415 lxxx = list = g_hash_table_get_values(GLOBALS->h_acc);
416 while (list != NULL)
417 {
418 Account *item = list->data;
419
420 if( item->imported == TRUE )
421 {
422 DB( g_print(" -> delete acc %p '%s'\n", item, item->name) );
423 da_acc_remove(item->key);
424 }
425 list = g_list_next(list);
426 }
427 g_list_free(lxxx);
428
429 // 2: delete imported payees
430 lxxx = list = g_hash_table_get_values(GLOBALS->h_pay);
431 while (list != NULL)
432 {
433 Payee *item = list->data;
434
435 if( item->imported == TRUE )
436 {
437 DB( g_print(" -> delete pay '%s'\n", item->name) );
438 da_pay_remove(item->key);
439 }
440 list = g_list_next(list);
441 }
442 g_list_free(lxxx);
443
444 // 3: delete imported category
445 lxxx = list = g_hash_table_get_values(GLOBALS->h_cat);
446 while (list != NULL)
447 {
448 Category *item = list->data;
449
450 if( item->imported == TRUE )
451 {
452 DB( g_print(" -> delete cat '%s'\n", item->name) );
453 da_cat_remove(item->key);
454 }
455 list = g_list_next(list);
456 }
457 g_list_free(lxxx);
458
459 _import_context_clear(&data->ictx);
460
461 }
462
463
464 static gboolean ui_import_panel_transaction_is_duplicate(Transaction *impope, Transaction *ope, gint maxgap)
465 {
466 Account *dstacc;
467 guint dstkacc;
468 gboolean retval = FALSE;
469
470 //common tests
471 if( (impope->amount == ope->amount) &&
472 (ope->date <= (impope->date + maxgap)) && (ope->date >= (impope->date - maxgap)) )
473 {
474
475 //we focus the test on impope->acc->imp_key (and not impope->kacc)
476 dstkacc = impope->kacc;
477 dstacc = da_acc_get(dstkacc);
478 if( dstacc && dstacc->imp_key > 0 )
479 {
480 dstkacc = dstacc->imp_key;
481 }
482
483 DB( g_print("--------\n -> dstkacc=%d, amount & date are similar\n", dstkacc) );
484
485 DB( g_print(" -> impope: kacc=%d, %s kxfer=%d, kxferacc=%d\n", impope->kacc, impope->wording, impope->kxfer, impope->kxferacc) );
486 DB( g_print(" -> ope: kacc=%d, %s kxfer=%d, kxferacc=%d\n", ope->kacc, ope->wording, ope->kxfer, ope->kxferacc) );
487
488
489 if(impope->paymode != PAYMODE_INTXFER)
490 {
491 if( dstkacc == ope->kacc )
492 {
493 DB( g_print(" -> impope is not a xfer and acc are similar\n") );
494 retval = TRUE;
495 }
496 }
497 else
498 {
499 if( ( (impope->kxferacc == ope->kxferacc) && ope->kxfer != 0) ||
500 ( impope->kxferacc == 0 )
501 )
502 retval = TRUE;
503 }
504 }
505 return retval;
506 }
507
508
509 static void ui_import_panel_transaction_find_duplicate(struct import_data *data)
510 {
511 ImportContext *ictx = &data->ictx;
512 GList *tmplist, *implist;
513 Transaction *item;
514 guint32 mindate;
515 guint maxgap;
516
517 DB( g_print("\n[import] find duplicate\n") );
518
519 ictx->nb_duplicate = 0;
520 if( ictx->trans_list )
521 {
522 /* 1: get import min bound date */
523 tmplist = g_list_first(ictx->trans_list);
524 item = tmplist->data;
525 mindate = item->date;
526 maxgap = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->NB_maxgap));
527
528 /* clear any previous same txn */
529 implist = g_list_first(ictx->trans_list);
530 while (implist != NULL)
531 {
532 Transaction *impope = implist->data;
533
534 if(impope->same != NULL)
535 {
536 g_list_free(impope->same);
537 impope->same = NULL;
538 }
539 implist = g_list_next(implist);
540 }
541
542
543 GQueue *txn_queue = da_obsolete_transaction_get_partial(mindate);
544
545 //tmplist = g_list_first(GLOBALS->ope_list);
546 tmplist = g_queue_peek_head_link(txn_queue);
547 while (tmplist != NULL)
548 {
549 Transaction *ope = tmplist->data;
550
551 if( ope->date >= mindate )
552 {
553 //DB( g_print("should check here %d: %s\n", ope->date, ope->wording) );
554
555 implist = g_list_first(ictx->trans_list);
556 while (implist != NULL)
557 {
558 Transaction *impope = implist->data;
559
560 if( ui_import_panel_transaction_is_duplicate(impope, ope, maxgap) )
561 {
562 //DB( g_print(" found %d: %s\n", impope->date, impope->wording) );
563
564 impope->same = g_list_append(impope->same, ope);
565 ictx->nb_duplicate++;
566 }
567
568 implist = g_list_next(implist);
569 }
570 }
571
572 tmplist = g_list_next(tmplist);
573 }
574
575 g_queue_free (txn_queue);
576
577 }
578
579 DB( g_print(" nb_duplicate = %d\n", ictx->nb_duplicate) );
580
581
582 }
583
584
585 static void ui_import_panel_account_fill(struct import_data *data)
586 {
587 ImportContext *ictx = &data->ictx;
588 gchar *label = NULL;
589 gchar *icon_name = NULL;
590 GList *lacc, *list;
591
592 DB( g_print("\n[import] panel account fill\n") );
593
594 if(ictx->nb_new_acc == 0)
595 {
596 icon_name = ICONNAME_INFO;
597 label = g_strdup( _("All seems all right here, your validation is optional!") );
598 }
599 else
600 {
601 gchar *tmpstr;
602
603 /* file name & path */
604 tmpstr = g_path_get_basename(data->filename);
605
606
607
608 icon_name = ICONNAME_WARNING;
609 label = g_strdup_printf(
610 _("No account information has been found into the file '%s'.\n"
611 "Please select the appropriate action for account below."),
612 tmpstr);
613
614 g_free(tmpstr);
615 }
616
617 gtk_label_set_text(GTK_LABEL(data->LB_acc), label);
618 gtk_image_set_from_icon_name(GTK_IMAGE(data->IM_acc), icon_name, GTK_ICON_SIZE_BUTTON);
619
620 g_free(label);
621
622 gtk_list_store_clear (GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_acc))));
623
624 lacc = list = g_hash_table_get_values(GLOBALS->h_acc);
625 while (list != NULL)
626 {
627 Account *item = list->data;
628
629 if( item->imported == TRUE )
630 {
631 ui_acc_affect_listview_add(GTK_TREE_VIEW(data->LV_acc), item);
632 }
633 list = g_list_next(list);
634 }
635 g_list_free(lacc);
636
637 DB( _import_context_debug(&data->ictx) );
638 }
639
640
641 /* count transaction with checkbox 'import' */
642 static void import_count_changes(struct import_data *data)
643 {
644 GList *lacc, *list;
645 GtkTreeModel *model;
646 GtkTreeIter iter;
647 gboolean valid;
648
649 DB( g_print("\n[import] count_final_changes\n") );
650
651 data->imp_cnt_acc = 0;
652
653 lacc = list = g_hash_table_get_values(GLOBALS->h_acc);
654 while (list != NULL)
655 {
656 Account *item = list->data;
657
658 if( item->imported == TRUE && item->imp_key != 0)
659 {
660 data->imp_cnt_acc++;
661 }
662 list = g_list_next(list);
663 }
664 g_list_free(lacc);
665
666
667 // then import transactions
668 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->imported_ope));
669
670 data->imp_cnt_trn = 0;
671
672 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
673 while (valid)
674 {
675 gboolean toimport;
676
677 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
678 LST_OPE_IMPTOGGLE, &toimport,
679 -1);
680
681 if(toimport == TRUE)
682 data->imp_cnt_trn++;
683
684 /* Make iter point to the next row in the list store */
685 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
686 }
687 }
688
689
690 static void import_apply(struct import_data *data)
691 {
692 GtkTreeModel *model;
693 GtkTreeIter iter;
694 gboolean valid;
695 GList *lxxx, *list;
696
697 DB( g_print("\n[import] apply\n") );
698
699 // 1: persist imported accounts
700 lxxx = list = g_hash_table_get_values(GLOBALS->h_acc);
701 while (list != NULL)
702 {
703 Account *item = list->data;
704
705 if( item->imported == TRUE )
706 {
707 //only persist user selected to new account
708 if( item->imp_key == 0)
709 {
710 DB( g_print(" -> persist acc %x '%s' k=%d, ik=%d\n", item, item->name, item->key, item->imp_key) );
711 item->imported = FALSE;
712 g_free(item->imp_name);
713 item->imp_name = NULL;
714 }
715 //else
716 //DB( g_print(" -> keep exist acc %x '%s' k=%d, ik=%d\n", item, item->name, item->key, item->imp_key) );
717
718 }
719 list = g_list_next(list);
720 }
721 g_list_free(lxxx);
722
723 // 2: persist imported payees
724 lxxx = list = g_hash_table_get_values(GLOBALS->h_pay);
725 while (list != NULL)
726 {
727 Payee *item = list->data;
728
729 if( item->imported == TRUE )
730 {
731 //DB( g_print(" -> persist pay '%s'\n", item->name) );
732 item->imported = FALSE;
733 }
734 list = g_list_next(list);
735 }
736 g_list_free(lxxx);
737
738 // 3: persist imported categories
739 lxxx = list = g_hash_table_get_values(GLOBALS->h_cat);
740 while (list != NULL)
741 {
742 Category *item = list->data;
743
744 if( item->imported == TRUE )
745 {
746 //DB( g_print(" -> persist cat '%s'\n", item->name) );
747 item->imported = FALSE;
748 }
749 list = g_list_next(list);
750 }
751 g_list_free(lxxx);
752
753 // 4: insert every transactions
754 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->imported_ope));
755 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
756 while (valid)
757 {
758 Transaction *item;
759 gboolean toimport;
760
761 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
762 LST_DSPOPE_DATAS, &item,
763 LST_OPE_IMPTOGGLE, &toimport,
764 -1);
765
766 if(toimport == TRUE)
767 {
768 Account *acc;
769
770 //DB(g_print("import %d to acc: %d\n", data->total, item->account) );
771
772 //todo: here also test imp_key on account and change the key into the transaction
773 acc = da_acc_get(item->kacc);
774 if( (acc != NULL) && (acc->imp_key > 0) )
775 {
776 item->kacc = acc->imp_key;
777 }
778
779 //#1653957 change also kxferacc
780 if( item->paymode == PAYMODE_INTXFER )
781 {
782 acc = da_acc_get(item->kxferacc);
783 if( (acc != NULL) && (acc->imp_key > 0) )
784 {
785 item->kxferacc = acc->imp_key;
786 }
787 }
788
789 transaction_add(item);
790 }
791
792 /* Make iter point to the next row in the list store */
793 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
794 }
795
796
797 }
798
799 /*
800 **
801 */
802 static gboolean
803 ui_import_assistant_dispose(GtkWidget *widget, gpointer user_data)
804 {
805 struct import_data *data = user_data;
806
807 DB( g_print("\n[import] dispose\n") );
808
809 #if MYDEBUG == 1
810 gpointer data2 = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
811 g_print(" user_data=%08x to be free, data2=%x\n", (gint)user_data, (gint)data2);
812 #endif
813
814 g_free( data->filename );
815
816 import_clearall(data);
817
818
819
820
821 // todo: optimize this
822 if(data->imp_cnt_trn > 0)
823 {
824 GLOBALS->changes_count += data->imp_cnt_trn;
825
826 //our global list has changed, so update the treeview
827 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_BALANCE+UF_REFRESHALL));
828 }
829
830
831 g_free(user_data);
832
833
834 //delete-event TRUE abort/FALSE destroy
835 return FALSE;
836 }
837
838
839 static void ui_import_panel_transaction_fill(struct import_data *data)
840 {
841 ImportContext *ictx = &data->ictx;
842 GtkWidget *view;
843 GtkTreeModel *model;
844 GtkTreeIter iter;
845 GList *tmplist;
846 gchar *label = NULL;
847 gchar *icon_name = NULL;
848
849 //DB( g_print("\n[import] fill imp operatoin\n") );
850
851 if(ictx->nb_duplicate == 0)
852 {
853 icon_name = ICONNAME_INFO;
854 label = _("All seems all right here, your validation is optional!");
855 }
856 else
857 {
858 icon_name = ICONNAME_WARNING;
859 label =
860 _("Possible duplicate of existing transaction have been found, and disabled for import.\n"
861 "Please check and choose the ones that have to be imported.");
862 }
863
864 gtk_label_set_text(GTK_LABEL(data->LB_txn), label);
865 gtk_image_set_from_icon_name(GTK_IMAGE(data->IM_txn), icon_name, GTK_ICON_SIZE_BUTTON);
866
867
868 view = data->imported_ope;
869 model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
870
871 gtk_list_store_clear (GTK_LIST_STORE(model));
872
873 g_object_ref(model); /* Make sure the model stays with us after the tree view unrefs it */
874 gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); /* Detach model from view */
875
876 tmplist = g_list_first(ictx->trans_list);
877 while (tmplist != NULL)
878 {
879 Transaction *item = tmplist->data;
880
881 /* append to our treeview */
882 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
883
884 //DB( g_print(" populate: %s\n", ope->ope_Word) );
885
886 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
887 LST_DSPOPE_DATAS, item,
888 LST_OPE_IMPTOGGLE, item->same == NULL ? TRUE : FALSE,
889 -1);
890
891 //DB( g_print(" - fill: %d, %s %.2f %x\n", item->account, item->wording, item->amount, item->same) );
892
893 tmplist = g_list_next(tmplist);
894 }
895
896 gtk_tree_view_set_model(GTK_TREE_VIEW(view), model); /* Re-attach model to view */
897
898 g_object_unref(model);
899
900
901
902 }
903
904
905 static void ui_import_panel_account_change_action_toggled_cb(GtkRadioButton *radiobutton, gpointer user_data)
906 {
907 struct import_target_data *data;
908 gboolean new_account;
909
910
911 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(radiobutton), GTK_TYPE_WINDOW)), "inst_data");
912
913 DB( g_print("\n[import] account type toggle\n") );
914
915 new_account = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->radio[0]));
916
917 gtk_widget_set_sensitive(data->label1, new_account);
918 gtk_widget_set_sensitive(data->getwidget1, new_account);
919
920 gtk_widget_set_sensitive(data->label2, new_account^1);
921 gtk_widget_set_sensitive(data->getwidget2, new_account^1);
922
923 }
924
925
926 static void ui_import_panel_account_change_action(GtkWidget *widget, gpointer user_data)
927 {
928 struct import_data *data;
929 struct import_target_data ddata;
930 ImportContext *ictx;
931 GtkWidget *dialog, *content_area, *group_grid, *label ;
932 guint32 key;
933 gint row;
934
935 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
936 DB( g_print("\n[import] account_change_action\n") );
937
938 ictx = &data->ictx;
939
940 key = ui_acc_affect_listview_get_selected_key(GTK_TREE_VIEW(data->LV_acc));
941 if( key > 0 )
942 {
943 Account *item;
944
945 item = da_acc_get( key );
946
947 dialog = gtk_dialog_new_with_buttons (_("Change account action"),
948 GTK_WINDOW (data->assistant),
949 0,
950 _("_Cancel"),
951 GTK_RESPONSE_REJECT,
952 _("_OK"),
953 GTK_RESPONSE_ACCEPT,
954 NULL);
955
956 //store our window private data
957 g_object_set_data(G_OBJECT(dialog), "inst_data", (gpointer)&ddata);
958
959 content_area = gtk_dialog_get_content_area(GTK_DIALOG (dialog));
960
961 // group :: dialog
962 group_grid = gtk_grid_new ();
963 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
964 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
965 gtk_container_set_border_width (GTK_CONTAINER(group_grid), SPACING_MEDIUM);
966 gtk_box_pack_start (GTK_BOX (content_area), group_grid, TRUE, TRUE, SPACING_SMALL);
967
968 row = 0;
969 ddata.radio[0] = gtk_radio_button_new_with_label (NULL, _("create new"));
970 gtk_grid_attach (GTK_GRID (group_grid), ddata.radio[0], 0, row, 3, 1);
971
972 row++;
973 label = make_label(_("_Name:"), 0, 0.5);
974 ddata.label1 = label;
975 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
976
977 ddata.getwidget1 = gtk_entry_new();
978 gtk_grid_attach (GTK_GRID (group_grid), ddata.getwidget1, 2, row, 1, 1);
979
980 row++;
981 ddata.radio[1] = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (ddata.radio[0]), _("use existing"));
982 gtk_grid_attach (GTK_GRID (group_grid), ddata.radio[1], 0, row, 3, 1);
983
984 row++;
985 label = make_label(_("A_ccount:"), 0, 0.5);
986 ddata.label2 = label;
987 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
988
989 ddata.getwidget2 = ui_acc_comboboxentry_new(NULL);
990 gtk_grid_attach (GTK_GRID (group_grid), ddata.getwidget2, 2, row, 1, 1);
991
992 //initialize
993 if( ictx->next_acc_key > 0 ) //if there were already some accounts
994 {
995 gtk_widget_set_sensitive(ddata.radio[1], TRUE);
996 if( item->imp_key > 0 )
997 {
998 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ddata.radio[1]), TRUE);
999 }
1000 }
1001 else
1002 {
1003 gtk_widget_set_sensitive(ddata.radio[1], FALSE);
1004
1005 }
1006
1007 gtk_entry_set_text(GTK_ENTRY(ddata.getwidget1), item->name);
1008 ui_acc_comboboxentry_populate(GTK_COMBO_BOX(ddata.getwidget2), GLOBALS->h_acc, ACC_LST_INSERT_NORMAL);
1009 ui_acc_comboboxentry_set_active(GTK_COMBO_BOX(ddata.getwidget2), item->imp_key);
1010
1011 ui_import_panel_account_change_action_toggled_cb(GTK_RADIO_BUTTON (ddata.radio[0]), NULL);
1012
1013 gtk_widget_show_all(group_grid);
1014
1015 g_signal_connect (ddata.radio[0], "toggled", G_CALLBACK (ui_import_panel_account_change_action_toggled_cb), NULL);
1016
1017
1018 //wait for the user
1019 gint result = gtk_dialog_run (GTK_DIALOG (dialog));
1020
1021 if(result == GTK_RESPONSE_ACCEPT)
1022 {
1023 gchar *name;
1024 gboolean bnew;
1025 guint key;
1026
1027 key = ui_acc_comboboxentry_get_key(GTK_COMBO_BOX(ddata.getwidget2));
1028
1029 bnew = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ddata.radio[0]));
1030 if( bnew )
1031 {
1032
1033 name = (gchar *)gtk_entry_get_text(GTK_ENTRY(ddata.getwidget1));
1034
1035 if(strcasecmp(name, item->name))
1036 {
1037
1038 DB( g_print("name '%s', existing acc %d\n", name, key) );
1039
1040 if (name && *name)
1041 {
1042 if( account_rename(item, name) == FALSE )
1043 {
1044 ui_dialog_msg_infoerror(GTK_WINDOW(dialog), GTK_MESSAGE_ERROR,
1045 _("Error"),
1046 _("Cannot rename this Account,\n"
1047 "from '%s' to '%s',\n"
1048 "this name already exists."),
1049 item->name,
1050 name
1051 );
1052 }
1053 }
1054 }
1055 else
1056 {
1057 item->imp_key = 0;
1058 }
1059 }
1060 else
1061 {
1062 item->imp_key = key;
1063 }
1064
1065 //we should refresh duplicate
1066 ui_import_panel_transaction_find_duplicate(data);
1067 ui_import_panel_transaction_fill(data);
1068
1069 }
1070
1071 // cleanup and destroy
1072 gtk_widget_destroy (dialog);
1073 }
1074
1075 }
1076
1077
1078 static void ui_import_panel_filechooser_selection_changed(GtkWidget *widget, gpointer user_data)
1079 {
1080 struct import_data *data = user_data;
1081 gint page_number;
1082 GtkWidget *current_page;
1083 gchar *filename;
1084
1085 page_number = gtk_assistant_get_current_page (GTK_ASSISTANT(data->assistant));
1086
1087 DB( g_print("\n[import] selchange (page %d)\n", page_number+1) );
1088
1089 data->valid = FALSE;
1090
1091 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(data->filechooser));
1092 if( filename == NULL )
1093 {
1094 gtk_label_set_text(GTK_LABEL(data->user_info), _("Please select a file..."));
1095 //current_page = gtk_assistant_get_nth_page (GTK_ASSISTANT(data->assistant), page_number);
1096 //gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), current_page, FALSE);
1097 }
1098 else
1099 {
1100 if( page_number == PAGE_SELECTFILE )
1101 {
1102 if(data->filename)
1103 g_free( data->filename );
1104 data->filename = filename;
1105 //DB( g_print(" filename -> %s\n", data->filename) );
1106
1107 data->filetype = homebank_alienfile_recognize(data->filename);
1108 switch(data->filetype)
1109 {
1110 case FILETYPE_QIF:
1111 gtk_label_set_text(GTK_LABEL(data->user_info), _("QIF file recognised !"));
1112 data->valid = TRUE;
1113 break;
1114
1115 case FILETYPE_OFX:
1116 #ifndef NOOFX
1117 gtk_label_set_text(GTK_LABEL(data->user_info), _("OFX file recognised !"));
1118 data->valid = TRUE;
1119 #else
1120 gtk_label_set_text(GTK_LABEL(data->user_info), _("** OFX support is disabled **"));
1121 #endif
1122 break;
1123
1124 case FILETYPE_CSV_HB:
1125 gtk_label_set_text(GTK_LABEL(data->user_info), _("CSV transaction file recognised !"));
1126 data->valid = TRUE;
1127 break;
1128
1129 default:
1130 data->filetype = FILETYPE_UNKNOW;
1131 gtk_label_set_text(GTK_LABEL(data->user_info), _("Unknown/Invalid file..."));
1132 break;
1133 }
1134
1135 current_page = gtk_assistant_get_nth_page (GTK_ASSISTANT(data->assistant), page_number);
1136 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), current_page, data->valid);
1137
1138 }
1139
1140 }
1141
1142 if(data->valid == TRUE)
1143 {
1144 gtk_widget_show(data->ok_image);
1145 gtk_widget_hide(data->ko_image);
1146 }
1147 else
1148 {
1149 gtk_widget_show(data->ko_image);
1150 gtk_widget_hide(data->ok_image);
1151 }
1152
1153 }
1154
1155
1156
1157 static void ui_import_panel_transaction_fill_same(GtkTreeSelection *treeselection, gpointer user_data)
1158 {
1159 struct import_data *data;
1160 GtkTreeSelection *selection;
1161 GtkTreeModel *model, *newmodel;
1162 GtkTreeIter iter, newiter;
1163 GList *tmplist;
1164 GtkWidget *view, *widget;
1165
1166 widget = GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection));
1167
1168
1169 //DB( g_print("\n[import] fillsame\n") );
1170
1171 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1172
1173 view = data->duplicat_ope;
1174
1175 newmodel = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
1176
1177 gtk_list_store_clear (GTK_LIST_STORE(newmodel));
1178
1179
1180
1181 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->imported_ope));
1182 //if true there is a selected node
1183 if (gtk_tree_selection_get_selected(selection, &model, &iter))
1184 {
1185 Transaction *item;
1186
1187 gtk_tree_model_get(model, &iter, LST_DSPOPE_DATAS, &item, -1);
1188
1189 if( item->same != NULL )
1190 {
1191 tmplist = g_list_first(item->same);
1192 while (tmplist != NULL)
1193 {
1194 Transaction *tmp = tmplist->data;
1195
1196 /* append to our treeview */
1197 gtk_list_store_append (GTK_LIST_STORE(newmodel), &newiter);
1198
1199 gtk_list_store_set (GTK_LIST_STORE(newmodel), &newiter,
1200 LST_DSPOPE_DATAS, tmp,
1201 -1);
1202
1203 //DB( g_print(" - fill: %s %.2f %x\n", item->wording, item->amount, (unsigned int)item->same) );
1204
1205 tmplist = g_list_next(tmplist);
1206 }
1207 }
1208
1209 }
1210
1211
1212
1213
1214 }
1215
1216
1217 static void ui_import_panel_properties_fill(struct import_data *data)
1218 {
1219 ImportContext *ictx = &data->ictx;
1220 gchar *tmpstr;
1221
1222 /* file name & path */
1223 tmpstr = g_path_get_basename(data->filename);
1224 gtk_label_set_text(GTK_LABEL(data->TX_filename), tmpstr);
1225 g_free(tmpstr);
1226
1227 tmpstr = g_path_get_dirname(data->filename);
1228 gtk_label_set_text(GTK_LABEL(data->TX_filepath), tmpstr);
1229 g_free(tmpstr);
1230
1231 gtk_label_set_text(GTK_LABEL(data->TX_encoding), ictx->encoding);
1232
1233 gtk_label_set_text(GTK_LABEL(data->TX_datefmt), CYA_IMPORT_DATEORDER[ictx->datefmt]);
1234
1235 /* file content detail */
1236 //TODO: difficult translation here
1237 tmpstr = g_strdup_printf(_("account: %d - transaction: %d - payee: %d - categorie: %d"),
1238 ictx->nb_src_acc,
1239 ictx->cnt_new_ope,
1240 ictx->cnt_new_pay,
1241 ictx->cnt_new_cat
1242 );
1243 gtk_label_set_text(GTK_LABEL(data->TX_filedetails), tmpstr);
1244 g_free(tmpstr);
1245
1246 DB( _import_context_debug(&data->ictx) );
1247
1248 }
1249
1250
1251 static void ui_import_panel_confirmation_fill(struct import_data *data)
1252 {
1253 ImportContext *ictx = &data->ictx;
1254
1255 /* account summary */
1256 ui_label_set_integer(GTK_LABEL(data->TX_acc_upd), data->imp_cnt_acc);
1257 ui_label_set_integer(GTK_LABEL(data->TX_acc_new), ictx->nb_src_acc - data->imp_cnt_acc);
1258
1259 /* transaction summary */
1260 ui_label_set_integer(GTK_LABEL(data->TX_trn_imp), data->imp_cnt_trn);
1261 ui_label_set_integer(GTK_LABEL(data->TX_trn_nop), ictx->cnt_new_ope - data->imp_cnt_trn);
1262 ui_label_set_integer(GTK_LABEL(data->TX_trn_asg), data->imp_cnt_asg);
1263
1264 }
1265
1266 static void
1267 ui_import_assistant_apply (GtkWidget *widget, gpointer user_data)
1268 {
1269 struct import_data *data;
1270
1271 DB( g_print("\n[import] apply\n") );
1272
1273 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1274
1275
1276 import_apply(data);
1277
1278 }
1279
1280 static void
1281 ui_import_assistant_close_cancel (GtkWidget *widget, gpointer user_data)
1282 {
1283 struct import_data *data;
1284 GtkWidget *assistant = (GtkWidget *) user_data;
1285
1286 DB( g_print("\n[import] close\n") );
1287
1288 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1289
1290 ui_import_assistant_dispose(widget, data);
1291
1292
1293 //g_free(data);
1294
1295
1296 gtk_widget_destroy (assistant);
1297 //assistant = NULL;
1298 }
1299
1300
1301 static void _import_tryload_file(struct import_data *data)
1302 {
1303 ImportContext *ictx = &data->ictx;
1304
1305 DB( g_print("\n[import] try load file\n") );
1306
1307 DB( g_print(" -> encoding='%s'\n", ictx->encoding) );
1308 DB( g_print(" -> date format='%s' (%d)\n", CYA_IMPORT_DATEORDER[ictx->datefmt], ictx->datefmt) );
1309
1310
1311 switch(data->filetype)
1312 {
1313 #ifndef NOOFX
1314 /* ofx_acc_list & ofx_ope_list are filled here */
1315 case FILETYPE_OFX:
1316 ictx->trans_list = homebank_ofx_import(data->filename, &data->ictx);
1317 break;
1318 #endif
1319 case FILETYPE_QIF:
1320 ictx->trans_list = homebank_qif_import(data->filename, &data->ictx);
1321 break;
1322
1323 case FILETYPE_CSV_HB:
1324 ictx->trans_list = homebank_csv_import(data->filename, &data->ictx);
1325 break;
1326 }
1327
1328 DB( g_print(" -> result: nbtrans=%d, date errors=%d\n", ictx->cnt_new_ope, ictx->cnt_err_date) );
1329
1330
1331 }
1332
1333
1334 static void import_file_import(struct import_data *data)
1335 {
1336 ImportContext *ictx = &data->ictx;
1337
1338 DB( g_print("\n[import] real import\n") );
1339
1340 import_clearall(data);
1341 ictx->encoding = homebank_file_getencoding(data->filename);
1342 _import_tryload_file(data);
1343
1344 // if fail, try to load with different date format
1345 if( ictx->cnt_err_date > 0)
1346 {
1347 const gchar *encoding = ictx->encoding;
1348 gint i;
1349
1350 for(i=0;i<NUM_PRF_DATEFMT;i++)
1351 {
1352 gboolean do_fix;
1353
1354 if(i != PREFS->dtex_datefmt) //don't reload with user pref date format
1355 {
1356 do_fix = ui_dialog_msg_question(
1357 GTK_WINDOW(data->assistant),
1358 _("Some date convertion failed"),
1359 _("Reload using date order: '%s' ?"),
1360 CYA_IMPORT_DATEORDER[i]
1361 );
1362
1363 if(do_fix == GTK_RESPONSE_YES)
1364 {
1365 DB( g_print(" fail, reload with '%s'\n", CYA_IMPORT_DATEORDER[i]) );
1366 //#1448549
1367 import_clearall(data);
1368 ictx->encoding = encoding; //#1425986 keep encoding with us
1369 ictx->datefmt = i;
1370 _import_tryload_file(data);
1371
1372 DB( g_print(" -> reloaded: nbtrans=%d, date errors=%d\n", ictx->cnt_new_ope, ictx->cnt_err_date) );
1373
1374 if(ictx->cnt_err_date == 0)
1375 break;
1376 }
1377
1378 }
1379 }
1380
1381 }
1382
1383 DB( g_print(" end of try import\n") );
1384
1385 // sort by date
1386 ictx->trans_list = da_transaction_sort(ictx->trans_list);
1387
1388 }
1389
1390 /**
1391 * ui_import_assistant_forward_page_func:
1392 *
1393 * define the page to be called when the user forward
1394 *
1395 * Return value: the page number
1396 *
1397 */
1398 static gint
1399 ui_import_assistant_forward_page_func(gint current_page, gpointer func_data)
1400 {
1401 gint next_page;
1402
1403 DB( g_print("---------------------------\n") );
1404 DB( g_print("\n[import] forward page func :: page %d\n", current_page) );
1405
1406 DB( g_print(" -> current: %d %s\n", current_page, page_titles[MIN(current_page, NUM_PAGE-1)] ) );
1407
1408 #ifdef MYDEBUG
1409 /*
1410 struct import_data *data = func_data;
1411 gint i
1412 for(i=0;i<NUM_PAGE;i++)
1413 {
1414 g_print("%d: %d '%s'\n", i,
1415 gtk_assistant_get_page_complete(GTK_ASSISTANT(data->assistant), data->pages[i]),
1416 page_titles[i]
1417 );
1418 }*/
1419 #endif
1420
1421 DB( g_print(" -> current: %d %s\n", current_page, page_titles[MIN(current_page, NUM_PAGE-1)] ) );
1422
1423 next_page = current_page + 1;
1424
1425 switch(current_page)
1426 {
1427 /*case PAGE_IMPORT:
1428 // if no new account, skip the account page
1429 if(ictx->nb_new_acc == 0)
1430 next_page = PAGE_TRANSACTION;
1431 break;*/
1432 }
1433
1434 DB( g_print(" -> next: %d %s\n", next_page, page_titles[MIN(next_page, NUM_PAGE-1)] ) );
1435
1436 return next_page;
1437 }
1438
1439
1440
1441
1442 static void
1443 ui_import_assistant_prepare (GtkWidget *widget, GtkWidget *page, gpointer user_data)
1444 {
1445 struct import_data *data;
1446 ImportContext *ictx;
1447 gint current_page, n_pages;
1448 gchar *title;
1449
1450 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1451
1452 ictx = &data->ictx;
1453
1454 current_page = gtk_assistant_get_current_page (GTK_ASSISTANT(data->assistant));
1455 n_pages = gtk_assistant_get_n_pages (GTK_ASSISTANT(data->assistant));
1456
1457 DB( g_print("\n[import] prepare %d of %d\n", current_page, n_pages) );
1458
1459 switch( current_page )
1460 {
1461 case PAGE_WELCOME:
1462 DB( g_print(" -> 1 intro\n") );
1463 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, TRUE);
1464 break;
1465
1466 case PAGE_SELECTFILE:
1467 DB( g_print(" -> 2 file choose\n") );
1468
1469 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, FALSE);
1470 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), data->pages[PAGE_ACCOUNT], FALSE);
1471 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), data->pages[PAGE_TRANSACTION], FALSE);
1472 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), data->pages[PAGE_CONFIRM], FALSE);
1473
1474 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(data->filechooser), PREFS->path_import);
1475 DB( g_print(" -> set current folder '%s'\n", PREFS->path_import) );
1476
1477 // the page complete is contextual in ui_import_panel_filechooser_selection_changed
1478 break;
1479
1480 case PAGE_IMPORT:
1481 DB( g_print(" -> 3 real import\n") );
1482
1483 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, FALSE);
1484 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), data->pages[PAGE_ACCOUNT], FALSE);
1485
1486 /* remind folder to preference */
1487 gchar *folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(data->filechooser));
1488 DB( g_print(" -> store folder '%s'\n", folder) );
1489 g_free(PREFS->path_import);
1490 PREFS->path_import = folder;
1491
1492 import_file_import(data);
1493 _import_context_count(data);
1494
1495 if( ictx->cnt_new_ope > 0 && ictx->cnt_err_date <= 0 )
1496 {
1497 if(ictx->nb_new_acc == 0)
1498 {
1499 DB( g_print(" -> jump to Transaction page\n") );
1500 //gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), data->pages[PAGE_ACCOUNT], TRUE);
1501 gtk_assistant_next_page(GTK_ASSISTANT(data->assistant));
1502 gtk_assistant_next_page(GTK_ASSISTANT(data->assistant));
1503 gtk_assistant_next_page(GTK_ASSISTANT(data->assistant));
1504 //gtk_assistant_set_current_page (GTK_ASSISTANT(data->assistant), PAGE_TRANSACTION);
1505 }
1506 else
1507 {
1508 DB( g_print(" -> jump to Account page\n") );
1509 //gtk_assistant_set_current_page (GTK_ASSISTANT(data->assistant), PAGE_ACCOUNT);
1510 gtk_assistant_next_page(GTK_ASSISTANT(data->assistant));
1511 gtk_assistant_next_page(GTK_ASSISTANT(data->assistant));
1512 }
1513
1514 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, TRUE);
1515 }
1516 break;
1517
1518 case PAGE_PROPERTIES:
1519 DB( g_print(" -> 4 properties\n") );
1520
1521
1522 ui_import_panel_properties_fill(data);
1523
1524 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, TRUE);
1525 break;
1526
1527 case PAGE_ACCOUNT:
1528 DB( g_print(" -> 5 account\n") );
1529
1530 ui_import_panel_account_fill(data);
1531
1532 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, TRUE);
1533 break;
1534
1535 case PAGE_TRANSACTION:
1536 DB( g_print(" -> 6 transaction\n") );
1537
1538 //todo: should be optional
1539 data->imp_cnt_asg = transaction_auto_assign(ictx->trans_list, 0);
1540
1541 ui_import_panel_transaction_find_duplicate(data);
1542
1543 ui_import_panel_transaction_fill(data);
1544
1545 if( ictx->nb_duplicate > 0 )
1546 {
1547 gtk_widget_show(data->GR_duplicate);
1548 gtk_expander_set_expanded(GTK_EXPANDER(data->GR_duplicate), TRUE);
1549 }
1550 else
1551 {
1552 gtk_widget_hide(data->GR_duplicate);
1553 }
1554
1555 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, TRUE);
1556 break;
1557
1558 case PAGE_CONFIRM:
1559 {
1560 DB( g_print(" -> 7 confirmation\n") );
1561
1562 //todo:rework this
1563 import_count_changes(data);
1564
1565 ui_import_panel_confirmation_fill(data);
1566
1567
1568
1569 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, TRUE);
1570 break;
1571 }
1572 }
1573
1574 title = g_strdup_printf ( _("Import assistant (%d of %d)"), current_page + 1 , n_pages );
1575 gtk_window_set_title (GTK_WINDOW (data->assistant), title);
1576 g_free (title);
1577 }
1578
1579
1580
1581
1582
1583
1584 static void
1585 ui_import_panel_transaction_refresh (GtkWidget *widget, gpointer data)
1586 {
1587
1588 DB( g_print("\n[import] refresh transaction\n") );
1589
1590 ui_import_panel_transaction_find_duplicate(data);
1591 ui_import_panel_transaction_fill(data);
1592
1593 }
1594
1595
1596 static void ui_acc_affect_listview_onRowActivated (GtkTreeView *treeview,
1597 GtkTreePath *path,
1598 GtkTreeViewColumn *col,
1599 gpointer userdata)
1600 {
1601 //GtkTreeModel *model;
1602
1603 //model = gtk_tree_view_get_model(treeview);
1604 //gtk_tree_model_get_iter_first(model, &iter);
1605 //if(gtk_tree_selection_iter_is_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), &iter) == FALSE)
1606 //{
1607 ui_import_panel_account_change_action(GTK_WIDGET(treeview), NULL);
1608 //}
1609 }
1610
1611
1612 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
1613
1614
1615 static GtkWidget *
1616 ui_import_panel_welcome_create(GtkWidget *assistant, struct import_data *data)
1617 {
1618 GtkWidget *vbox, *label, *align;
1619
1620 align = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
1621 gtk_alignment_set_padding(GTK_ALIGNMENT(align), 0, 0, 0, 0);
1622
1623 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_SMALL);
1624 //gtk_container_set_border_width (GTK_CONTAINER(vbox), SPACING_MEDIUM);
1625 gtk_container_add(GTK_CONTAINER(align), vbox);
1626
1627 label = make_label(
1628 _("Welcome to the HomeBank Import Assistant.\n\n" \
1629 "With this assistant you will be guided throught the process\n" \
1630 "of importing an external file into HomeBank.\n\n" \
1631 "No changes will be made until you click \"Apply\" at the end\n" \
1632 "of this assistant.")
1633 , 0., 0.0);
1634 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, SPACING_SMALL);
1635
1636 /* supported format */
1637
1638
1639 label = make_label(
1640 _("HomeBank can import files in the following formats:\n" \
1641 "- QIF\n" \
1642 "- OFX/QFX (optional at compilation time)\n" \
1643 "- CSV (format is specific to HomeBank, see the documentation)\n" \
1644 ), 0.0, 0.0);
1645
1646 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, SPACING_SMALL);
1647
1648
1649 gtk_widget_show_all (align);
1650
1651 gtk_assistant_append_page (GTK_ASSISTANT (assistant), align);
1652 gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), align, GTK_ASSISTANT_PAGE_INTRO);
1653 gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), align, _(page_titles[PAGE_WELCOME]));
1654 //gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), align, TRUE);
1655
1656 return align;
1657 }
1658
1659
1660 static GtkWidget *
1661 ui_import_panel_filechooser_create (GtkWidget *assistant, struct import_data *data)
1662 {
1663 GtkWidget *vbox, *hbox, *align, *widget, *label;
1664 GtkFileFilter *filter;
1665
1666 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_SMALL);
1667 //gtk_container_set_border_width (GTK_CONTAINER(vbox), SPACING_MEDIUM);
1668
1669
1670 // widget = gtk_file_chooser_button_new ("Pick a File", GTK_FILE_CHOOSER_ACTION_OPEN);
1671
1672 widget = gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_OPEN);
1673
1674
1675
1676 data->filechooser = widget;
1677 gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0);
1678
1679 filter = gtk_file_filter_new ();
1680 gtk_file_filter_set_name (filter, _("Known files"));
1681 gtk_file_filter_add_pattern (filter, "*.[Qq][Ii][Ff]");
1682 #ifndef NOOFX
1683 gtk_file_filter_add_pattern (filter, "*.[OoQq][Ff][Xx]");
1684 #endif
1685 gtk_file_filter_add_pattern (filter, "*.[Cc][Ss][Vv]");
1686 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(widget), filter);
1687 if(data->filetype == FILETYPE_UNKNOW)
1688 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(widget), filter);
1689
1690 filter = gtk_file_filter_new ();
1691 gtk_file_filter_set_name (filter, _("QIF files"));
1692 gtk_file_filter_add_pattern (filter, "*.[Qq][Ii][Ff]");
1693 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(widget), filter);
1694 if(data->filetype == FILETYPE_QIF)
1695 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(widget), filter);
1696
1697 #ifndef NOOFX
1698 filter = gtk_file_filter_new ();
1699 gtk_file_filter_set_name (filter, _("OFX/QFX files"));
1700 gtk_file_filter_add_pattern (filter, "*.[OoQq][Ff][Xx]");
1701 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(widget), filter);
1702 if(data->filetype == FILETYPE_OFX)
1703 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(widget), filter);
1704 #endif
1705
1706 filter = gtk_file_filter_new ();
1707 gtk_file_filter_set_name (filter, _("CSV files"));
1708 gtk_file_filter_add_pattern (filter, "*.[Cc][Ss][Vv]");
1709 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(widget), filter);
1710 if(data->filetype == FILETYPE_CSV_HB)
1711 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(widget), filter);
1712
1713
1714 filter = gtk_file_filter_new ();
1715 gtk_file_filter_set_name (filter, _("All files"));
1716 gtk_file_filter_add_pattern (filter, "*");
1717 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(widget), filter);
1718
1719
1720 /* our addon message */
1721 align = gtk_alignment_new(0.65, 0, 0, 0);
1722 gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
1723
1724 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
1725 gtk_container_add(GTK_CONTAINER(align), hbox);
1726
1727 label = gtk_label_new("");
1728 data->user_info = label;
1729 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, SPACING_SMALL);
1730
1731 gimp_label_set_attributes (GTK_LABEL (label),
1732 PANGO_ATTR_SCALE, PANGO_SCALE_LARGE,
1733 PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
1734 -1);
1735
1736
1737
1738 widget = gtk_image_new_from_icon_name(ICONNAME_HB_FILE_VALID, GTK_ICON_SIZE_LARGE_TOOLBAR);
1739 data->ok_image = widget;
1740 gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
1741
1742 widget = gtk_image_new_from_icon_name(ICONNAME_HB_FILE_INVALID, GTK_ICON_SIZE_LARGE_TOOLBAR);
1743 data->ko_image = widget;
1744 gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
1745
1746
1747 gtk_widget_show_all (vbox);
1748 gtk_widget_hide(data->ok_image);
1749 gtk_widget_hide(data->ko_image);
1750
1751
1752 gtk_assistant_append_page (GTK_ASSISTANT (assistant), vbox);
1753 //gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), vbox, GTK_ASSISTANT_PAGE_CONTENT);
1754 gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), vbox, _(page_titles[PAGE_SELECTFILE]));
1755
1756
1757
1758 return vbox;
1759 }
1760
1761
1762 static GtkWidget *
1763 ui_import_panel_import_create (GtkWidget *assistant, struct import_data *data)
1764 {
1765 GtkWidget *align, *content_grid;
1766 GtkWidget *label, *widget;
1767 gchar *txt;
1768
1769 align = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
1770
1771 content_grid = gtk_grid_new();
1772 gtk_grid_set_column_spacing (GTK_GRID (content_grid), SPACING_MEDIUM);
1773 gtk_orientable_set_orientation(GTK_ORIENTABLE(content_grid), GTK_ORIENTATION_VERTICAL);
1774 gtk_container_add(GTK_CONTAINER(align), content_grid);
1775
1776 widget = gtk_image_new_from_icon_name(ICONNAME_ERROR, GTK_ICON_SIZE_DIALOG );
1777 gtk_grid_attach (GTK_GRID (content_grid), widget, 0, 0, 1, 1);
1778
1779 txt = _("A general error occured, and this file cannot be loaded.");
1780 label = gtk_label_new(txt);
1781 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
1782 gtk_grid_attach (GTK_GRID (content_grid), label, 1, 0, 1, 1);
1783
1784 gtk_widget_show_all (align);
1785 gtk_assistant_append_page (GTK_ASSISTANT (assistant), align);
1786 //gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), align, GTK_ASSISTANT_PAGE_PROGRESS);
1787 gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), align, _(page_titles[PAGE_IMPORT]));
1788
1789 return align;
1790 }
1791
1792
1793
1794 static GtkWidget *
1795 ui_import_panel_properties_create (GtkWidget *assistant, struct import_data *data)
1796 {
1797 GtkWidget *content_grid, *group_grid;
1798 GtkWidget *label, *widget;
1799 gint crow, row;
1800
1801 content_grid = gtk_grid_new();
1802 gtk_grid_set_row_spacing (GTK_GRID (content_grid), SPACING_LARGE);
1803 gtk_orientable_set_orientation(GTK_ORIENTABLE(content_grid), GTK_ORIENTATION_VERTICAL);
1804
1805 crow = 0;
1806 // group :: File properties
1807 group_grid = gtk_grid_new ();
1808 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
1809 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
1810 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
1811
1812 label = make_label_group(_("File properties"));
1813 gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
1814
1815 row = 1;
1816 label = make_label(_("Name:"), 0.0, 0.5);
1817 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
1818 widget = make_label(NULL, 0.0, 0.5);
1819 data->TX_filename = widget;
1820 gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
1821
1822 row++;
1823 label = make_label(_("Path:"), 0.0, 0.5);
1824 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
1825 widget = make_label(NULL, 0.0, 0.5);
1826 data->TX_filepath = widget;
1827 gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
1828
1829 row++;
1830 label = make_label(_("Encoding:"), 0.0, 0.5);
1831 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
1832 widget = make_label(NULL, 0.0, 0.5);
1833 data->TX_encoding = widget;
1834 gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
1835
1836 row++;
1837 label = make_label(_("Date format:"), 0.0, 0.5);
1838 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
1839 widget = make_label(NULL, 0.0, 0.5);
1840 data->TX_datefmt = widget;
1841 gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
1842
1843 // group :: File content
1844 group_grid = gtk_grid_new ();
1845 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
1846 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
1847 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
1848
1849 label = make_label_group(_("File content"));
1850 gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
1851
1852 row = 1;
1853 label = make_label(_("Content:"), 0.0, 0.5);
1854 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
1855 widget = make_label(NULL, 0.0, 0.5);
1856 data->TX_filedetails = widget;
1857 gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
1858
1859 /*
1860 expander = gtk_expander_new (_("File content"));
1861 gtk_box_pack_start (GTK_BOX (container), expander, TRUE, TRUE, 0);
1862 scrollwin = gtk_scrolled_window_new(NULL,NULL);
1863 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1864 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
1865 widget = gtk_text_view_new ();
1866 gtk_container_add(GTK_CONTAINER(scrollwin), widget);
1867 gtk_container_add(GTK_CONTAINER(expander), scrollwin);
1868 */
1869
1870
1871 gtk_widget_show_all (content_grid);
1872
1873 gtk_assistant_append_page (GTK_ASSISTANT (assistant), content_grid);
1874 //set page type to intro to avoid going back once that point over
1875 gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), content_grid, GTK_ASSISTANT_PAGE_INTRO);
1876 gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), content_grid, _(page_titles[PAGE_PROPERTIES]));
1877
1878 return content_grid;
1879 }
1880
1881
1882 static GtkWidget *
1883 ui_import_panel_account_create (GtkWidget *assistant, struct import_data *data)
1884 {
1885 GtkWidget *content_grid, *group_grid;
1886 GtkWidget *label, *widget, *scrollwin;
1887 gint crow, row;
1888
1889 content_grid = gtk_grid_new();
1890 gtk_grid_set_row_spacing (GTK_GRID (content_grid), SPACING_LARGE);
1891 gtk_orientable_set_orientation(GTK_ORIENTABLE(content_grid), GTK_ORIENTATION_VERTICAL);
1892
1893 crow = 0;
1894 // group :: Title
1895 group_grid = gtk_grid_new ();
1896
1897 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
1898 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
1899 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
1900
1901 //label = make_label_group(_("Title"));
1902 //gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 2, 1);
1903
1904 row = 1;
1905 widget = gtk_image_new ();
1906 data->IM_acc = widget;
1907 gtk_widget_set_valign(widget, GTK_ALIGN_START);
1908 gtk_grid_attach (GTK_GRID (group_grid), widget, 0, row, 1, 1);
1909 label = make_label(NULL, 0, 0.5);
1910 data->LB_acc = label;
1911 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 2, 1);
1912
1913 // group :: Account list
1914 group_grid = gtk_grid_new ();
1915 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
1916 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
1917 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
1918
1919 label = make_label_group(_("Choose the action for accounts"));
1920 gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 1, 1);
1921
1922 row = 1;
1923 scrollwin = gtk_scrolled_window_new(NULL,NULL);
1924 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1925 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
1926 gtk_widget_set_size_request(scrollwin, -1, HB_MINWIDTH_LIST);
1927
1928 widget = ui_acc_affect_listview_new();
1929 data->LV_acc = widget;
1930 gtk_container_add(GTK_CONTAINER(scrollwin), widget);
1931 gtk_widget_set_hexpand(scrollwin, TRUE);
1932 gtk_grid_attach (GTK_GRID (group_grid), scrollwin, 0, row, 1, 1);
1933
1934 row++;
1935 widget = gtk_button_new_with_mnemonic (_("Change _action"));
1936 data->BT_edit = widget;
1937 gtk_widget_set_halign(widget, GTK_ALIGN_START);
1938 gtk_grid_attach (GTK_GRID (group_grid), widget, 0, row, 1, 1);
1939
1940 /* signal and other stuff */
1941 g_signal_connect (G_OBJECT (data->BT_edit), "clicked", G_CALLBACK (ui_import_panel_account_change_action), data);
1942 g_signal_connect (GTK_TREE_VIEW(data->LV_acc), "row-activated", G_CALLBACK (ui_acc_affect_listview_onRowActivated), NULL);
1943
1944 gtk_widget_show_all (content_grid);
1945 gtk_assistant_append_page (GTK_ASSISTANT (assistant), content_grid);
1946 //gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), content_grid, GTK_ASSISTANT_PAGE_INTRO);
1947 gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), content_grid, _(page_titles[PAGE_ACCOUNT]));
1948
1949 return content_grid;
1950 }
1951
1952
1953 static GtkWidget *
1954 ui_import_panel_transaction_create (GtkWidget *assistant, struct import_data *data)
1955 {
1956 GtkWidget *content_grid, *group_grid;
1957 GtkWidget *label, *scrollwin, *widget, *expander;
1958 gint crow, row;
1959
1960 content_grid = gtk_grid_new();
1961 gtk_grid_set_row_spacing (GTK_GRID (content_grid), SPACING_LARGE);
1962 gtk_orientable_set_orientation(GTK_ORIENTABLE(content_grid), GTK_ORIENTATION_VERTICAL);
1963
1964 crow = 0;
1965 // group :: Title
1966 group_grid = gtk_grid_new ();
1967 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
1968 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
1969 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
1970
1971 //label = make_label_group(_("Title"));
1972 //gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
1973
1974 row = 1;
1975 widget = gtk_image_new ();
1976 data->IM_txn = widget;
1977 gtk_widget_set_valign(widget, GTK_ALIGN_START);
1978 gtk_grid_attach (GTK_GRID (group_grid), widget, 0, row, 1, 1);
1979 label = make_label(NULL, 0, 0.5);
1980 data->LB_txn = label;
1981 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 2, 1);
1982
1983 // group :: Transactions to import
1984 group_grid = gtk_grid_new ();
1985 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
1986 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
1987 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
1988
1989 label = make_label_group(_("Choose transactions to import"));
1990 gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 2, 1);
1991
1992 row = 1;
1993 scrollwin = gtk_scrolled_window_new (NULL, NULL);
1994 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
1995 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1996 gtk_widget_set_hexpand(scrollwin, TRUE);
1997 gtk_widget_set_vexpand(scrollwin, TRUE);
1998 widget = create_list_import_transaction(TRUE);
1999 data->imported_ope = widget;
2000 gtk_container_add (GTK_CONTAINER (scrollwin), widget);
2001 gtk_grid_attach (GTK_GRID (group_grid), scrollwin, 0, row, 2, 1);
2002
2003 expander = gtk_expander_new (_("Detail of existing transaction (possible duplicate)"));
2004 data->GR_duplicate = expander;
2005 gtk_grid_attach (GTK_GRID (group_grid), expander, 0, crow++, 2, 1);
2006
2007 group_grid = gtk_grid_new ();
2008 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
2009 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
2010 gtk_container_add (GTK_CONTAINER (expander), group_grid);
2011
2012 row = 0;
2013 scrollwin = gtk_scrolled_window_new (NULL, NULL);
2014 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
2015 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2016 gtk_widget_set_hexpand(scrollwin, TRUE);
2017 //widget = create_list_transaction(LIST_TXN_TYPE_IMPORT, list_imptxn_columns);
2018 widget = create_list_import_transaction(FALSE);
2019 data->duplicat_ope = widget;
2020 gtk_container_add (GTK_CONTAINER (scrollwin), widget);
2021 gtk_widget_set_size_request(scrollwin, -1, HB_MINWIDTH_LIST/2);
2022 gtk_grid_attach (GTK_GRID (group_grid), scrollwin, 0, row, 6, 1);
2023
2024 row++;
2025 label = make_label(_("Date _tolerance:"), 0, 0.5);
2026 gtk_grid_attach (GTK_GRID (group_grid), label, 0, row, 1, 1);
2027
2028 widget = make_numeric(label, 0.0, 14.0);
2029 data->NB_maxgap = widget;
2030 gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 1, 1);
2031
2032 //TRANSLATORS: there is a spinner on the left of this label, and so you have 0....x days of date tolerance
2033 label = make_label(_("days"), 0, 0.5);
2034 gtk_grid_attach (GTK_GRID (group_grid), label, 2, row, 1, 1);
2035
2036 widget = gtk_button_new_with_mnemonic (_("_Refresh"));
2037 gtk_grid_attach (GTK_GRID (group_grid), widget, 3, row, 1, 1);
2038 g_signal_connect (widget, "clicked",
2039 G_CALLBACK (ui_import_panel_transaction_refresh), data);
2040
2041 widget = gtk_image_new_from_icon_name(ICONNAME_INFO, GTK_ICON_SIZE_SMALL_TOOLBAR );
2042 gtk_widget_set_hexpand(widget, FALSE);
2043 gtk_grid_attach (GTK_GRID (group_grid), widget, 4, row, 1, 1);
2044
2045 label = make_label (_(
2046 "The match is done in order: by account, amount and date.\n" \
2047 "A date tolerance of 0 day means an exact match"), 0, 0.5);
2048 gimp_label_set_attributes (GTK_LABEL (label),
2049 PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
2050 -1);
2051 gtk_widget_set_hexpand(label, TRUE);
2052 gtk_grid_attach (GTK_GRID (group_grid), label, 5, row, 1, 1);
2053
2054
2055 gtk_widget_show_all (content_grid);
2056
2057 gtk_assistant_append_page (GTK_ASSISTANT (assistant), content_grid);
2058 // gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), content_grid, GTK_ASSISTANT_PAGE_PROGRESS);
2059 gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), content_grid, _(page_titles[PAGE_TRANSACTION]));
2060
2061 return content_grid;
2062 }
2063
2064
2065 static GtkWidget *
2066 ui_import_panel_confirmation_create(GtkWidget *assistant, struct import_data *data)
2067 {
2068 GtkWidget *vbox, *label, *align, *widget, *table;
2069 gint row;
2070
2071 align = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
2072 gtk_alignment_set_padding(GTK_ALIGNMENT(align), 0, 0, 0, 0);
2073
2074 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_SMALL);
2075 gtk_container_set_border_width (GTK_CONTAINER(vbox), SPACING_MEDIUM);
2076 gtk_container_add(GTK_CONTAINER(align), vbox);
2077
2078 label = make_label(
2079 _("Click \"Apply\" to update your accounts.\n"), 0.5, 0.5);
2080 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
2081
2082 /* the summary */
2083 table = gtk_grid_new ();
2084 gtk_container_set_border_width (GTK_CONTAINER (table), SPACING_SMALL);
2085 gtk_grid_set_row_spacing (GTK_GRID (table), SPACING_SMALL/2);
2086 gtk_grid_set_column_spacing (GTK_GRID (table), SPACING_MEDIUM);
2087 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
2088
2089 row = 0;
2090 label = make_label(_("Accounts"), 0.0, 0.5);
2091 gimp_label_set_attributes(GTK_LABEL(label), PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD, -1);
2092 gtk_grid_attach (GTK_GRID (table), label, 0, row, 3, 1);
2093
2094 /* acc update */
2095 row++;
2096 label = make_label(NULL, 0.0, 0.5);
2097 //gtk_misc_set_padding (GTK_MISC (label), SPACING_SMALL, 0);
2098 gtk_grid_attach (GTK_GRID (table), label, 0, row, 1, 1);
2099 widget = make_label(NULL, 1.0, 0.5);
2100 data->TX_acc_upd = widget;
2101 gtk_grid_attach (GTK_GRID (table), widget, 1, row, 1, 1);
2102 label = make_label(_("to update"), 0.0, 0.5);
2103 gtk_grid_attach (GTK_GRID (table), label, 2, row, 1, 1);
2104
2105 /* acc create */
2106 row++;
2107 widget = make_label(NULL, 1.0, 0.5);
2108 data->TX_acc_new = widget;
2109 gtk_grid_attach (GTK_GRID (table), widget, 1, row, 1, 1);
2110 label = make_label(_("to create"), 0.0, 0.5);
2111 gtk_grid_attach (GTK_GRID (table), label, 2, row, 1, 1);
2112
2113 row++;
2114 label = make_label(_("Transactions"), 0.0, 0.5);
2115 gimp_label_set_attributes(GTK_LABEL(label), PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD, -1);
2116 gtk_grid_attach (GTK_GRID (table), label, 0, row, 3, 1);
2117
2118 /* trn import */
2119 row++;
2120 widget = make_label(NULL, 1.0, 0.5);
2121 data->TX_trn_imp = widget;
2122 gtk_grid_attach (GTK_GRID (table), widget, 1, row, 1, 1);
2123 label = make_label(_("to import"), 0.0, 0.5);
2124 gtk_grid_attach (GTK_GRID (table), label, 2, row, 1, 1);
2125
2126 /* trn reject */
2127 row++;
2128 widget = make_label(NULL, 1.0, 0.5);
2129 data->TX_trn_nop = widget;
2130 gtk_grid_attach (GTK_GRID (table), widget, 1, row, 1, 1);
2131 label = make_label(_("to reject"), 0.0, 0.5);
2132 gtk_grid_attach (GTK_GRID (table), label, 2, row, 1, 1);
2133
2134 /* trn auto-assigned */
2135 row++;
2136 widget = make_label(NULL, 1.0, 0.5);
2137 data->TX_trn_asg = widget;
2138 gtk_grid_attach (GTK_GRID (table), widget, 1, row, 1, 1);
2139 label = make_label(_("auto-assigned"), 0.0, 0.5);
2140 gtk_grid_attach (GTK_GRID (table), label, 2, row, 1, 1);
2141
2142
2143 gtk_widget_show_all (align);
2144
2145 gtk_assistant_append_page (GTK_ASSISTANT (assistant), align);
2146 gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), align, GTK_ASSISTANT_PAGE_CONFIRM);
2147 //gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), label, TRUE);
2148 gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), align, _(page_titles[PAGE_CONFIRM]));
2149
2150 return align;
2151 }
2152
2153
2154 /* starting point of import */
2155 GtkWidget *ui_import_assistant_new (gint filetype)
2156 {
2157 struct import_data *data;
2158 GtkWidget *assistant;
2159 gint w, h, pos;
2160
2161 data = g_malloc0(sizeof(struct import_data));
2162 if(!data) return NULL;
2163
2164 data->filetype = filetype;
2165
2166 assistant = gtk_assistant_new ();
2167 data->assistant = assistant;
2168
2169 //store our window private data
2170 g_object_set_data(G_OBJECT(assistant), "inst_data", (gpointer)data);
2171 //DB( g_print("** \n[import] window=%x, inst_data=%x\n", assistant, data) );
2172
2173
2174 gtk_window_set_modal(GTK_WINDOW (assistant), TRUE);
2175 gtk_window_set_transient_for(GTK_WINDOW(assistant), GTK_WINDOW(GLOBALS->mainwindow));
2176
2177 //set a nice dialog size
2178 gtk_window_get_size(GTK_WINDOW(GLOBALS->mainwindow), &w, &h);
2179 gtk_window_set_default_size (GTK_WINDOW(assistant), w*0.8, h*0.8);
2180
2181
2182 pos = 0;
2183 data->pages[pos++] = ui_import_panel_welcome_create (assistant, data);
2184 data->pages[pos++] = ui_import_panel_filechooser_create (assistant, data);
2185 data->pages[pos++] = ui_import_panel_import_create (assistant, data);
2186 data->pages[pos++] = ui_import_panel_properties_create (assistant, data);
2187 data->pages[pos++] = ui_import_panel_account_create (assistant, data);
2188 data->pages[pos++] = ui_import_panel_transaction_create (assistant, data);
2189 data->pages[pos++] = ui_import_panel_confirmation_create (assistant, data);
2190
2191 gtk_assistant_set_forward_page_func(GTK_ASSISTANT(assistant), ui_import_assistant_forward_page_func, data, NULL);
2192
2193 //setup
2194
2195 ui_import_panel_filechooser_selection_changed(assistant, data);
2196
2197 //connect all our signals
2198 //g_signal_connect (window, "delete-event", G_CALLBACK (hbfile_dispose), (gpointer)data);
2199
2200 g_signal_connect (G_OBJECT (assistant), "cancel", G_CALLBACK (ui_import_assistant_close_cancel), assistant);
2201
2202 g_signal_connect (G_OBJECT (assistant), "close", G_CALLBACK (ui_import_assistant_close_cancel), assistant);
2203
2204 g_signal_connect (G_OBJECT (assistant), "apply", G_CALLBACK (ui_import_assistant_apply), NULL);
2205
2206 g_signal_connect (G_OBJECT (assistant), "prepare", G_CALLBACK (ui_import_assistant_prepare), NULL);
2207
2208 g_signal_connect (G_OBJECT (data->filechooser), "selection-changed",
2209 G_CALLBACK (ui_import_panel_filechooser_selection_changed), (gpointer)data);
2210
2211 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data->imported_ope)), "changed",
2212 G_CALLBACK (ui_import_panel_transaction_fill_same), NULL);
2213
2214 gtk_widget_show (assistant);
2215
2216 gtk_assistant_set_page_complete (GTK_ASSISTANT(assistant), data->pages[PAGE_WELCOME], TRUE );
2217 gtk_assistant_set_current_page(GTK_ASSISTANT(assistant), PAGE_SELECTFILE);
2218
2219 return assistant;
2220 }
2221
2222
2223
2224
This page took 0.189756 seconds and 5 git commands to generate.