/* HomeBank -- Free, easy, personal accounting for everyone.
* Copyright (C) 1995-2019 Maxime DOYEN
*
* This file is part of HomeBank.
*
* HomeBank is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* HomeBank is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "homebank.h"
#include "hb-import.h"
#include "ui-assist-import.h"
#include "dsp-mainwindow.h"
#include "list-operation.h"
/****************************************************************************/
/* Debug macros */
/****************************************************************************/
#define MYDEBUG 0
#if MYDEBUG
#define DB(x) (x);
#else
#define DB(x);
#endif
/* our global datas */
extern struct HomeBank *GLOBALS;
extern struct Preferences *PREFS;
extern gchar *CYA_IMPORT_DATEORDER[];
extern gchar *CYA_IMPORT_OFXNAME[];
extern gchar *CYA_IMPORT_OFXMEMO[];
static void ui_import_page_filechooser_eval(GtkWidget *widget, gpointer user_data);
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
#if MYDEBUG == 1
static void list_txn_cell_data_function_debug (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
GenTxn *gentxn;
gchar *text;
gtk_tree_model_get(model, iter,
LST_GENTXN_POINTER, &gentxn,
-1);
text = g_strdup_printf("%d %d > %d", gentxn->is_imp_similar, gentxn->is_dst_similar, gentxn->to_import);
g_object_set(renderer,
"text", text,
NULL);
g_free(text);
}
#endif
static void list_txn_cell_data_function_toggle (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
GenTxn *gentxn;
gtk_tree_model_get(model, iter,
LST_GENTXN_POINTER, &gentxn,
-1);
g_object_set(renderer, "active", gentxn->to_import, NULL);
}
static void list_txn_cell_data_function_warning (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
GenTxn *gentxn;
gchar *iconname = NULL;
// get the transaction
gtk_tree_model_get(model, iter,
LST_GENTXN_POINTER, &gentxn,
-1);
//iconname = ( gentxn->julian == 0 ) ? ICONNAME_WARNING : NULL;
//if(iconname == NULL)
iconname = ( gentxn->is_dst_similar || gentxn->is_imp_similar ) ? ICONNAME_HB_OPE_SIMILAR : NULL;
g_object_set(renderer, "icon-name", iconname, NULL);
}
static void list_txn_cell_data_function_error (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
GenTxn *gentxn;
gchar *iconname = NULL;
// get the transaction
gtk_tree_model_get(model, iter,
LST_GENTXN_POINTER, &gentxn,
-1);
iconname = ( gentxn->julian == 0 ) ? ICONNAME_ERROR : NULL;
g_object_set(renderer, "icon-name", iconname, NULL);
}
static void list_txn_cell_data_function_text (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
gint colid = GPOINTER_TO_INT(user_data);
gchar buf[12];
GDate date;
gchar *text = "";
GenTxn *item;
gtk_tree_model_get(model, iter,
LST_GENTXN_POINTER, &item,
-1);
switch(colid)
{
case LST_DSPOPE_DATE: //date
{
gchar *color = NULL;
if(item->julian > 0)
{
g_date_set_julian(&date, item->julian);
//#1794170 %F is ignored under ms windows
//g_date_strftime (buf, 12-1, "%F", &date);
g_date_strftime (buf, 12-1, "%Y-%m-%d", &date);
text = buf;
}
else
{
text = item->date;
color = PREFS->color_warn;
}
g_object_set(renderer,
"foreground", color,
NULL);
}
//g_object_set(renderer, "text", item->date, NULL);
break;
case LST_DSPOPE_MEMO: //memo
text = item->memo;
break;
case LST_DSPOPE_PAYEE: //payee
text = item->payee;
break;
case LST_DSPOPE_CATEGORY: //category
text = item->category;
break;
}
g_object_set(renderer,
"text", text,
//"scale-set", TRUE,
//"scale", item->to_import ? 1.0 : 0.8,
"strikethrough-set", TRUE,
"strikethrough", item->to_import ? FALSE : TRUE,
NULL);
}
/*
** amount cell function
*/
static void list_txn_cell_data_function_amount (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
GenTxn *item;
gchar formatd_buf[G_ASCII_DTOSTR_BUF_SIZE];
gchar *color;
gtk_tree_model_get(model, iter,
LST_GENTXN_POINTER, &item,
-1);
//todo: we could use digit and currency of target account
//hb_strfnum(buf, G_ASCII_DTOSTR_BUF_SIZE-1, item->amount, GLOBALS->kcur, FALSE);
//hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, ope->amount, GLOBALS->minor);
g_ascii_formatd(formatd_buf, G_ASCII_DTOSTR_BUF_SIZE-1, "%.2f", item->amount);
color = get_normal_color_amount(item->amount);
g_object_set(renderer,
"foreground", color,
"text", formatd_buf,
NULL);
}
static void list_txn_cell_data_function_info (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
GenTxn *item;
gtk_tree_model_get(model, iter,
LST_GENTXN_POINTER, &item,
-1);
switch(GPOINTER_TO_INT(user_data))
{
case 1:
g_object_set(renderer, "icon-name", get_paymode_icon_name(item->paymode), NULL);
break;
case 2:
g_object_set(renderer, "text", item->info, NULL);
break;
}
}
static void list_txn_importfixed_toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer data)
{
GtkTreeModel *model = (GtkTreeModel *)data;
GtkTreeIter iter;
GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
GenTxn *gentxn;
gtk_tree_model_get_iter (model, &iter, path);
gtk_tree_model_get (model, &iter, LST_GENTXN_POINTER, &gentxn, -1);
gentxn->to_import ^= 1;
gtk_tree_path_free (path);
}
static gint list_txn_import_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
{
gint sortcol = GPOINTER_TO_INT(userdata);
gint retval = 0;
GenTxn *gentxn1, *gentxn2;
gtk_tree_model_get(model, a, LST_GENTXN_POINTER, &gentxn1, -1);
gtk_tree_model_get(model, b, LST_GENTXN_POINTER, &gentxn2, -1);
switch(sortcol)
{
case LST_DSPOPE_MEMO:
retval = hb_string_utf8_compare(gentxn1->memo, gentxn2->memo);
break;
case LST_DSPOPE_AMOUNT:
retval = (gentxn1->amount - gentxn2->amount) > 0 ? 1 : -1;
break;
case LST_DSPOPE_PAYEE:
retval = hb_string_utf8_compare(gentxn1->payee, gentxn2->payee);
break;
case LST_DSPOPE_CATEGORY:
retval = hb_string_utf8_compare(gentxn1->category, gentxn2->category);
break;
case LST_DSPOPE_DATE:
default:
retval = gentxn1->julian - gentxn2->julian;
break;
}
return retval;
}
static GtkTreeViewColumn *
list_txn_import_column_text_create(gchar *title, gint sortcolumnid, gpointer user_data)
{
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
renderer = gtk_cell_renderer_text_new ();
/*g_object_set(renderer,
"ellipsize", PANGO_ELLIPSIZE_END,
"ellipsize-set", TRUE,
NULL);*/
if( sortcolumnid == LST_DSPOPE_AMOUNT )
g_object_set(renderer, "xalign", 1.0, NULL);
column = gtk_tree_view_column_new_with_attributes(title, renderer, NULL);
gtk_tree_view_column_set_alignment (column, 0.5);
gtk_tree_view_column_set_sort_column_id (column, sortcolumnid);
if(sortcolumnid == LST_DSPOPE_AMOUNT )
gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_cell_data_function_amount, GINT_TO_POINTER(sortcolumnid), NULL);
else
gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_cell_data_function_text, GINT_TO_POINTER(sortcolumnid), NULL);
return column;
}
static GtkWidget *list_txn_import_create(void)
{
GtkListStore *store;
GtkWidget *treeview;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
/* create list store */
store = gtk_list_store_new(
NUM_LST_GENTXN,
G_TYPE_POINTER
);
//treeview
treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
g_object_unref(store);
gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (treeview), PREFS->grid_lines|GTK_TREE_VIEW_GRID_LINES_VERTICAL);
// debug/import checkbox
column = gtk_tree_view_column_new();
#if MYDEBUG == 1
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start(column, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_cell_data_function_debug, NULL, NULL);
#endif
renderer = gtk_cell_renderer_toggle_new ();
gtk_tree_view_column_pack_start(column, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_cell_data_function_toggle, NULL, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
g_signal_connect (renderer, "toggled", G_CALLBACK (list_txn_importfixed_toggled), store);
// icons
column = gtk_tree_view_column_new();
//gtk_tree_view_column_set_title(column, _("Import ?"));
renderer = gtk_cell_renderer_pixbuf_new ();
//gtk_cell_renderer_set_fixed_size(renderer, 16, -1);
//gtk_cell_renderer_set_fixed_size(renderer, GLOBALS->lst_pixbuf_maxwidth, -1);
gtk_tree_view_column_pack_start(column, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_cell_data_function_warning, NULL, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
// date
column = gtk_tree_view_column_new();
renderer = gtk_cell_renderer_pixbuf_new ();
gtk_tree_view_column_pack_start(column, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_cell_data_function_error, NULL, NULL);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start(column, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_cell_data_function_text, GINT_TO_POINTER(LST_DSPOPE_DATE), NULL);
gtk_tree_view_column_set_title (column, _("Date"));
gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_DATE);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
// memo
column = list_txn_import_column_text_create(_("Memo"), LST_DSPOPE_MEMO, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
// amount
column = list_txn_import_column_text_create(_("Amount"), LST_DSPOPE_AMOUNT, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
// info
column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(column, _("Info"));
renderer = gtk_cell_renderer_pixbuf_new ();
gtk_tree_view_column_pack_start(column, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_cell_data_function_info, GINT_TO_POINTER(1), NULL);
renderer = gtk_cell_renderer_text_new ();
/*g_object_set(renderer,
"ellipsize", PANGO_ELLIPSIZE_END,
"ellipsize-set", TRUE,
NULL);*/
gtk_tree_view_column_pack_start(column, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_cell_data_function_info, GINT_TO_POINTER(2), NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
// payee
column = list_txn_import_column_text_create(_("Payee"), LST_DSPOPE_PAYEE, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
// category
column = list_txn_import_column_text_create(_("Category"), LST_DSPOPE_CATEGORY, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
// empty
column = gtk_tree_view_column_new();
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
//gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), list_txn_import_compare_func, NULL, NULL);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_DATE , list_txn_import_compare_func, GINT_TO_POINTER(LST_DSPOPE_DATE), NULL);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_MEMO , list_txn_import_compare_func, GINT_TO_POINTER(LST_DSPOPE_MEMO), NULL);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_AMOUNT , list_txn_import_compare_func, GINT_TO_POINTER(LST_DSPOPE_AMOUNT), NULL);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_PAYEE , list_txn_import_compare_func, GINT_TO_POINTER(LST_DSPOPE_PAYEE), NULL);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_CATEGORY, list_txn_import_compare_func, GINT_TO_POINTER(LST_DSPOPE_CATEGORY), NULL);
return(treeview);
}
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
static gint ui_genacc_comboboxtext_get_active(GtkWidget *widget)
{
GtkTreeModel *model;
GtkTreeIter iter;
gint key = -1;
g_return_val_if_fail(GTK_IS_COMBO_BOX(widget), key);
if( gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
{
model = gtk_combo_box_get_model (GTK_COMBO_BOX(widget));
gtk_tree_model_get(model, &iter,
LST_GENACC_KEY, &key,
-1);
}
return key;
}
static void ui_genacc_comboboxtext_set_active(GtkWidget *widget, gint active_key)
{
GtkTreeModel *model;
GtkTreeIter iter;
gboolean valid;
gint key;
g_return_if_fail(GTK_IS_COMBO_BOX(widget));
model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
while (valid)
{
gtk_tree_model_get(model, &iter,
LST_GENACC_KEY, &key,
-1);
if(key == active_key)
gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
}
}
static GtkWidget *ui_genacc_comboboxtext_new(struct import_data *data, GtkWidget *label)
{
GtkListStore *store;
GtkCellRenderer *renderer;
GtkWidget *combobox;
GtkTreeIter iter;
GList *lacc, *list;
store = gtk_list_store_new (NUM_LST_GENACC, G_TYPE_STRING, G_TYPE_INT);
combobox = gtk_combo_box_new_with_model (GTK_TREE_MODEL(store));
renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, FALSE);
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(combobox), renderer, "text", LST_GENACC_NAME);
g_object_unref(store);
gtk_list_store_insert_with_values (GTK_LIST_STORE(store), &iter, -1,
LST_GENACC_NAME, _(""),
LST_GENACC_KEY, DST_ACC_GLOBAL,
-1);
gtk_list_store_insert_with_values (GTK_LIST_STORE(store), &iter, -1,
LST_GENACC_NAME, _(""),
LST_GENACC_KEY, DST_ACC_NEW,
-1);
lacc = list = account_glist_sorted(0);
while (list != NULL)
{
Account *item = list->data;
if( !(item->flags & AF_CLOSED) )
{
gtk_list_store_insert_with_values (GTK_LIST_STORE(store), &iter, -1,
LST_GENACC_NAME, item->name,
LST_GENACC_KEY, item->key,
-1);
}
list = g_list_next(list);
}
g_list_free(lacc);
gtk_list_store_insert_with_values (GTK_LIST_STORE(store), &iter, -1,
LST_GENACC_NAME, _(""),
LST_GENACC_KEY, DST_ACC_SKIP,
-1);
gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 0);
if(label)
gtk_label_set_mnemonic_widget (GTK_LABEL(label), combobox);
return combobox;
}
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
enum
{
TARGET_URI_LIST
};
static GtkTargetEntry drop_types[] =
{
{"text/uri-list", 0, TARGET_URI_LIST}
};
static void
list_file_add(GtkWidget *treeview, GenFile *genfile)
{
char *basename;
GtkTreeModel *model;
GtkTreeIter iter;
basename = g_path_get_basename(genfile->filepath);
model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
gtk_list_store_append (GTK_LIST_STORE(model), &iter);
gtk_list_store_set (GTK_LIST_STORE(model), &iter,
LST_GENFILE_POINTER, genfile,
LST_GENFILE_NAME, g_strdup(basename),
-1);
g_free(basename);
}
static void list_file_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x, gint y,
GtkSelectionData *selection_data,
guint info, guint time, GtkWindow *window)
{
struct import_data *data;
gchar **uris, **str;
gchar *newseldata;
gint slen;
if (info != TARGET_URI_LIST)
return;
DB( g_print("\n[ui-treeview] drag_data_received\n") );
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
/* On MS-Windows, it looks like `selection_data->data' is not NULL terminated. */
slen = gtk_selection_data_get_length(selection_data);
newseldata = g_new (gchar, slen + 1);
memcpy (newseldata, gtk_selection_data_get_data(selection_data), slen);
newseldata[slen] = 0;
uris = g_uri_list_extract_uris (newseldata);
ImportContext *ictx = &data->ictx;
str = uris;
for (str = uris; *str; str++)
//if( *str )
{
GError *error = NULL;
gchar *path = g_filename_from_uri (*str, NULL, &error);
if (path)
{
GenFile *genfile;
genfile = da_gen_file_append_from_filename(ictx, path);
if(genfile)
list_file_add(data->LV_file, genfile);
}
else
{
g_warning ("Could not convert uri to local path: %s", error->message);
g_error_free (error);
}
g_free (path);
}
g_strfreev (uris);
g_free(newseldata);
ui_import_page_filechooser_eval(widget, NULL);
}
static void
list_file_valid_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
GenFile *genfile;
gchar *iconname = NULL;
gtk_tree_model_get(model, iter,
LST_GENFILE_POINTER, &genfile,
-1);
iconname = (genfile->filetype == FILETYPE_UNKNOWN) ? ICONNAME_HB_FILE_INVALID : ICONNAME_HB_FILE_VALID;
g_object_set(renderer, "icon-name", iconname, NULL);
}
static GtkWidget *
list_file_new(void)
{
GtkListStore *store;
GtkWidget *treeview;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
// create list store
store = gtk_list_store_new(NUM_LST_FILE,
G_TYPE_POINTER,
G_TYPE_STRING
);
// treeview
treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
g_object_unref(store);
//column: valid
column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(column, _("Valid"));
renderer = gtk_cell_renderer_pixbuf_new ();
//gtk_cell_renderer_set_fixed_size(renderer, 16, -1);
gtk_tree_view_column_pack_start(column, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func(column, renderer, list_file_valid_cell_data_function, NULL, NULL);
gtk_tree_view_column_set_alignment (column, 0.5);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
g_object_set(renderer, "stock-size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
// column: name
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("Name"),
renderer,
"text",
LST_GENFILE_NAME,
NULL);
gtk_tree_view_column_set_sort_column_id (column, LST_GENFILE_NAME);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
// treeviewattribute
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), TRUE);
//gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), ui_acc_listview_compare_func, NULL, NULL);
//gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
gtk_drag_dest_set (GTK_WIDGET (treeview),
GTK_DEST_DEFAULT_ALL,
drop_types,
G_N_ELEMENTS (drop_types),
GDK_ACTION_COPY);
g_signal_connect (G_OBJECT (treeview), "drag-data-received",
G_CALLBACK (list_file_drag_data_received), treeview);
return treeview;
}
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
static void ui_import_page_filechooser_remove_action(GtkWidget *widget, gpointer user_data)
{
struct import_data *data;
ImportContext *ictx;
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreeSelection *selection;
DB( g_print("\n[ui-import] page_filechooser_remove_action\n") );
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
ictx = &data->ictx;
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_file));
//if true there is a selected node
if (gtk_tree_selection_get_selected(selection, &model, &iter))
{
GenFile *genfile;
gtk_tree_model_get(model, &iter, LST_GENFILE_POINTER, &genfile, -1);
//remove genacc & gentxn
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
ictx->gen_lst_file = g_list_remove(ictx->gen_lst_file, genfile);
da_gen_file_free(genfile);
}
ui_import_page_filechooser_eval(widget, NULL);
}
static void ui_import_page_filechooser_add_action(GtkWidget *widget, gpointer user_data)
{
struct import_data *data;
ImportContext *ictx;
GtkWidget *dialog;
GtkFileFilter *filter;
gint res;
DB( g_print("\n[ui-import] page_filechooser_add_action\n") );
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
ictx = &data->ictx;
dialog = gtk_file_chooser_dialog_new ("Open File",
GTK_WINDOW(data->assistant),
GTK_FILE_CHOOSER_ACTION_OPEN,
_("_Cancel"),
GTK_RESPONSE_CANCEL,
_("_Open"),
GTK_RESPONSE_ACCEPT,
NULL);
gtk_window_set_position(GTK_WINDOW(data->assistant), GTK_WIN_POS_CENTER_ON_PARENT);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(dialog), PREFS->path_import);
DB( g_print(" set current folder '%s'\n", PREFS->path_import) );
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("Known files"));
gtk_file_filter_add_pattern (filter, "*.[Qq][Ii][Ff]");
#ifndef NOOFX
gtk_file_filter_add_pattern (filter, "*.[OoQq][Ff][Xx]");
#endif
gtk_file_filter_add_pattern (filter, "*.[Cc][Ss][Vv]");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
//if(data->filetype == FILETYPE_UNKNOWN)
// gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(dialog), filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("QIF files"));
gtk_file_filter_add_pattern (filter, "*.[Qq][Ii][Ff]");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
//if(data->filetype == FILETYPE_QIF)
// gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(dialog), filter);
#ifndef NOOFX
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("OFX/QFX files"));
gtk_file_filter_add_pattern (filter, "*.[OoQq][Ff][Xx]");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
//if(data->filetype == FILETYPE_OFX)
// gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(dialog), filter);
#endif
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("CSV files"));
gtk_file_filter_add_pattern (filter, "*.[Cc][Ss][Vv]");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
//if(data->filetype == FILETYPE_CSV_HB)
// gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(dialog), filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("All files"));
gtk_file_filter_add_pattern (filter, "*");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
res = gtk_dialog_run (GTK_DIALOG (dialog));
if (res == GTK_RESPONSE_ACCEPT)
{
GSList *list;
GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog);
list = gtk_file_chooser_get_filenames(chooser);
while(list)
{
GenFile *genfile;
DB( g_print(" selected '%p'\n", list->data) );
genfile = da_gen_file_append_from_filename(ictx, list->data);
if(genfile)
list_file_add(data->LV_file, genfile);
list = g_slist_next(list);
}
g_slist_free_full (list, g_free);
/* remind folder to preference */
gchar *folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(chooser));
DB( g_print(" store folder '%s'\n", folder) );
g_free(PREFS->path_import);
PREFS->path_import = folder;
}
gtk_widget_destroy (dialog);
ui_import_page_filechooser_eval(widget, NULL);
}
static void ui_import_page_confirmation_fill(struct import_data *data)
{
ImportContext *ictx = &data->ictx;
GList *list;
GString *node;
DB( g_print("\n[ui-import] page_confirmation_fill\n") );
node = g_string_sized_new(255);
list = g_list_first(ictx->gen_lst_acc);
while (list != NULL)
{
GenAcc *genacc = list->data;
gchar *targetname = NULL;
switch( genacc->kacc )
{
case DST_ACC_GLOBAL:
targetname = _("new global account");
break;
case DST_ACC_NEW:
targetname = _("new account");
break;
case DST_ACC_SKIP:
targetname = _("skipped");
break;
default:
{
Account *acc = da_acc_get (genacc->kacc);
if(acc)
targetname = acc->name;
}
break;
}
//line1: title
g_string_append_printf(node, "'%s'\n => '%s'", genacc->name, targetname);
//line2: count
if( genacc->kacc != DST_ACC_SKIP)
{
hb_import_gen_acc_count_txn(ictx, genacc);
g_string_append_printf(node, _(", %d of %d transactions"), genacc->n_txnimp, genacc->n_txnall);
}
g_string_append(node, "\n\n");
list = g_list_next(list);
}
gtk_label_set_markup (GTK_LABEL(data->TX_summary), node->str);
g_string_free(node, TRUE);
}
static gboolean ui_import_page_import_eval(GtkWidget *widget, gpointer user_data)
{
//struct import_data *data;
//ImportContext *ictx;
//gint count;
DB( g_print("\n[ui-import] page_import_eval\n") );
//data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
//ictx = &data->ictx;
//count = g_list_length (ictx->gen_lst_acc);
//DB( g_print(" count=%d (max=%d)\n", count, TXN_MAX_ACCOUNT) );
//if( count <= TXN_MAX_ACCOUNT )
return TRUE;
//return FALSE;
}
static void ui_import_page_filechooser_eval(GtkWidget *widget, gpointer user_data)
{
struct import_data *data;
ImportContext *ictx;
GList *list;
gint count = 0;
DB( g_print("\n[ui-import] page_filechooser_eval\n") );
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
ictx = &data->ictx;
list = g_list_first(ictx->gen_lst_file);
while (list != NULL)
{
GenFile *genfile = list->data;
if(genfile->filetype != FILETYPE_UNKNOWN)
count++;
list = g_list_next(list);
}
gint index = gtk_assistant_get_current_page(GTK_ASSISTANT(data->assistant));
GtkWidget *current_page = gtk_assistant_get_nth_page (GTK_ASSISTANT(data->assistant), index);
gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), current_page, (count > 0) ? TRUE : FALSE);
}
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
static ImpTxnData *ui_import_page_transaction_data_get(GArray *txndata, guint32 idx)
{
//gint i;
/*g_print(" array @%p, len is %d\n", txndata, txndata->len);
for(i=0;ilen;i++)
g_print(" %d %p\n", i, &g_array_index(txndata, ImpTxnData, i) );
g_print(" get idx=%d - %p\n", idx, &g_array_index (txndata, ImpTxnData, idx) );
*/
if( idx <= txndata->len )
return &g_array_index (txndata, ImpTxnData, idx);
return NULL;
}
static void ui_import_page_transaction_cb_fill_same(GtkTreeSelection *treeselection, gpointer user_data)
{
struct import_data *data;
ImpTxnData *txndata;
//ImportContext *ictx;
GtkTreeSelection *selection;
GtkTreeModel *model, *dupmodel;
GtkTreeIter iter, newiter;
GList *tmplist;
GtkWidget *widget;
guint count = 0;
DB( g_print("\n[ui-import] page_transaction_cb_fill_same\n") );
widget = GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection));
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
//ictx = &data->ictx;
gint pageidx = gtk_assistant_get_current_page(GTK_ASSISTANT(data->assistant));
gint acckey = pageidx - (PAGE_IMPORT);
//GenAcc *genacc = da_gen_acc_get_by_key(ictx->gen_lst_acc, acckey);
//txndata = &data->txndata[acckey];
txndata = ui_import_page_transaction_data_get(data->txndata, acckey);
dupmodel = gtk_tree_view_get_model(GTK_TREE_VIEW(txndata->LV_duptxn));
gtk_list_store_clear (GTK_LIST_STORE(dupmodel));
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(txndata->LV_gentxn));
//if true there is a selected node
if (gtk_tree_selection_get_selected(selection, &model, &iter))
{
GenTxn *gentxn;
gtk_tree_model_get(model, &iter, MODEL_TXN_POINTER, &gentxn, -1);
if( gentxn->lst_existing != NULL )
{
tmplist = g_list_first(gentxn->lst_existing);
while (tmplist != NULL)
{
Transaction *tmp = tmplist->data;
/* append to our treeview */
//gtk_list_store_append (GTK_LIST_STORE(dupmodel), &newiter);
//gtk_list_store_set (GTK_LIST_STORE(dupmodel), &newiter,
count++;
gtk_list_store_insert_with_values(GTK_LIST_STORE(dupmodel), &newiter, -1,
MODEL_TXN_POINTER, tmp,
-1);
//DB( g_print(" - fill: %s %.2f %x\n", item->memo, item->amount, (unsigned int)item->same) );
tmplist = g_list_next(tmplist);
}
}
}
gtk_expander_set_expanded (GTK_EXPANDER(txndata->EX_duptxn), (count > 0) ? TRUE : FALSE);
}
static void ui_import_page_transaction_options_get(struct import_data *data)
{
ImpTxnData *txndata;
ImportContext *ictx;
DB( g_print("\n[ui-import] options_get\n") );
ictx = &data->ictx;
gint pageidx = gtk_assistant_get_current_page(GTK_ASSISTANT(data->assistant));
gint accidx = pageidx - (PAGE_IMPORT);
//GenAcc *genacc = g_list_nth_data(ictx->gen_lst_acc, accidx);
//txndata = &data->txndata[accidx];
txndata = ui_import_page_transaction_data_get(data->txndata, accidx);
ictx->opt_dateorder = gtk_combo_box_get_active (GTK_COMBO_BOX(txndata->CY_txn_dateorder));
ictx->opt_daygap = gtk_spin_button_get_value(GTK_SPIN_BUTTON(txndata->NB_txn_daygap));
ictx->opt_ucfirst = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(txndata->CM_txn_ucfirst));
ictx->opt_ofxname = gtk_combo_box_get_active (GTK_COMBO_BOX(txndata->CY_txn_ofxname));
ictx->opt_ofxmemo = gtk_combo_box_get_active (GTK_COMBO_BOX(txndata->CY_txn_ofxmemo));
ictx->opt_qifmemo = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(txndata->CM_txn_qifmemo));
ictx->opt_qifswap = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(txndata->CM_txn_qifswap));
DB( g_print(" datefmt = '%s' (%d)\n", CYA_IMPORT_DATEORDER[ictx->opt_dateorder], ictx->opt_dateorder) );
}
static void ui_import_page_transaction_update(struct import_data *data)
{
ImpTxnData *txndata;
ImportContext *ictx;
gboolean sensitive, visible;
gboolean iscomplete;
GtkTreeModel *model;
DB( g_print("\n[ui-import] page_transaction_update\n") );
ictx = &data->ictx;
gint pageidx = gtk_assistant_get_current_page(GTK_ASSISTANT(data->assistant));
gint acckey = pageidx - (PAGE_IMPORT);
//GenAcc *genacc = g_list_nth_data(ictx->gen_lst_acc, acckey);
GenAcc *genacc = da_gen_acc_get_by_key(ictx->gen_lst_acc, acckey);
//txndata = &data->txndata[acckey];
txndata = ui_import_page_transaction_data_get(data->txndata, acckey);
DB( g_print(" page idx:%d, genacckey:%d genacc:%p, txndata:%p\n", pageidx, acckey, genacc, txndata) );
if(genacc)
{
DB( g_print(" genacc id=%d name='%s'\n dstacc=%d\n", acckey, genacc->name, genacc->kacc ) );
visible = (genacc->is_unamed == TRUE) && (genacc->filetype != FILETYPE_CSV_HB) ? TRUE: FALSE;
hb_widget_visible (txndata->IM_unamed, visible);
sensitive = (genacc->kacc == DST_ACC_SKIP) ? FALSE : TRUE;
DB( g_print(" sensitive=%d\n", sensitive) );
gtk_widget_set_sensitive(txndata->LV_gentxn, sensitive);
gtk_widget_set_sensitive(txndata->EX_duptxn, sensitive);
//todo: disable option button
gtk_widget_set_sensitive(txndata->GR_misc, sensitive);
gtk_widget_set_sensitive(txndata->GR_date, sensitive);
gtk_widget_set_sensitive(txndata->GR_ofx, sensitive);
gtk_widget_set_sensitive(txndata->GR_qif, sensitive);
gtk_widget_set_sensitive(txndata->GR_select, sensitive);
//todo: display a warning if incorrect date
gchar *msg_icon = NULL, *msg_label = NULL;
iscomplete = (genacc->n_txnbaddate > 0) ? FALSE : TRUE;
iscomplete = (genacc->kacc == DST_ACC_SKIP) ? TRUE : iscomplete;
DB( g_print(" nbbaddates=%d, dstacc=%d\n", genacc->n_txnbaddate, genacc->kacc) );
DB( g_print(" iscomplete=%d\n", iscomplete) );
//show/hide invalid date group
visible = FALSE;
if(genacc->n_txnbaddate > 0)
{
visible = TRUE;
DB( g_print(" invalid date detected\n" ) );
msg_icon = ICONNAME_ERROR;
msg_label =
_("Some date cannot be converted. Please try to change the date order to continue.");
}
gtk_image_set_from_icon_name(GTK_IMAGE(txndata->IM_txn), msg_icon, GTK_ICON_SIZE_BUTTON);
gtk_label_set_text(GTK_LABEL(txndata->LB_txn), msg_label);
hb_widget_visible (txndata->GR_msg, visible);
//show/hide duplicate
visible = TRUE;
if( genacc->kacc==DST_ACC_GLOBAL || genacc->kacc==DST_ACC_NEW || genacc->kacc==DST_ACC_SKIP)
visible = FALSE;
hb_widget_visible (txndata->EX_duptxn, visible);
model = gtk_tree_view_get_model(GTK_TREE_VIEW(txndata->LV_gentxn));
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), LST_DSPOPE_DATE, GTK_SORT_ASCENDING);
//gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
//gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
GtkWidget *page = gtk_assistant_get_nth_page (GTK_ASSISTANT(data->assistant), pageidx);
gtk_assistant_set_page_complete(GTK_ASSISTANT(data->assistant), page, iscomplete);
}
}
static void ui_import_page_transaction_cb_account_changed(GtkWidget *widget, gpointer user_data)
{
struct import_data *data;
ImpTxnData *txndata;
ImportContext *ictx;
gint dstacc;
DB( g_print("\n[ui-import] cb_account_changed\n") );
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
ictx = &data->ictx;
gint pageidx = gtk_assistant_get_current_page(GTK_ASSISTANT(data->assistant));
gint acckey = pageidx - (PAGE_IMPORT);
//GenAcc *genacc = g_list_nth_data(ictx->gen_lst_acc, accidx);
GenAcc *genacc = da_gen_acc_get_by_key(ictx->gen_lst_acc, acckey);
//txndata = &data->txndata[acckey];
txndata = ui_import_page_transaction_data_get(data->txndata, acckey);
dstacc = ui_genacc_comboboxtext_get_active (txndata->CY_acc);
genacc->kacc = dstacc;
ui_import_page_transaction_options_get(data);
hb_import_option_apply(ictx, genacc);
hb_import_gen_txn_check_duplicate(ictx, genacc);
hb_import_gen_txn_check_target_similar(ictx, genacc);
genacc->is_dupcheck = TRUE;
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(txndata->LV_gentxn));
ui_import_page_transaction_update(data);
}
static void ui_import_page_transaction_cb_option_changed(GtkWidget *widget, gpointer user_data)
{
struct import_data *data;
ImpTxnData *txndata;
ImportContext *ictx;
DB( g_print("\n[ui-import] cb_option_changed\n") );
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
ictx = &data->ictx;
gint pageidx = gtk_assistant_get_current_page(GTK_ASSISTANT(data->assistant));
gint acckey = pageidx - (PAGE_IMPORT);
//GenAcc *genacc = g_list_nth_data(ictx->gen_lst_acc, accidx);
GenAcc *genacc = da_gen_acc_get_by_key(ictx->gen_lst_acc, acckey);
//txndata = &data->txndata[acckey];
txndata = ui_import_page_transaction_data_get(data->txndata, acckey);
ui_import_page_transaction_options_get(data);
hb_import_option_apply(ictx, genacc);
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(txndata->LV_gentxn));
ui_import_page_transaction_update(data);
}
static void ui_import_page_transaction_fill(struct import_data *data)
{
ImpTxnData *txndata;
ImportContext *ictx = &data->ictx;
GtkWidget *view;
GtkTreeModel *model;
GtkTreeIter iter;
GList *tmplist;
gchar *label = NULL;
gboolean visible;
//gint nbacc;
DB( g_print("\n[ui-import] page_transaction_fill\n") );
//get the account, it will be the account into the glist
//of pagenum - PAGE_IMPORT
//gint pageidx = gtk_assistant_get_current_page(GTK_ASSISTANT(data->assistant));
gint acckey = gtk_assistant_get_current_page(GTK_ASSISTANT(data->assistant)) - (PAGE_IMPORT);
//GenAcc *genacc = g_list_nth_data(ictx->gen_lst_acc, acckey);
GenAcc *genacc = da_gen_acc_get_by_key(ictx->gen_lst_acc, acckey);
//nbacc = g_list_length(ictx->gen_lst_acc);
//txndata = &data->txndata[acckey];
txndata = ui_import_page_transaction_data_get(data->txndata, acckey);
DB( g_print(" genacckey:%d genacc:%p, txndata:%p\n", acckey, genacc, txndata) );
if(genacc)
{
gint count;
DB( g_print(" genacc id=%d name='%s'\n dstacc=%d\n", acckey, genacc->name, genacc->kacc ) );
g_signal_handlers_block_by_func(txndata->CY_acc, G_CALLBACK(ui_import_page_transaction_cb_account_changed), NULL);
ui_genacc_comboboxtext_set_active(txndata->CY_acc, genacc->kacc);
g_signal_handlers_unblock_by_func(txndata->CY_acc, G_CALLBACK(ui_import_page_transaction_cb_account_changed), NULL);
ui_import_page_transaction_options_get(data);
hb_import_option_apply(ictx, genacc);
if( genacc->is_dupcheck == FALSE )
{
hb_import_gen_txn_check_duplicate(ictx, genacc);
hb_import_gen_txn_check_target_similar(ictx, genacc);
genacc->is_dupcheck = TRUE;
}
view = txndata->LV_gentxn;
model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
gtk_list_store_clear (GTK_LIST_STORE(model));
count = 0;
tmplist = g_list_first(ictx->gen_lst_txn);
while (tmplist != NULL)
{
GenTxn *item = tmplist->data;
//todo: chnage this, this should be account
if(item->kacc == genacc->key)
{
// append to our treeview
//gtk_list_store_append (GTK_LIST_STORE(model), &iter);
//gtk_list_store_set (GTK_LIST_STORE(model), &iter,
gtk_list_store_insert_with_values(GTK_LIST_STORE(model), &iter, -1,
LST_GENTXN_POINTER, item,
-1);
DB( g_print(" fill: %s, %d, %s %.2f\n", item->account, item->julian, item->memo, item->amount) );
count++;
}
tmplist = g_list_next(tmplist);
}
//label = g_strdup_printf(_("'%s' - %s"), genacc->name, hb_import_filetype_char_get(genacc));
label = g_strdup_printf(_("Import %s in_to:"), genacc->is_unamed ? _("this file") : _("this account") );
gtk_label_set_markup_with_mnemonic (GTK_LABEL(txndata->LB_acc_title), label);
g_free(label);
//build tooltip
GenFile *genfile = da_gen_file_get (ictx->gen_lst_file, genacc->kfile);
label = g_strdup_printf(_("Name: %s\nNumber: %s\nFile: %s\nEncoding: %s"), genacc->name, genacc->number, genfile->filepath, genfile->encoding);
gtk_widget_set_tooltip_text (GTK_WIDGET(txndata->LB_acc_title), label);
g_free(label);
//label = g_strdup_printf(_("Account %d of %d"), acckey+1, nbacc);
//gtk_label_set_markup (GTK_LABEL(txndata->LB_acc_count), label);
//g_free(label);
label = g_strdup_printf(_("%d transactions"), count);
gtk_label_set_markup (GTK_LABEL(txndata->LB_txn_title), label);
g_free(label);
visible = (genacc->filetype == FILETYPE_OFX) ? FALSE : TRUE;
hb_widget_visible(GTK_WIDGET(txndata->GR_date), visible);
visible = (genacc->filetype == FILETYPE_OFX) ? TRUE : FALSE;
hb_widget_visible(GTK_WIDGET(txndata->GR_ofx), visible);
visible = (genacc->filetype == FILETYPE_QIF) ? TRUE : FALSE;
hb_widget_visible(GTK_WIDGET(txndata->GR_qif), visible);
gtk_stack_set_visible_child_name(GTK_STACK(txndata->ST_stack), visible ? "QIF" : "OFX");
}
}
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
static void
ui_import_page_intro_cb_dontshow(GtkWidget *widget, gpointer user_data)
{
PREFS->dtex_nointro = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget));
}
static GtkWidget *
ui_import_page_intro_create(GtkWidget *assistant, struct import_data *data)
{
GtkWidget *mainbox, *label, *widget;
mainbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_SMALL);
gtk_widget_set_halign(mainbox, GTK_ALIGN_CENTER);
gtk_widget_set_valign(mainbox, GTK_ALIGN_CENTER);
label = make_label(_("Import transactions from bank or credit card"), 0, 0);
gimp_label_set_attributes(GTK_LABEL(label),
PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
PANGO_ATTR_SCALE, PANGO_SCALE_LARGE,
-1);
gtk_box_pack_start (GTK_BOX (mainbox), label, FALSE, FALSE, SPACING_SMALL);
label = make_label(
_("With this assistant you will be guided through the process of importing one or several\n" \
"downloaded statements from your bank or credit card, in the following formats:"), 0, 0);
gtk_box_pack_start (GTK_BOX (mainbox), label, FALSE, FALSE, SPACING_SMALL);
label = gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(label),
_("Recommended: .OFX or .QFX\n" \
"(Sometimes named Money™ or Quicken™)\n" \
"Supported: .QIF\n" \
"(Common Quicken™ file)\n" \
"Advanced users only: .CSV\n"
"(format is specific to HomeBank, see the documentation)"));
/* supported format */
/*label = make_label(
_("HomeBank can import files in the following formats:\n" \
"- QIF\n" \
"- OFX/QFX (optional at compilation time)\n" \
"- CSV (format is specific to HomeBank, see the documentation)\n" \
), 0.0, 0.0);*/
gtk_box_pack_start (GTK_BOX (mainbox), label, FALSE, FALSE, SPACING_SMALL);
label = make_label(
_("No changes will be made until you click \"Apply\" at the end of this assistant."), 0., 0.0);
gtk_box_pack_start (GTK_BOX (mainbox), label, FALSE, FALSE, SPACING_SMALL);
widget = gtk_check_button_new_with_mnemonic (_("Don't show this again"));
data->CM_dsta = widget;
gtk_box_pack_end (GTK_BOX (mainbox), widget, FALSE, FALSE, SPACING_SMALL);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(data->CM_dsta), PREFS->dtex_nointro);
gtk_widget_show_all (mainbox);
g_signal_connect (data->CM_dsta, "toggled", G_CALLBACK (ui_import_page_intro_cb_dontshow), data);
return mainbox;
}
static void ui_import_page_filechooser_update(GtkWidget *widget, gpointer user_data)
{
struct import_data *data;
GtkTreeSelection *selection;
gboolean sensitive;
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_file));
gint count = gtk_tree_selection_count_selected_rows(selection);
sensitive = (count > 0) ? TRUE : FALSE;
gtk_widget_set_sensitive(data->BT_file_remove, sensitive);
//gtk_widget_set_sensitive(data->BT_merge, sensitive);
//gtk_widget_set_sensitive(data->BT_delete, sensitive);
}
static void ui_import_page_filechooser_selection(GtkTreeSelection *treeselection, gpointer user_data)
{
ui_import_page_filechooser_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), NULL);
}
static GtkWidget *
ui_import_page_filechooser_create (GtkWidget *assistant, struct import_data *data)
{
GtkWidget *mainbox, *vbox, *hbox, *widget, *label, *scrollwin, *tbar;
GtkToolItem *toolitem;
mainbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_SMALL);
//gtk_container_set_border_width (GTK_CONTAINER(vbox), SPACING_SMALL);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start (GTK_BOX (mainbox), hbox, FALSE, FALSE, SPACING_SMALL);
widget = gtk_image_new_from_icon_name (ICONNAME_INFO, GTK_ICON_SIZE_LARGE_TOOLBAR);
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, SPACING_SMALL);
label = make_label(
_("Drag&Drop one or several files to import.\n" \
"You can also use the add/remove buttons of the list.")
, 0., 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, SPACING_SMALL);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (mainbox), vbox, TRUE, TRUE, 0);
//list
scrollwin = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_widget_set_hexpand(scrollwin, TRUE);
gtk_widget_set_vexpand(scrollwin, TRUE);
widget = list_file_new();
data->LV_file = widget;
gtk_container_add (GTK_CONTAINER (scrollwin), widget);
//gtk_grid_attach (GTK_GRID (group_grid), scrollwin, 0, row, 2, 1);
gtk_box_pack_start (GTK_BOX (vbox), scrollwin, TRUE, TRUE, 0);
//list toolbar
tbar = gtk_toolbar_new();
gtk_toolbar_set_icon_size (GTK_TOOLBAR(tbar), GTK_ICON_SIZE_MENU);
gtk_toolbar_set_style(GTK_TOOLBAR(tbar), GTK_TOOLBAR_ICONS);
gtk_style_context_add_class (gtk_widget_get_style_context (tbar), GTK_STYLE_CLASS_INLINE_TOOLBAR);
gtk_box_pack_start (GTK_BOX (vbox), tbar, FALSE, FALSE, 0);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
toolitem = gtk_tool_item_new();
gtk_container_add (GTK_CONTAINER(toolitem), hbox);
gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
widget = make_image_button(ICONNAME_LIST_ADD, NULL);
data->BT_file_add = widget;
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
widget = make_image_button(ICONNAME_LIST_REMOVE, NULL);
data->BT_file_remove = widget;
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
gtk_widget_show_all (mainbox);
ui_import_page_filechooser_update(assistant, NULL);
g_signal_connect (G_OBJECT (data->BT_file_add), "clicked", G_CALLBACK (ui_import_page_filechooser_add_action), data);
g_signal_connect (G_OBJECT (data->BT_file_remove), "clicked", G_CALLBACK (ui_import_page_filechooser_remove_action), data);
g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_file)), "changed", G_CALLBACK (ui_import_page_filechooser_selection), NULL);
return mainbox;
}
static GtkWidget *
ui_import_page_import_create (GtkWidget *assistant, struct import_data *data)
{
GtkWidget *mainbox;
GtkWidget *label, *widget;
gchar *txt;
mainbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
//gtk_widget_set_halign(mainbox, GTK_ALIGN_CENTER);
//gtk_widget_set_valign(mainbox, GTK_ALIGN_CENTER);
widget = gtk_image_new_from_icon_name(ICONNAME_ERROR, GTK_ICON_SIZE_DIALOG );
gtk_box_pack_start (GTK_BOX (mainbox), widget, FALSE, FALSE, 0);
txt = _("There is too much account in the files you choosed,\n" \
"please use the back button to select less files.");
label = gtk_label_new(txt);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (mainbox), label, FALSE, FALSE, 0);
gtk_widget_show_all (mainbox);
return mainbox;
}
static gboolean
ui_import_page_transaction_cb_activate_link (GtkWidget *label, const gchar *uri, gpointer user_data)
{
GtkTreeModel *model;
GtkTreeIter iter;
gboolean valid;
GenTxn *gentxn;
g_return_val_if_fail(GTK_IS_TREE_VIEW(user_data), TRUE);
model = gtk_tree_view_get_model(GTK_TREE_VIEW(user_data));
DB( g_print(" comboboxlink '%s' \n", uri) );
if (g_strcmp0 (uri, "all") == 0)
{
valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
while (valid)
{
gtk_tree_model_get(model, &iter,
LST_GENTXN_POINTER, &gentxn,
-1);
gentxn->to_import = TRUE;
valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
}
}
else
if (g_strcmp0 (uri, "non") == 0)
{
valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
while (valid)
{
gtk_tree_model_get(model, &iter,
LST_GENTXN_POINTER, &gentxn,
-1);
gentxn->to_import = FALSE;
valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
}
}
else
if (g_strcmp0 (uri, "inv") == 0)
{
valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
while (valid)
{
gtk_tree_model_get(model, &iter,
LST_GENTXN_POINTER, &gentxn,
-1);
gentxn->to_import ^= TRUE;
valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
}
}
gtk_widget_queue_draw(GTK_WIDGET(user_data));
return TRUE;
}
static GtkWidget *
ui_import_page_transaction_create (GtkWidget *assistant, gint idx, struct import_data *data)
{
ImpTxnData *txndata;
GtkWidget *table, *box, *group, *stack;
GtkWidget *label, *scrollwin, *expander, *widget;
ImpTxnData tmp;
gint row;
//txndata = &data->txndata[idx];
memset(&tmp, 0, sizeof(ImpTxnData));
g_array_insert_vals(data->txndata, idx, &tmp, 1);
txndata = ui_import_page_transaction_data_get(data->txndata, idx);
DB( g_print(" txndat=%p\n", txndata) );
if(!txndata)
return NULL;
table = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (table), SPACING_SMALL);
gtk_grid_set_column_spacing (GTK_GRID (table), SPACING_MEDIUM);
row = 0;
//line 1 left
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
//gtk_widget_set_hexpand(box, TRUE);
gtk_grid_attach (GTK_GRID(table), box, 0, row, 1, 1);
// XXX (type) + accname
label = make_label(NULL, 0.0, 0.5);
txndata->LB_acc_title = label;
//gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_LARGE, -1);
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
widget = ui_genacc_comboboxtext_new(data, label);
//gtk_widget_set_hexpand(widget, TRUE);
txndata->CY_acc = widget;
gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
widget = gtk_image_new_from_icon_name(ICONNAME_WARNING, GTK_ICON_SIZE_SMALL_TOOLBAR);
txndata->IM_unamed = widget;
gtk_widget_set_tooltip_text (widget, _("Target account identification by name or number failed."));
gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
//line 1 right
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
//gtk_widget_set_hexpand(box, TRUE);
gtk_grid_attach (GTK_GRID(table), box, 1, row, 1, 1);
//csv options
group = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
txndata->GR_date = group;
gtk_box_pack_start (GTK_BOX(box), group, FALSE, FALSE, 0);
label = make_label(_("Date order:"), 0, 0.5);
gtk_box_pack_start (GTK_BOX(group), label, FALSE, FALSE, 0);
widget = make_cycle(label, CYA_IMPORT_DATEORDER);
txndata->CY_txn_dateorder = widget;
gtk_box_pack_start (GTK_BOX(group), widget, FALSE, FALSE, 0);
stack = gtk_stack_new();
gtk_box_pack_start (GTK_BOX(box), stack, FALSE, FALSE, 0);
txndata->ST_stack= stack;
//qif options
group = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
txndata->GR_qif = group;
//gtk_box_pack_start (GTK_BOX(box), group, FALSE, FALSE, 0);
gtk_stack_add_named(GTK_STACK(stack), group, "QIF");
widget = gtk_check_button_new_with_mnemonic (_("_Import memos"));
txndata->CM_txn_qifmemo = widget;
gtk_box_pack_start (GTK_BOX(group), widget, FALSE, FALSE, 0);
widget = gtk_check_button_new_with_mnemonic (_("_Swap memos with payees"));
txndata->CM_txn_qifswap = widget;
gtk_box_pack_start (GTK_BOX(group), widget, FALSE, FALSE, 0);
//ofx options
group = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
txndata->GR_ofx = group;
//gtk_box_pack_start (GTK_BOX(box), group, FALSE, FALSE, 0);
gtk_stack_add_named(GTK_STACK(stack), group, "OFX");
label = make_label(_("OFX _Name:"), 0, 0.5);
gtk_box_pack_start (GTK_BOX(group), label, FALSE, FALSE, 0);
widget = make_cycle(label, CYA_IMPORT_OFXNAME);
txndata->CY_txn_ofxname = widget;
gtk_box_pack_start (GTK_BOX(group), widget, FALSE, FALSE, 0);
label = make_label(_("OFX _Memo:"), 0, 0.5);
gtk_box_pack_start (GTK_BOX(group), label, FALSE, FALSE, 0);
widget = make_cycle(label, CYA_IMPORT_OFXMEMO);
txndata->CY_txn_ofxmemo = widget;
gtk_box_pack_start (GTK_BOX(group), widget, FALSE, FALSE, 0);
// n transaction ...
row++;
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
//gtk_widget_set_hexpand(box, TRUE);
gtk_grid_attach (GTK_GRID(table), box, 0, row, 1, 1);
group = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
txndata->GR_select = group;
gtk_box_pack_start (GTK_BOX (box), group, FALSE, FALSE, 0);
label = make_label (_("Select:"), 0, 0.5);
gtk_box_pack_start (GTK_BOX (group), label, FALSE, FALSE, 0);
label = make_clicklabel("all", _("All"));
txndata->BT_all= label;
gtk_box_pack_start (GTK_BOX (group), label, FALSE, FALSE, 0);
label = make_clicklabel("non", _("None"));
txndata->BT_non = label;
gtk_box_pack_start (GTK_BOX (group), label, FALSE, FALSE, 0);
label = make_clicklabel("inv", _("Invert"));
txndata->BT_inv = label;
gtk_box_pack_start (GTK_BOX (group), label, FALSE, FALSE, 0);
label = make_label(NULL, 0.0, 0.0);
txndata->LB_txn_title = label;
gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (group), label, FALSE, FALSE, 0);
// import into
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
gtk_grid_attach (GTK_GRID(table), box, 1, row, 1, 1);
group = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
txndata->GR_misc = group;
gtk_box_pack_start (GTK_BOX (box), group, FALSE, FALSE, 0);
widget = gtk_check_button_new_with_mnemonic (_("Sentence _case memo/payee"));
txndata->CM_txn_ucfirst = widget;
gtk_box_pack_start (GTK_BOX(group), widget, FALSE, FALSE, 0);
// error messages
row++;
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
txndata->GR_msg = box;
//gtk_widget_set_hexpand(box, TRUE);
gtk_grid_attach (GTK_GRID(table), box, 0, row, 2, 1);
widget = gtk_image_new ();
txndata->IM_txn = widget;
gtk_widget_set_valign(widget, GTK_ALIGN_START);
gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
label = make_label(NULL, 0.0, 0.5);
txndata->LB_txn = label;
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
row++;
scrollwin = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
widget = list_txn_import_create();
txndata->LV_gentxn = widget;
gtk_widget_set_hexpand(scrollwin, TRUE);
gtk_widget_set_vexpand(scrollwin, TRUE);
gtk_container_add (GTK_CONTAINER (scrollwin), widget);
gtk_grid_attach (GTK_GRID(table), scrollwin, 0, row, 2, 1);
//duplicate
row++;
expander = gtk_expander_new (_("Similar transaction in target account (possible duplicate)"));
txndata->EX_duptxn = expander;
//gtk_widget_set_hexpand(expander, TRUE);
gtk_grid_attach (GTK_GRID(table), expander, 0, row, 2, 1);
group = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (group), SPACING_SMALL);
gtk_grid_set_column_spacing (GTK_GRID (group), SPACING_SMALL);
gtk_container_add (GTK_CONTAINER (expander), group);
row = 0;
scrollwin = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_widget_set_hexpand(scrollwin, TRUE);
//widget = create_list_transaction(LIST_TXN_TYPE_DETAIL, PREFS->lst_ope_columns);
widget = create_list_transaction(LIST_TXN_TYPE_DETAIL, PREFS->lst_impope_columns);
txndata->LV_duptxn = widget;
gtk_container_add (GTK_CONTAINER (scrollwin), widget);
gtk_widget_set_size_request(scrollwin, -1, HB_MINWIDTH_LIST/2);
gtk_grid_attach (GTK_GRID (group), scrollwin, 0, row, 5, 1);
row++;
label = make_label(_("Date _gap:"), 0, 0.5);
gtk_grid_attach (GTK_GRID (group), label, 0, row, 1, 1);
widget = make_numeric(label, 0.0, HB_DATE_MAX_GAP);
txndata->NB_txn_daygap = widget;
gtk_grid_attach (GTK_GRID (group), widget, 1, row, 1, 1);
//TRANSLATORS: there is a spinner on the left of this label, and so you have 0....x days of date tolerance
label = make_label(_("days"), 0, 0.5);
gtk_grid_attach (GTK_GRID (group), label, 2, row, 1, 1);
widget = gtk_image_new_from_icon_name(ICONNAME_INFO, GTK_ICON_SIZE_SMALL_TOOLBAR );
gtk_widget_set_hexpand(widget, FALSE);
gtk_grid_attach (GTK_GRID (group), widget, 3, row, 1, 1);
label = make_label (_(
"The match is done in order: by account, amount and date.\n" \
"A date tolerance of 0 day means an exact match"), 0, 0.5);
gimp_label_set_attributes (GTK_LABEL (label),
PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
-1);
gtk_widget_set_hexpand(label, TRUE);
gtk_grid_attach (GTK_GRID (group), label, 4, row, 1, 1);
// init ofx/qfx option to move
gtk_combo_box_set_active(GTK_COMBO_BOX(txndata->CY_txn_dateorder), PREFS->dtex_datefmt);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(txndata->CM_txn_ucfirst), PREFS->dtex_ucfirst);
gtk_combo_box_set_active(GTK_COMBO_BOX(txndata->CY_txn_ofxname), PREFS->dtex_ofxname);
gtk_combo_box_set_active(GTK_COMBO_BOX(txndata->CY_txn_ofxmemo), PREFS->dtex_ofxmemo);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(txndata->CM_txn_qifmemo), PREFS->dtex_qifmemo);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(txndata->CM_txn_qifswap), PREFS->dtex_qifswap);
gtk_widget_show_all (table);
gtk_widget_hide(txndata->GR_qif);
gtk_widget_hide(txndata->GR_ofx);
g_signal_connect (txndata->BT_all, "activate-link", G_CALLBACK (ui_import_page_transaction_cb_activate_link), txndata->LV_gentxn);
g_signal_connect (txndata->BT_non, "activate-link", G_CALLBACK (ui_import_page_transaction_cb_activate_link), txndata->LV_gentxn);
g_signal_connect (txndata->BT_inv, "activate-link", G_CALLBACK (ui_import_page_transaction_cb_activate_link), txndata->LV_gentxn);
g_signal_connect (txndata->CY_acc , "changed", G_CALLBACK (ui_import_page_transaction_cb_account_changed), data);
g_signal_connect (txndata->CY_txn_dateorder, "changed", G_CALLBACK (ui_import_page_transaction_cb_account_changed), data);
g_signal_connect (txndata->NB_txn_daygap , "value-changed", G_CALLBACK (ui_import_page_transaction_cb_account_changed), data);
g_signal_connect (txndata->CY_txn_ofxname , "changed", G_CALLBACK (ui_import_page_transaction_cb_option_changed), data);
g_signal_connect (txndata->CY_txn_ofxmemo , "changed", G_CALLBACK (ui_import_page_transaction_cb_option_changed), data);
g_signal_connect (txndata->CM_txn_qifmemo, "toggled", G_CALLBACK (ui_import_page_transaction_cb_option_changed), data);
g_signal_connect (txndata->CM_txn_qifswap, "toggled", G_CALLBACK (ui_import_page_transaction_cb_option_changed), data);
g_signal_connect (txndata->CM_txn_ucfirst, "toggled", G_CALLBACK (ui_import_page_transaction_cb_option_changed), data);
g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(txndata->LV_gentxn)), "changed",
G_CALLBACK (ui_import_page_transaction_cb_fill_same), NULL);
return table;
}
static GtkWidget *
ui_import_page_confirmation_create(GtkWidget *assistant, struct import_data *data)
{
GtkWidget *mainbox, *label, *widget, *scrollwin;
mainbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_SMALL);
//gtk_container_set_border_width (GTK_CONTAINER(mainbox), SPACING_SMALL);
scrollwin = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_NONE);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_widget_set_hexpand(scrollwin, TRUE);
gtk_widget_set_vexpand(scrollwin, TRUE);
widget = gtk_label_new (NULL);
data->TX_summary = widget;
gtk_container_add (GTK_CONTAINER (scrollwin), widget);
gtk_box_pack_start (GTK_BOX (mainbox), scrollwin, TRUE, TRUE, 0);
label = make_label(
_("Click \"Apply\" to update your accounts.\n"), 0.5, 0.5);
gtk_box_pack_start (GTK_BOX (mainbox), label, FALSE, FALSE, 0);
gtk_widget_set_margin_top(GTK_WIDGET(label), SPACING_SMALL);
gtk_widget_set_margin_bottom(GTK_WIDGET(label), SPACING_SMALL);
gtk_widget_show_all (mainbox);
return mainbox;
}
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/**
* ui_import_assistant_forward_page_func:
*
* define the page to be called when the user forward
*
* Return value: the page number
*
*/
/*static gint
ui_import_assistant_forward_page_func(gint current_page, gpointer func_data)
{
struct import_data *data;
GtkWidget *page;
gint next_page;
data = func_data;
DB( g_print("---------------------------\n") );
DB( g_print("\n[ui-import] forward page func\n") );
page = gtk_assistant_get_nth_page(GTK_ASSISTANT(data->assistant), current_page);
DB( g_print(" -> current: %d %s\n", current_page, gtk_assistant_get_page_title(GTK_ASSISTANT(data->assistant), page) ) );
#if MYDEBUG == 1
struct import_data *data = func_data;
gint i
for(i=0;iassistant), data->pages[i]),
page_titles[i]
);
#endif
next_page = current_page + 1;
switch(current_page)
{
//case PAGE_IMPORT:
// if no new account, skip the account page
//if(ictx->nb_new_acc == 0)
// next_page = PAGE_TRANSACTION;
//break;
}
page = gtk_assistant_get_nth_page(GTK_ASSISTANT(data->assistant), next_page);
DB( g_print(" -> next: %d %s\n", next_page, gtk_assistant_get_page_title(GTK_ASSISTANT(data->assistant), page) ) );
return next_page;
}*/
static void
ui_import_assistant_prepare (GtkWidget *widget, GtkWidget *page, gpointer user_data)
{
struct import_data *data;
ImportContext *ictx;
gint current_page, n_pages;
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
ictx = &data->ictx;
current_page = gtk_assistant_get_current_page (GTK_ASSISTANT(data->assistant));
n_pages = gtk_assistant_get_n_pages (GTK_ASSISTANT(data->assistant));
DB( g_print("\n--------\n[ui-import] prepare \n page %d of %d\n", current_page, n_pages) );
switch( current_page )
{
case PAGE_WELCOME:
DB( g_print("\n #1 intro\n") );
gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, TRUE);
break;
case PAGE_FILES:
DB( g_print("\n #2 file choose\n") );
gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, FALSE);
//open the file add if no file
if( gtk_tree_model_iter_n_children(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_file)), NULL) == 0 )
{
//g_signal_emit_by_name(data->BT_file_add, "clicked", NULL);
ui_import_page_filechooser_add_action(data->BT_file_add, NULL);
}
// the page complete is contextual in ui_import_page_filechooser_selection_changed
// check is something valid :: count total rows
ui_import_page_filechooser_eval(widget, user_data);
break;
case PAGE_IMPORT:
DB( g_print("\n #3 real import\n") );
gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, FALSE);
//todo: more test needed here
//clean any previous txn page
/*for(i=(n_pages-1);i>=PAGE_IMPORT+1;i--)
{
GtkWidget *page = gtk_assistant_get_nth_page (GTK_ASSISTANT(data->assistant), i);
gboolean isacc;
if( page != NULL )
{
isacc = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(page), "pgacc"));
DB( g_print(" %d is acc: %d\n", i, isacc) );
if( isacc )
{
gtk_assistant_remove_page(GTK_ASSISTANT(data->assistant), i);
gtk_widget_destroy (page);
}
}
}*/
hb_import_load_all(&data->ictx);
//add 1 page per account
gint key, nbacc;
nbacc = g_list_length (ictx->gen_lst_acc);
if(data->txndata)
{
g_array_free(data->txndata, TRUE);
data->txndata = NULL;
}
data->txndata = g_array_sized_new(FALSE, TRUE, sizeof(ImpTxnData), nbacc);
//#1820618 patch for glib < 2.58 https://gitlab.gnome.org/GNOME/glib/issues/1374
if( glib_minor_version < 58 )
{
g_array_set_size(data->txndata, nbacc);
}
DB( g_print(" accnb=%d @%p\n", nbacc, data->txndata) );
//debug
//_import_context_debug_acc_list(&data->ictx);
//if(nbacc < TXN_MAX_ACCOUNT)
//{
for(key=1;keygen_lst_acc, key);
DB( g_print(" create page txn for '%s' '%s' at page %d\n", genacc->name, genacc->number, PAGE_IMPORT + key) );
page = ui_import_page_transaction_create (data->assistant, key, data);
//g_object_set_data(G_OBJECT(page), "pgacc", (gpointer)TRUE);
gtk_widget_show_all (page);
gtk_assistant_insert_page (GTK_ASSISTANT (data->assistant), page, PAGE_IMPORT + key);
//gtk_assistant_set_page_title (GTK_ASSISTANT (data->assistant), page, _("Transaction"));
//gtk_assistant_set_page_title (GTK_ASSISTANT (data->assistant), page, genacc->name);
title = g_strdup_printf("%s %d", (!genacc->is_unamed) ? _("Account") : _("Unknown"), key );
gtk_assistant_set_page_title (GTK_ASSISTANT (data->assistant), page, title);
g_free(title);
}
//}
// obsolete ??
if( ui_import_page_import_eval (widget, NULL) )
{
/*if(ictx->nb_new_acc == 0)
{
DB( g_print(" -> jump to Transaction page\n") );
//gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), data->pages[PAGE_ACCOUNT], TRUE);
gtk_assistant_next_page(GTK_ASSISTANT(data->assistant));
gtk_assistant_next_page(GTK_ASSISTANT(data->assistant));
//gtk_assistant_set_current_page (GTK_ASSISTANT(data->assistant), PAGE_TRANSACTION);
}
else
{
DB( g_print(" -> jump to Account page\n") );
//gtk_assistant_set_current_page (GTK_ASSISTANT(data->assistant), PAGE_ACCOUNT);
gtk_assistant_next_page(GTK_ASSISTANT(data->assistant));
}*/
gtk_assistant_next_page(GTK_ASSISTANT(data->assistant));
gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, TRUE);
}
break;
default:
if(current_page != (n_pages - 1))
{
DB( g_print("\n #4 transaction\n") );
if( current_page == PAGE_IMPORT + 1)
//hack to get rid of back button
gtk_assistant_set_page_type (GTK_ASSISTANT(data->assistant), page, GTK_ASSISTANT_PAGE_INTRO);
ui_import_page_transaction_fill(data);
ui_import_page_transaction_update(data);
}
else
{
DB( g_print("\n #5 confirmation\n") );
//todo: auto assignment should be optional
//data->imp_cnt_asg = transaction_auto_assign(ictx->trans_list, 0);
//ui_import_page_transaction_find_duplicate(data);
ui_import_page_confirmation_fill(data);
gtk_assistant_set_page_complete (GTK_ASSISTANT(data->assistant), page, TRUE);
}
}
}
static void
ui_import_assistant_apply (GtkWidget *widget, gpointer user_data)
{
struct import_data *data;
DB( g_print("\n[ui-import] apply\n") );
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
hb_import_apply(&data->ictx);
}
static gboolean
ui_import_assistant_dispose(GtkWidget *widget, gpointer user_data)
{
struct import_data *data = user_data;
DB( g_print("\n[ui-import] dispose\n") );
#if MYDEBUG == 1
gpointer data2 = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
g_print(" user_data=%p to be free, data2=%p\n", user_data, data2);
#endif
da_import_context_destroy(&data->ictx);
if(data->txndata)
{
g_array_free(data->txndata, TRUE);
}
// todo: optimize this
//if(data->imp_cnt_trn > 0)
//{
//GLOBALS->changes_count += data->imp_cnt_trn;
//our global list has changed, so update the treeview
ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_BALANCE+UF_REFRESHALL));
//}
g_free(user_data);
//delete-event TRUE abort/FALSE destroy
return FALSE;
}
static void
ui_import_assistant_close_cancel (GtkWidget *widget, gpointer user_data)
{
struct import_data *data;
GtkWidget *assistant = (GtkWidget *) user_data;
DB( g_print("\n[ui-import] close\n") );
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
ui_import_assistant_dispose(widget, data);
gtk_widget_destroy (assistant);
}
/* starting point of import */
GtkWidget *ui_import_assistant_new (gchar **paths)
{
struct import_data *data;
GtkWidget *assistant, *page;
gint w, h;
DB( g_print("\n[ui-import] new\n") );
data = g_malloc0(sizeof(struct import_data));
if(!data) return NULL;
assistant = gtk_assistant_new ();
data->assistant = assistant;
//store our window private data
g_object_set_data(G_OBJECT(assistant), "inst_data", (gpointer)data);
//DB( g_print("** \n[ui-import] window=%x, inst_data=%x\n", assistant, data) );
gtk_window_set_modal(GTK_WINDOW (assistant), TRUE);
gtk_window_set_transient_for(GTK_WINDOW(assistant), GTK_WINDOW(GLOBALS->mainwindow));
//set a nice dialog size
gtk_window_get_size(GTK_WINDOW(GLOBALS->mainwindow), &w, &h);
gtk_window_set_default_size (GTK_WINDOW(assistant), w * 0.8, h * 0.8);
//gtk_window_set_default_size (GTK_WINDOW(assistant), w - 24, h - 24);
page = ui_import_page_intro_create (assistant, data);
gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_INTRO);
gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, _("Welcome"));
gtk_assistant_set_page_complete (GTK_ASSISTANT(assistant), page, TRUE );
page = ui_import_page_filechooser_create (assistant, data);
gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, _("Select file(s)"));
page = ui_import_page_import_create (assistant, data);
gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
//gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_PROGRESS);
gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, _("Import"));
//3...x transaction page will be added automatically
//page = ui_import_page_transaction_create (assistant, 0, data);
//gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
//hack to hide the back button here
//gtk_assistant_set_page_type (GTK_ASSISTANT(assistant), page, GTK_ASSISTANT_PAGE_INTRO);
//gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, _("Transaction"));
page = ui_import_page_confirmation_create (assistant, data);
gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_CONFIRM);
gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, _("Confirmation"));
//gtk_assistant_set_forward_page_func(GTK_ASSISTANT(assistant), ui_import_assistant_forward_page_func, data, NULL);
//setup
//ui_import_page_filechooser_selection_changed(assistant, data);
DB( g_printf(" check list of paths '%p'\n", paths) );
if( paths != NULL )
{
ImportContext *ictx = &data->ictx;
GenFile *genfile;
gchar **str = paths;
while(*str != NULL)
{
DB( g_printf(" try to append '%s'\n", *str) );
genfile = da_gen_file_append_from_filename(ictx, *str);
if(genfile)
{
list_file_add(data->LV_file, genfile);
}
str++;
}
g_strfreev(paths);
}
//connect all our signals
//g_signal_connect (window, "delete-event", G_CALLBACK (hbfile_dispose), (gpointer)data);
g_signal_connect (G_OBJECT (assistant), "cancel", G_CALLBACK (ui_import_assistant_close_cancel), assistant);
g_signal_connect (G_OBJECT (assistant), "close", G_CALLBACK (ui_import_assistant_close_cancel), assistant);
g_signal_connect (G_OBJECT (assistant), "apply", G_CALLBACK (ui_import_assistant_apply), NULL);
g_signal_connect (G_OBJECT (assistant), "prepare", G_CALLBACK (ui_import_assistant_prepare), NULL);
gtk_widget_show (assistant);
if(PREFS->dtex_nointro)
gtk_assistant_set_current_page(GTK_ASSISTANT(assistant), PAGE_FILES);
return assistant;
}