ui-transaction.h \
ui-txn-multi.c \
ui-txn-multi.h \
+ ui-widgets-data.c \
ui-widgets.c \
- ui-widgets.h
+ ui-widgets.h \
+ refcount.h \
+ ext.c \
+ ext.h \
+ ext-value.c \
+ ext-value.h \
+ ext-native.c \
+ ext-perl.xs
+
+EXTRA_homebank_DEPENDENCIES = $(PERL_OBJS)
+
homebank_LDADD = $(DEPS_LIBS) \
- $(LIBSOUP_LIBS)
+ $(LIBSOUP_LIBS) \
+ $(PERL_OBJS)
AM_CPPFLAGS = \
$(DEPS_CFLAGS) \
#include "homebank.h"
- #include "dsp_mainwindow.h"
+ #include "dsp-mainwindow.h"
- #include "list_account.h"
- #include "list_upcoming.h"
- #include "list_topspending.h"
+#include "ext.h"
+
+ #include "list-account.h"
- #include "dsp_account.h"
+ #include "hub-account.h"
+ #include "hub-scheduled.h"
+ #include "hub-spending.h"
+ #include "hub-transaction.h"
+
+ #include "dsp-account.h"
#include "ui-assist-import.h"
#include "ui-assist-start.h"
#include "ui-account.h"
void ui_mainwindow_addtransactions(GtkWidget *widget, gpointer user_data);
void ui_mainwindow_recent_add (struct hbfile_data *data, const gchar *path);
- static void ui_panel_topspending_update(GtkWidget *widget, gpointer user_data);
-
- static void ui_mainwindow_scheduled_populate(GtkWidget *widget, gpointer user_data);
- void ui_mainwindow_scheduled_postall(GtkWidget *widget, gpointer user_data);
-
void ui_mainwindow_recent_add (struct hbfile_data *data, const gchar *path);
+static void ui_mainwindow_showprefs(gint page);
- static void ui_panel_accounts_setup(struct hbfile_data *data);
-
- extern gchar *CYA_ACC_TYPE[];
-
- gchar *CYA_CATSUBCAT[] = {
- N_("Category"),
- N_("Subcategory"),
- NULL
- };
-
-
static GtkActionEntry entries[] = {
/* name, icon-name, label */
{ "Quit" , ICONNAME_QUIT , N_("_Quit") , "<control>Q", N_("Quit HomeBank"), G_CALLBACK (ui_mainwindow_action_quit) },
/* Exchange */
- { "ImportQIF" , ICONNAME_HB_FILE_IMPORT , N_("QIF file...") , NULL, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import) },
- { "ImportOFX" , ICONNAME_HB_FILE_IMPORT , N_("OFX/QFX file...") , NULL, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import) },
- { "ImportCSV" , ICONNAME_HB_FILE_IMPORT , N_("CSV file...") , NULL, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import) },
-
- { "ExportQIF" , ICONNAME_HB_FILE_EXPORT , N_("Export QIF file...") , NULL, N_("Export all account in a QIF file"), G_CALLBACK (ui_mainwindow_action_export) },
+ { "Import" , ICONNAME_HB_FILE_IMPORT , N_("Import...") , NULL, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import) },
+ //{ "ImportQIF" , ICONNAME_HB_FILE_IMPORT , N_("QIF file...") , NULL, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import) },
+ //{ "ImportOFX" , ICONNAME_HB_FILE_IMPORT , N_("OFX/QFX file...") , NULL, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import) },
+ //{ "ImportCSV" , ICONNAME_HB_FILE_IMPORT , N_("CSV file...") , NULL, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import) },
-
++
+ { "ExportQIF" , ICONNAME_HB_FILE_EXPORT , N_("Export as QIF...") , NULL, N_("Export all account in a QIF file"), G_CALLBACK (ui_mainwindow_action_export) },
/* EditMenu */
{ "Preferences", ICONNAME_PREFERENCES , N_("Preferences..."), NULL, N_("Configure HomeBank"), G_CALLBACK (ui_mainwindow_action_preferences) },
{ "Welcome" , NULL , N_("Show welcome dialog...") , NULL, NULL, G_CALLBACK (ui_mainwindow_action_help_welcome) },
{ "FileStats" , NULL , N_("File statistics...") , NULL, NULL, G_CALLBACK (ui_mainwindow_action_file_statistics) },
{ "Anonymize" , NULL , N_("Anonymize...") , NULL, NULL, G_CALLBACK (ui_mainwindow_action_anonymize) },
--
++
+ /* Plugins */
+ { "PluginPreferences", "prf-plugins", N_("_Plugins..."), "<control>U", N_("Configure plugin preferences"), G_CALLBACK(ui_mainwindow_action_pluginprefs) },
+
/* HelpMenu */
{ "Contents" , ICONNAME_HELP , N_("_Contents") , "F1", N_("Documentation about HomeBank"), G_CALLBACK (ui_mainwindow_action_help) },
{ "Online" , "lpi-help" , N_("Get Help Online...") , NULL, N_("Connect to the LaunchPad website for online help"), G_CALLBACK (ui_mainwindow_action_help_online) },
title = g_strdup_printf (
_("Revert unsaved changes to file '%s'?"), basename);
-- secondtext =
++ secondtext =
_("- Changes made to the file will be permanently lost\n"
"- File will be reloaded from the last save (.xhb~)");
if( result == GTK_RESPONSE_OK )
{
DB( g_print(" - should revert\n") );
--
++
hbfile_change_filepath(hb_filename_new_with_extension(GLOBALS->xhb_filepath, "xhb~"));
ui_mainwindow_open_internal(widget, NULL);
hbfile_change_filepath(hb_filename_new_with_extension(GLOBALS->xhb_filepath, "xhb"));
gpointer data)
{
DB( g_print("activate url %s\n", link) );
--
++
homebank_util_url_show (link);
}
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());
--
++
dialog = gtk_about_dialog_new();
gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(GLOBALS->mainwindow));
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
--
++
gtk_about_dialog_set_program_name (GTK_ABOUT_DIALOG(dialog), g_get_application_name ());
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), version);
gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog), copyright);
gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog), _("Free, easy, personal accounting for everyone"));
gtk_about_dialog_set_license_type (GTK_ABOUT_DIALOG(dialog), GTK_LICENSE_GPL_2_0);
--
++
//gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(dialog), );
gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog), "http://homebank.free.fr");
gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(dialog), "Visit the HomeBank website");
gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), pixbuf);
g_object_unref (pixbuf);
}
--
++
gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(dialog), authors);
gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(dialog), artists);
//gtk_about_dialog_set_documenters(GTK_ABOUT_DIALOG(dialog), );
gtk_widget_destroy (dialog);
g_free(version);
--
++
}
title = _("Are you sure you want to anonymize the file?");
-- secondtext =
++ secondtext =
_("Proceeding will anonymize any text, \n"
"like 'account x', 'payee y', 'memo z', ...");
//#1707201
//if( result == GTK_RESPONSE_CANCEL )
-- // return;
++ // return;
if( result == GTK_RESPONSE_OK )
{
hbfile_anonymize();
}
+ static void ui_mainwindow_action_deftag(void)
+ {
+
+ ui_tag_manage_dialog();
+
+ //ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE));
+ }
+
+
static void ui_mainwindow_action_preferences(void)
+{
+ ui_mainwindow_showprefs(PREF_GENERAL);
+}
+
+static void ui_mainwindow_showprefs(gint page)
{
struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
// top spending
gtk_chart_show_minor(GTK_CHART(data->RE_pie), GLOBALS->minor);
--
- ui_panel_topspending_update(data->window, data);
++
+ ui_hub_spending_update(data->window, data);
}
static void ui_mainwindow_action_trendtime(void)
{
struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
--
++
ui_reptime_window_new(data->acc != NULL ? data->acc->key : 0);
}
NULL);
content_area = gtk_dialog_get_content_area(GTK_DIALOG (dialog));
--
++
mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (content_area), mainvbox, FALSE, FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER(mainvbox), SPACING_MEDIUM);
widget = gtk_button_new_with_mnemonic(_("Read HomeBank _Manual"));
gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome1), dialog);
--
++
widget = gtk_button_new_with_mnemonic(_("Configure _preferences"));
gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome2), dialog);
--
++
widget = gtk_button_new_with_mnemonic(_("Create a _new file"));
gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome3), dialog);
gtk_tree_store_clear(GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_acc))));
gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_upc))));
gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_top))));
--
++
data->showall = FALSE;
- ui_panel_accounts_setup(data);
-
+ ui_hub_account_setup(data);
-
++
hbfile_cleanup(file_clear);
hbfile_setup(file_clear);
if( PREFS->heritdate == FALSE ) //fix: 318733
ope->date = GLOBALS->today;
-
++
+ da_transaction_set_default_template(ope);
}
// normally we can't be in addkeep without initialized ope with add
DB( g_print(" - added 1 transaction to %d\n", ope->kacc) );
- ui_mainwindow_populate_accounts(GLOBALS->mainwindow, NULL);
-
+ ui_hub_account_populate(GLOBALS->mainwindow, NULL);
-
++
count++;
//todo: still usefull ? store last date
date = ope->date;
}
}
- struct tmptop
- {
- guint32 key;
- gdouble value;
- };
-
-
- #define MAX_TOPSPENDING 10
-
-
- static gint tmptop_compare_func(struct tmptop *tt1, struct tmptop *tt2)
- {
- return tt1->value > tt2->value ? 1 : -1;
- }
-
- static void ui_panel_topspending_update(GtkWidget *widget, gpointer user_data)
+ gboolean ui_mainwindow_open_backup_check_confirm(gchar *filepath)
{
- struct hbfile_data *data;
- GtkTreeModel *model;
- gchar *title;
- gchar strbuffer[G_ASCII_DTOSTR_BUF_SIZE];
-
- DB( g_print("\n[ui-mainwindow] topspending_update\n") );
+ gboolean retval = FALSE;
+ gchar *basename, *secondtext;
+ gboolean result;
- data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
+ basename = g_path_get_basename(filepath);
+ secondtext = g_strdup_printf (
- _("Your are about to open the backup file '%s'.\n\nAre you sure you want to do this ?"), basename);
++ _("Your are about to open the backup file '%s'.\n\nAre you sure you want to do this ?"), basename);
- hb_strfmon(strbuffer, G_ASCII_DTOSTR_BUF_SIZE-1, data->toptotal, GLOBALS->kcur, GLOBALS->minor);
- //hb_label_set_amount(GTK_LABEL(data->TX_topamount), total, GLOBALS->kcur, GLOBALS->minor);
- title = g_strdup_printf("%s %s", _("Top spending"), strbuffer);
+ result = ui_dialog_msg_confirm_alert(
+ GTK_WINDOW(GLOBALS->mainwindow),
+ _("Open the backup file ?"),
+ secondtext,
+ _("_Open backup")
- );
++ );
- model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_top));
-
- gtk_chart_set_color_scheme(GTK_CHART(data->RE_pie), PREFS->report_color_scheme);
- gtk_chart_set_currency(GTK_CHART(data->RE_pie), GLOBALS->kcur);
- gtk_chart_set_datas(GTK_CHART(data->RE_pie), model, LST_TOPSPEND_AMOUNT, title, NULL);
+ g_free(secondtext);
+ g_free(basename);
- g_free(title);
+ if( result == GTK_RESPONSE_OK )
+ retval = TRUE;
-
+
- //future usage
- gchar *fu = _("Top %d spending"); title = fu;
+ return retval;
}
}
else
{
- struct tmptop *item;
-
- pos = category_report_id(ope->kcat, type);
-
- //#1297054 if( trn_amount < 0 ) {
- item = &g_array_index (garray, struct tmptop, pos);
- item->key = pos;
- item->value += trn_amount;
- //DB( g_print(" - stored %.2f to item %d\n", trn_amount, pos) );
- //}
+ g_free(filename);
+ return;
}
-
-
- }
-
- list = g_list_next(list);
- }
-
- g_queue_free (txn_queue);
-
- // we need to sort this and limit before
- g_array_sort(garray, (GCompareFunc)tmptop_compare_func);
-
- n_items = MIN(garray->len,MAX_TOPSPENDING);
- other = 0;
- for(i=0 ; i<garray->len ; i++)
- {
- struct tmptop *item;
-
- item = &g_array_index (garray, struct tmptop, i);
- if(item->value < 0)
- {
- total += item->value;
-
- if(i >= n_items)
- other += item->value;
-
- DB( g_print(" - %d : k='%d' v='%f' t='%f'\n", i, item->key, item->value, total) );
-
- }
+ }
- }
- model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_top));
- gtk_list_store_clear (GTK_LIST_STORE(model));
- g_object_ref(model); /* Make sure the model stays with us after the tree view unrefs it */
- gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_top), NULL); /* Detach model from view */
-
- /* insert into the treeview */
- for(i=0 ; i<MIN(garray->len,MAX_TOPSPENDING) ; i++)
- {
- gchar *name;
- Category *entry;
- struct tmptop *item;
- gdouble value;
-
- item = &g_array_index (garray, struct tmptop, i);
-
- if(!item->value) continue;
-
- value = hb_amount_round(item->value, 2);
- entry = da_cat_get(item->key);
- if(entry == NULL) continue;
-
- name = entry->key == 0 ? _("(no category)") : da_cat_get_fullname(entry);
-
- // append test
- gtk_list_store_append (GTK_LIST_STORE(model), &iter);
- gtk_list_store_set (GTK_LIST_STORE(model), &iter,
- LST_TOPSPEND_ID, i,
- LST_TOPSPEND_KEY, 0,
- LST_TOPSPEND_NAME, name,
- LST_TOPSPEND_AMOUNT, value,
- //LST_TOPSPEND_RATE, (gint)(((ABS(value)*100)/ABS(total)) + 0.5),
- -1);
-
- }
-
- // append test
- if(ABS(other) > 0)
- {
- gtk_list_store_append (GTK_LIST_STORE(model), &iter);
- gtk_list_store_set (GTK_LIST_STORE(model), &iter,
- LST_TOPSPEND_ID, n_items,
- LST_TOPSPEND_KEY, 0,
- LST_TOPSPEND_NAME, _("Other"),
- LST_TOPSPEND_AMOUNT, other,
- //LST_TOPSPEND_RATE, (gint)(((ABS(other)*100)/ABS(total)) + 0.5),
- -1);
- }
-
- /* Re-attach model to view */
- gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_top), model);
- g_object_unref(model);
-
-
- // update chart and widgets
- {
- gchar *daterange;
-
- data->toptotal = total;
- ui_panel_topspending_update(widget, data);
-
- daterange = filter_daterange_text_get(data->filter);
- gtk_widget_set_tooltip_markup(GTK_WIDGET(data->CY_range), daterange);
- g_free(daterange);
+ hbfile_change_filepath(filename);
+ ui_mainwindow_open_internal(widget, NULL);
}
}
-
- /* free our memory */
- g_array_free (garray, TRUE);
-
}
- /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
- /* scheduled */
- /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
- static Archive *
- ui_mainwindow_scheduled_get_selected_item(GtkTreeView *treeview)
+ /*
+ * open the file stored in GLOBALS->xhb_filepath
+ */
+ void ui_mainwindow_open_internal(GtkWidget *widget, gpointer user_data)
{
- GtkTreeSelection *treeselection;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- treeselection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
- if( gtk_tree_selection_get_selected(treeselection, &model, &iter) )
- {
- Archive *arc;
+ struct hbfile_data *data;
+ gint r;
- gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, LST_DSPUPC_DATAS, &arc, -1);
- return arc;
- }
+ DB( g_print("\n[ui-mainwindow] open internal\n") );
- return NULL;
- }
+ data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
+ if( GLOBALS->xhb_filepath != NULL )
+ {
+ DB( g_print(" - filename: '%s'\n", GLOBALS->xhb_filepath) );
- static void ui_mainwindow_scheduled_onRowActivated (GtkTreeView *treeview,
- GtkTreePath *path,
- GtkTreeViewColumn *col,
- gpointer userdata)
- {
- //struct hbfile_data *data;
- Archive *arc;
+ ui_mainwindow_clear(GLOBALS->mainwindow, GINT_TO_POINTER(FALSE));
+ GLOBALS->hbfile_is_new = FALSE;
- DB( g_print ("\n[ui-mainwindow] A scheduled row has been double-clicked!\n") );
+ r = homebank_load_xml(GLOBALS->xhb_filepath);
+ if( r == XML_OK )
+ {
+ DB( g_print(" - file loaded ok : rcode=%d\n", r) );
- //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(treeview, GTK_TYPE_WINDOW)), "inst_data");
+ GLOBALS->xhb_timemodified = hbfile_file_get_time_modified(GLOBALS->xhb_filepath);
+ hbfile_file_hasrevert(GLOBALS->xhb_filepath);
-
+
- arc = ui_mainwindow_scheduled_get_selected_item(treeview);
- ui_mainwindow_defarchive(arc);
- }
+ if(PREFS->appendscheduled)
+ scheduled_post_all_pending();
+ if(PREFS->do_update_currency)
+ ui_cur_manage_dialog_update_currencies(GTK_WINDOW(GLOBALS->mainwindow));
- static void ui_mainwindow_scheduled_do_post(Archive *arc, gboolean doedit, gpointer user_data)
- {
- struct hbfile_data *data = user_data;
- GtkWidget *window;
- gint result;
- Transaction *txn;
+ homebank_lastopenedfiles_save();
- window = create_deftransaction_window(GTK_WINDOW(data->window), TRANSACTION_EDIT_ADD, TRUE);
+ //todo: delete this after computing done at xml read
+ account_compute_balances();
- /* fill in the transaction */
- txn = da_transaction_malloc();
- da_transaction_init_from_template(txn, arc);
- txn->date = scheduled_get_postdate(arc, arc->nextdate);
+ ui_mainwindow_recent_add(data, GLOBALS->xhb_filepath);
+ }
+ else
+ {
+ gchar *msg = _("Unknown error");
- deftransaction_set_transaction(window, txn);
+ switch(r)
+ {
+ case XML_IO_ERROR:
+ msg = _("I/O error for file '%s'.");
+ break;
+ case XML_FILE_ERROR:
+ msg = _("The file '%s' is not a valid HomeBank file.");
+ break;
- case XML_VERSION_ERROR:
++ case XML_VERSION_ERROR:
+ msg = _("The file '%s' was saved with a higher version of HomeBank\nand cannot be loaded by the current version.");
+ break;
+ }
- result = gtk_dialog_run (GTK_DIALOG (window));
+ ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_ERROR,
+ _("File error"),
+ msg,
+ GLOBALS->xhb_filepath
+ );
- DB( g_print(" - dialog result is %d\n", result) );
+ ui_mainwindow_clear(GLOBALS->mainwindow, GINT_TO_POINTER(TRUE));
- if(result == GTK_RESPONSE_ADD || result == GTK_RESPONSE_ACCEPT)
- {
- deftransaction_get(window, NULL);
- transaction_add(txn);
- GLOBALS->changes_count++;
+ }
- scheduled_date_advance(arc);
+ ui_hub_account_populate(GLOBALS->mainwindow, NULL);
+ ui_hub_scheduled_populate(GLOBALS->mainwindow, NULL);
+ ui_hub_spending_populate(GLOBALS->mainwindow, NULL);
+ ui_hub_transaction_populate(data);
-
+
- DB( g_print(" - added 1 transaction to %d\n", txn->kacc) );
+ ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_VISUAL));
}
- da_transaction_free(txn);
-
- deftransaction_dispose(window, NULL);
- gtk_widget_destroy (window);
}
- static void ui_mainwindow_scheduled_editpost_cb(GtkWidget *widget, gpointer user_data)
+ /*
+ **
+ */
+ void ui_mainwindow_save(GtkWidget *widget, gpointer user_data)
{
- struct hbfile_data *data = user_data;
-
- Archive *arc = ui_mainwindow_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
-
- if( (arc != NULL) )
- {
- ui_mainwindow_scheduled_do_post(arc, TRUE, data);
- ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE|UF_REFRESHALL));
- }
- }
+ struct hbfile_data *data;
+ gboolean saveas = GPOINTER_TO_INT(user_data);
+ gchar *filename = NULL;
+ gint r = XML_UNSET;
+ DB( g_print("\n[ui-mainwindow] save\n") );
- static void ui_mainwindow_scheduled_post_cb(GtkWidget *widget, gpointer user_data)
- {
- struct hbfile_data *data = user_data;
+ data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
- DB( g_print("\n[ui-mainwindow] scheduled post\n") );
+ if( GLOBALS->hbfile_is_new == TRUE )
+ saveas = 1;
- Archive *arc = ui_mainwindow_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
+ //#1710955 test for backup open
+ if( GLOBALS->hbfile_is_bak == TRUE )
+ {
+ //todo: later for backup, should also remove datetime and .bak
+ hbfile_change_filepath(hb_filename_new_with_extension(GLOBALS->xhb_filepath, "xhb"));
+ saveas = 1;
+ }
- if( (arc != NULL) )
+ if(saveas == 1)
{
- if( scheduled_is_postable(arc) )
+ if(ui_file_chooser_xhb(GTK_FILE_CHOOSER_ACTION_SAVE, &filename, FALSE) == TRUE)
{
- Transaction *txn = da_transaction_malloc ();
-
- da_transaction_init_from_template(txn, arc);
- txn->date = scheduled_get_postdate(arc, arc->nextdate);
- transaction_add(txn);
-
- GLOBALS->changes_count++;
- scheduled_date_advance(arc);
-
- da_transaction_free (txn);
+ DB( g_print(" + should save as '%s'\n", filename) );
+ homebank_file_ensure_xhb(filename);
+ homebank_backup_current_file();
+ r = homebank_save_xml(GLOBALS->xhb_filepath);
+ GLOBALS->hbfile_is_new = FALSE;
+ GLOBALS->hbfile_is_bak = FALSE;
}
else
- {
- ui_mainwindow_scheduled_do_post(arc, FALSE, data);
- }
-
- ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE|UF_REFRESHALL));
+ return;
}
- }
+ else
+ {
+ guint64 time_modified = hbfile_file_get_time_modified (GLOBALS->xhb_filepath);
+ gint result = GTK_RESPONSE_OK;
+ DB( g_print(" + should quick save '%s'\n + time: open=%lu :: now=%lu\n", GLOBALS->xhb_filepath, GLOBALS->xhb_timemodified, time_modified) );
- static void ui_mainwindow_scheduled_skip_cb(GtkWidget *widget, gpointer user_data)
- {
- struct hbfile_data *data = user_data;
-
- Archive *arc = ui_mainwindow_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
- if( (arc != NULL) && (arc->flags & OF_AUTO) )
- {
- GLOBALS->changes_count++;
- scheduled_date_advance(arc);
-
- ui_mainwindow_scheduled_populate(GLOBALS->mainwindow, NULL);
- ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
- }
- }
-
-
-
- static void ui_mainwindow_scheduled_update(GtkWidget *widget, gpointer user_data)
- {
- struct hbfile_data *data;
- //gint filter;
-
- DB( g_print("\n[ui-mainwindow] scheduled update\n") );
-
- data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
-
- //filter = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_sched_filter));
-
- Archive *arc = ui_mainwindow_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
-
- if(arc)
- {
- DB( g_print("archive is %s\n", arc->memo) );
-
- gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_skip), TRUE);
- gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_post), TRUE);
- gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_editpost), TRUE);
- }
- else
- {
- gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_skip), FALSE);
- gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_post), FALSE);
- gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_editpost), FALSE);
- }
-
- }
-
-
-
- static void ui_mainwindow_scheduled_selection_cb(GtkTreeSelection *treeselection, gpointer user_data)
- {
-
-
- ui_mainwindow_scheduled_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), GINT_TO_POINTER(UF_SENSITIVE));
- }
-
-
-
- /*
- ** called after load, importamiga, on demand
- */
- void ui_mainwindow_scheduled_postall(GtkWidget *widget, gpointer user_data)
- {
- //struct hbfile_data *data;
- gint count;
- gint usermode = GPOINTER_TO_INT(user_data);
-
- DB( g_print("\n[ui-mainwindow] check scheduled\n") );
-
- //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
-
- count = scheduled_post_all_pending();
-
- //inform the user
- if(usermode == TRUE)
- {
- gchar *txt;
-
- //#125534
- if( count > 0 )
- {
- ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_REFRESHALL));
- }
-
- if(count == 0)
- txt = _("No transaction to add");
- else
- txt = _("transaction added: %d");
-
- ui_dialog_msg_infoerror(GTK_WINDOW(GLOBALS->mainwindow), GTK_MESSAGE_INFO,
- _("Check scheduled transactions result"),
- txt,
- count);
- }
-
- }
-
-
- static void ui_mainwindow_scheduled_populate(GtkWidget *widget, gpointer user_data)
- {
- struct hbfile_data *data;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GList *list;
- gdouble totexp = 0;
- gdouble totinc = 0;
- gint count = 0;
- gchar buffer[256];
- guint32 maxpostdate;
- GDate *date;
- //Account *acc;
-
- DB( g_print("\n[ui-mainwindow] scheduled populate list\n") );
-
- data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
-
- model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_upc));
- gtk_list_store_clear (GTK_LIST_STORE(model));
-
- homebank_app_date_get_julian();
-
- maxpostdate = scheduled_date_get_post_max();
-
- date = g_date_new_julian (maxpostdate);
- g_date_strftime (buffer, 256-1, PREFS->date_format, date);
- g_date_free(date);
-
- gtk_label_set_text(GTK_LABEL(data->LB_maxpostdate), buffer);
-
-
- list = g_list_first(GLOBALS->arc_list);
- while (list != NULL)
- {
- Archive *arc = list->data;
- Account *acc;
- gdouble inc, exp;
- guint nbdays, nblate;
-
- if((arc->flags & OF_AUTO) ) //&& arc->kacc > 0)
- {
- count++;
- nbdays = arc->nextdate - maxpostdate;
- nblate = scheduled_get_latepost_count(arc, GLOBALS->today);
-
- DB( g_print(" - append '%s' : %d\n", arc->memo, nbdays) );
-
- if(arc->flags & OF_INCOME)
- {
- inc = arc->amount;
- exp = 0.0;
- }
- else
- {
- exp = arc->amount;
- inc = 0.0;
- }
-
- /* insert normal txn */
- acc = da_acc_get(arc->kacc);
- if( acc)
- {
- totinc += hb_amount_base(inc, acc->kcur);
- totexp += hb_amount_base(exp, acc->kcur);
- }
- gtk_list_store_append (GTK_LIST_STORE(model), &iter);
- gtk_list_store_set (GTK_LIST_STORE(model), &iter,
- LST_DSPUPC_DATAS, arc,
- LST_DSPUPC_ACCOUNT, acc,
- LST_DSPUPC_MEMO, arc->memo,
- LST_DSPUPC_EXPENSE, exp,
- LST_DSPUPC_INCOME, inc,
- LST_DSPUPC_REMAINING, nbdays,
- LST_DSPUPC_NB_LATE, nblate,
- -1);
-
- /* insert internal xfer txn : 1378836 */
- if(arc->paymode == PAYMODE_INTXFER)
- {
- acc = da_acc_get(arc->kxferacc);
- if( acc)
- {
- totinc += hb_amount_base(-inc, acc->kcur);
- totexp += hb_amount_base(-exp, acc->kcur);
- }
- gtk_list_store_append (GTK_LIST_STORE(model), &iter);
- gtk_list_store_set (GTK_LIST_STORE(model), &iter,
- LST_DSPUPC_DATAS, arc,
- LST_DSPUPC_ACCOUNT, acc,
- LST_DSPUPC_MEMO, arc->memo,
- LST_DSPUPC_EXPENSE, -inc,
- LST_DSPUPC_INCOME, -exp,
- LST_DSPUPC_REMAINING, nbdays,
- LST_DSPUPC_NB_LATE, nblate,
- -1);
- }
-
- }
- list = g_list_next(list);
- }
-
- // insert total
- if(count > 0 )
- {
- gtk_list_store_append (GTK_LIST_STORE(model), &iter);
- gtk_list_store_set (GTK_LIST_STORE(model), &iter,
- LST_DSPUPC_DATAS, NULL,
- LST_DSPUPC_ACCOUNT, NULL,
- LST_DSPUPC_MEMO, _("Total"),
- LST_DSPUPC_EXPENSE, totexp,
- LST_DSPUPC_INCOME, totinc,
- -1);
- }
-
- ui_mainwindow_scheduled_update(widget, NULL);
-
- }
-
-
- gboolean ui_mainwindow_open_backup_check_confirm(gchar *filepath)
- {
- gboolean retval = FALSE;
- gchar *basename, *secondtext;
- gboolean result;
-
- basename = g_path_get_basename(filepath);
- secondtext = g_strdup_printf (
- _("Your are about to open the backup file '%s'.\n\nAre you sure you want to do this ?"), basename);
-
- result = ui_dialog_msg_confirm_alert(
- GTK_WINDOW(GLOBALS->mainwindow),
- _("Open a backup file ?"),
- secondtext,
- _("_Open backup")
- );
-
- g_free(secondtext);
- g_free(basename);
-
- if( result == GTK_RESPONSE_OK )
- retval = TRUE;
-
- return retval;
- }
-
-
- /*
- **
- */
- void ui_mainwindow_open(GtkWidget *widget, gpointer user_data)
- {
- //struct hbfile_data *data;
- gchar *filename = NULL;
-
- DB( g_print("\n[ui-mainwindow] open\n") );
-
- //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
-
- if( ui_dialog_msg_savechanges(widget,NULL) == TRUE )
- {
- if( ui_file_chooser_xhb(GTK_FILE_CHOOSER_ACTION_OPEN, &filename) == TRUE )
- {
- //#1710955 test for backup open
- if( hbfile_file_isbackup(filename) )
- {
- if( ui_mainwindow_open_backup_check_confirm(filename) == TRUE )
- {
- GLOBALS->hbfile_is_bak = TRUE;
- }
- else
- {
- g_free(filename);
- return;
- }
- }
-
- hbfile_change_filepath(filename);
- ui_mainwindow_open_internal(widget, NULL);
- }
- }
- }
-
-
- /*
- * open the file stored in GLOBALS->xhb_filepath
- */
- void ui_mainwindow_open_internal(GtkWidget *widget, gpointer user_data)
- {
- struct hbfile_data *data;
- gint r;
-
- DB( g_print("\n[ui-mainwindow] open internal\n") );
-
- data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
-
- if( GLOBALS->xhb_filepath != NULL )
- {
- DB( g_print(" - filename: '%s'\n", GLOBALS->xhb_filepath) );
-
- ui_mainwindow_clear(GLOBALS->mainwindow, GINT_TO_POINTER(FALSE));
- GLOBALS->hbfile_is_new = FALSE;
-
- r = homebank_load_xml(GLOBALS->xhb_filepath);
- if( r == XML_OK )
- {
- DB( g_print(" - file loaded ok : rcode=%d\n", r) );
-
- hbfile_file_hasbackup(GLOBALS->xhb_filepath);
-
- if(PREFS->appendscheduled)
- scheduled_post_all_pending();
-
- if(PREFS->do_update_currency)
- ui_cur_manage_dialog_update_currencies(GTK_WINDOW(GLOBALS->mainwindow));
-
- homebank_lastopenedfiles_save();
-
- //todo: delete this after computing done at xml read
- account_compute_balances();
-
- ui_mainwindow_recent_add(data, GLOBALS->xhb_filepath);
- }
- else
- {
- gchar *msg = _("Unknow error");
-
- switch(r)
- {
- case XML_IO_ERROR:
- msg = _("I/O error for file '%s'.");
- break;
- case XML_FILE_ERROR:
- msg = _("The file '%s' is not a valid HomeBank file.");
- break;
- case XML_VERSION_ERROR:
- msg = _("The file '%s' was saved with a higher version of HomeBank\nand cannot be loaded by the current version.");
- break;
- }
-
- ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_ERROR,
- _("File error"),
- msg,
- GLOBALS->xhb_filepath
- );
-
- ui_mainwindow_clear(GLOBALS->mainwindow, GINT_TO_POINTER(TRUE));
-
- }
-
- ui_mainwindow_populate_accounts(GLOBALS->mainwindow, NULL);
- ui_mainwindow_scheduled_populate(GLOBALS->mainwindow, NULL);
- ui_mainwindow_populate_topspending(GLOBALS->mainwindow, NULL);
- ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_VISUAL));
- }
-
-
- }
-
-
- /*
- **
- */
- void ui_mainwindow_save(GtkWidget *widget, gpointer user_data)
- {
- struct hbfile_data *data;
- gboolean saveas = GPOINTER_TO_INT(user_data);
- gchar *filename = NULL;
- gint r = XML_UNSET;
-
- DB( g_print("\n[ui-mainwindow] save\n") );
-
- data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
-
- if( GLOBALS->hbfile_is_new == TRUE )
- saveas = 1;
-
- //#1710955 test for backup open
- if( GLOBALS->hbfile_is_bak == TRUE )
- {
- //todo: later for backup, should also remove datetime and .bak
- hbfile_change_filepath(hb_filename_new_with_extension(GLOBALS->xhb_filepath, "xhb"));
- saveas = 1;
- }
-
- if(saveas == 1)
- {
- if(ui_file_chooser_xhb(GTK_FILE_CHOOSER_ACTION_SAVE, &filename) == TRUE)
- {
- DB( g_print(" + should save as '%s'\n", filename) );
- homebank_file_ensure_xhb(filename);
- homebank_backup_current_file();
- r = homebank_save_xml(GLOBALS->xhb_filepath);
- GLOBALS->hbfile_is_new = FALSE;
- GLOBALS->hbfile_is_bak = FALSE;
- }
- else
- return;
- }
- else
- {
- DB( g_print(" + should quick save %s\n", GLOBALS->xhb_filepath) );
- homebank_file_ensure_xhb(NULL);
- homebank_backup_current_file();
- r = homebank_save_xml(GLOBALS->xhb_filepath);
- }
-
-
- if(r == XML_OK)
- {
- GLOBALS->changes_count = 0;
- ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_VISUAL));
- }
- else
- {
- gchar *msg = _("I/O error for file '%s'.");
-
- ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_ERROR,
- _("File error"),
- msg,
- GLOBALS->xhb_filepath
- );
-
- }
-
-
- }
-
-
- static void ui_panel_accounts_expand_all(GtkWidget *widget, gpointer user_data)
- {
- struct hbfile_data *data;
-
- data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
- gtk_tree_view_expand_all(GTK_TREE_VIEW(data->LV_acc));
- }
-
-
- static void ui_panel_accounts_collapse_all(GtkWidget *widget, gpointer user_data)
- {
- struct hbfile_data *data;
-
- data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
- gtk_tree_view_collapse_all(GTK_TREE_VIEW(data->LV_acc));
- }
-
-
-
- static GHashTable *ui_panel_accounts_groups_get(GList *lacc, gint groupby, gboolean showall)
- {
- GHashTable *hash;
- GList *elt;
- gchar *groupname;
- gint nballoc;
-
- DB( g_print("\n[ui-mainwindow] accounts_groups_get\n") );
-
- nballoc = da_acc_length ();
-
- DB( g_print(" %d accounts\n", nballoc) );
-
- hash = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL);
- elt = g_list_first(lacc);
- while (elt != NULL)
- {
- Account *acc = elt->data;
- GPtrArray *group;
-
- //#1674045 ony rely on nosummary
- //if( showall || !(acc->flags & (AF_CLOSED|AF_NOSUMMARY)) )
- if( showall || !(acc->flags & AF_NOSUMMARY) )
- {
- if( groupby == DSPACC_GROUP_BY_BANK )
- {
- groupname = _("(no institution)");
- if( (acc->bankname != NULL) && strlen(acc->bankname) > 0 )
- groupname = acc->bankname;
- }
- else
- {
- //pre 5.1.3 historical by type display
- groupname = _(CYA_ACC_TYPE[acc->type]);
- }
-
- if( g_hash_table_contains(hash, groupname) == FALSE )
- {
- g_hash_table_insert(hash, g_strdup(groupname), g_ptr_array_sized_new(nballoc) );
- //DB( g_print(" - type hash insert '%s' = %d\n", groupname, inserted) );
- }
-
- group = g_hash_table_lookup(hash, groupname);
- if( group != NULL )
- {
- g_ptr_array_add(group, (gpointer)acc);
- DB( g_print(" -- add '%s' to group '%s'\n", acc->name, groupname) );
- }
- }
- elt = g_list_next(elt);
- }
-
- return hash;
- }
-
-
-
-
-
-
- void ui_mainwindow_populate_accounts(GtkWidget *widget, gpointer user_data)
- {
- struct hbfile_data *data;
- GtkTreeModel *model;
- GtkTreeIter iter1, child_iter;
- GList *lacc, *elt;
- Account *acc;
- guint j, nbtype;
- gdouble gtbank, gttoday, gtfuture;
-
- GHashTable *h_group;
- GHashTableIter grp_iter;
- gpointer key, value;
-
- DB( g_print("\n[ui-mainwindow] populate accounts\n") );
-
- data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
-
- /* here we create a count and a list of every account pointer by type */
- lacc = elt = g_hash_table_get_values(GLOBALS->h_acc);
-
- h_group = ui_panel_accounts_groups_get(lacc, PREFS->pnl_acc_show_by, data->showall);
- g_list_free(lacc);
-
-
- gtbank = gttoday = gtfuture = 0;
-
- DB( g_print(" - populate listview, %d group(s)\n", g_hash_table_size(h_group)) );
-
- model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_acc));
- gtk_tree_store_clear (GTK_TREE_STORE(model));
-
- nbtype = 0;
- g_hash_table_iter_init (&grp_iter, h_group);
- while (g_hash_table_iter_next (&grp_iter, &key, &value))
- {
- GPtrArray *gpa = value;
- gdouble tbank, ttoday, tfuture;
- gint position;
-
- if(gpa != NULL)
+ if( GLOBALS->xhb_timemodified != time_modified )
{
- nbtype++;
- //1: Header: Bank, Cash, ...
- DB( g_print(" - add group '%s'\n", (gchar *)key) );
-
- //#1663399 keep type position like in dropdown
- position = 0;
- if( PREFS->pnl_acc_show_by == DSPACC_GROUP_BY_TYPE )
- {
- gint t = 0;
-
- while(CYA_ACC_TYPE[t] != NULL && t < 15)
- {
- if( !strcmp(CYA_ACC_TYPE[t], key) )
- break;
- t++;
- }
-
- position = t;
- }
-
- gtk_tree_store_append (GTK_TREE_STORE(model), &iter1, NULL);
- gtk_tree_store_set (GTK_TREE_STORE(model), &iter1,
- LST_DSPACC_POS, position,
- LST_DSPACC_DATATYPE, DSPACC_TYPE_HEADER,
- LST_DSPACC_NAME, key,
- -1);
-
- tbank = ttoday = tfuture = 0;
-
- //2: Accounts for real
- for(j=0;j<gpa->len;j++)
- {
- acc = g_ptr_array_index(gpa, j);
-
- //tbank += acc->bal_bank;
- //ttoday += acc->bal_today;
- //tfuture += acc->bal_future;
- tbank += hb_amount_base(acc->bal_bank, acc->kcur);
- ttoday += hb_amount_base(acc->bal_today, acc->kcur);
- tfuture += hb_amount_base(acc->bal_future, acc->kcur);
-
- DB( g_print(" - add account '%s' :: %.2f %.2f %.2f\n", acc->name, acc->bal_bank, acc->bal_today, acc->bal_future) );
-
- gtk_tree_store_append (GTK_TREE_STORE(model), &child_iter, &iter1);
- gtk_tree_store_set (GTK_TREE_STORE(model), &child_iter,
- LST_DSPACC_DATAS, acc,
- LST_DSPACC_DATATYPE, DSPACC_TYPE_NORMAL,
- LST_DSPACC_BANK, acc->bal_bank,
- LST_DSPACC_TODAY, acc->bal_today,
- LST_DSPACC_FUTURE, acc->bal_future,
- -1);
- }
-
- if(gpa->len > 1)
- {
- DB( g_print(" - group total :: %.2f %.2f %.2f\n", tbank, ttoday, tfuture) );
-
- // insert the total line
- gtk_tree_store_append (GTK_TREE_STORE(model), &child_iter, &iter1);
- gtk_tree_store_set (GTK_TREE_STORE(model), &child_iter,
- LST_DSPACC_DATATYPE, DSPACC_TYPE_SUBTOTAL,
- LST_DSPACC_NAME, _("Total"),
- LST_DSPACC_BANK, tbank,
- LST_DSPACC_TODAY, ttoday,
- LST_DSPACC_FUTURE, tfuture,
- -1);
- }
-
- /* set balance to header to display when collasped */
- DB( g_print(" - enrich group total header :: %.2f %.2f %.2f\n", tbank, ttoday, tfuture) );
- gtk_tree_store_set (GTK_TREE_STORE(model), &iter1,
- LST_DSPACC_BANK, tbank,
- LST_DSPACC_TODAY, ttoday,
- LST_DSPACC_FUTURE, tfuture,
- -1);
-
- /* add to grand total */
- gtbank += tbank;
- gttoday += ttoday;
- gtfuture += tfuture;
+ result = ui_dialog_msg_confirm_alert(
+ GTK_WINDOW(GLOBALS->mainwindow),
+ _("The file has been modified since reading it."),
+ _("If you save it, all the external changes could be lost. Save it anyway?"),
+ _("S_ave Anyway")
+ );
-
+
+ if( result != GTK_RESPONSE_OK )
+ return;
}
+ DB( g_print(" + saving...\n") );
+ homebank_file_ensure_xhb(NULL);
+ homebank_backup_current_file();
+ r = homebank_save_xml(GLOBALS->xhb_filepath);
}
- DB( g_print(" - grand total :: %.2f %.2f %.2f\n", gtbank, gttoday, gtfuture) );
-
- // Grand total
- if( nbtype > 1 )
+ if(r == XML_OK)
{
- gtk_tree_store_append (GTK_TREE_STORE(model), &iter1, NULL);
- gtk_tree_store_set (GTK_TREE_STORE(model), &iter1,
- LST_DSPACC_DATATYPE, DSPACC_TYPE_SUBTOTAL,
- LST_DSPACC_NAME, _("Grand total"),
- LST_DSPACC_BANK, gtbank,
- LST_DSPACC_TODAY, gttoday,
- LST_DSPACC_FUTURE, gtfuture,
- -1);
+ DB( g_print(" + OK...\n") );
+ GLOBALS->changes_count = 0;
+ GLOBALS->xhb_timemodified = hbfile_file_get_time_modified (GLOBALS->xhb_filepath);
+ ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_VISUAL));
}
-
-
- gtk_tree_view_expand_all(GTK_TREE_VIEW(data->LV_acc));
-
- DB( g_print(" - free ressources\n") );
-
- g_hash_table_iter_init (&grp_iter, h_group);
- while (g_hash_table_iter_next (&grp_iter, &key, &value))
+ else
{
- g_ptr_array_free (value, TRUE);
- }
- g_hash_table_destroy (h_group);
+ gchar *msg = _("I/O error for file '%s'.");
+ ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_ERROR,
+ _("File error"),
+ msg,
+ GLOBALS->xhb_filepath
+ );
+ }
}
changed = (GLOBALS->changes_count > 0) ? "*" : "";
+ #if MYDEBUG == 1
+ data->wintitle = g_strdup_printf("%s%s (%d)- %s - " PROGNAME, changed, basename, GLOBALS->changes_count, GLOBALS->owner);
+ #else
data->wintitle = g_strdup_printf("%s%s - %s - " PROGNAME, changed, basename, GLOBALS->owner);
-
+ #endif
+
gtk_window_set_title (GTK_WINDOW (gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), data->wintitle);
g_free(basename);
gtk_widget_hide(GTK_WIDGET(data->GR_top));
--
++
DB( g_print(" - show upcoming=%d\n", PREFS->wal_upcoming) );
if(PREFS->wal_upcoming)
gtk_widget_show(GTK_WIDGET(data->GR_upc));
PREFS->wal_vpaned = gtk_paned_get_position(GTK_PANED(data->vpaned));
PREFS->wal_hpaned = gtk_paned_get_position(GTK_PANED(data->hpaned));
-
DB( g_print(" - vpaned=%d hpaned=%d\n", PREFS->wal_vpaned, PREFS->wal_hpaned) );
-
+ if(PREFS->pnl_list_tab)
+ g_free(PREFS->pnl_list_tab);
+ PREFS->pnl_list_tab = g_strdup(gtk_stack_get_visible_child_name(GTK_STACK(data->stack)));
++
//todo
if(ui_dialog_msg_savechanges(widget, NULL) == FALSE)
{
gtk_widget_destroy(data->LV_top);
g_free(data->wintitle);
- da_filter_free(data->filter);
+ da_flt_free(data->filter);
g_free(user_data);
--
++
gtk_main_quit();
}
{
gchar **uris, **str;
gchar *newseldata;
- gint filetype, slen;
+ gint n_uris, filetype, slen;
+ GError *error = NULL;
-
+
if (info != TARGET_URI_LIST)
return;
newseldata = g_new (gchar, slen + 1);
memcpy (newseldata, gtk_selection_data_get_data(selection_data), slen);
newseldata[slen] = 0;
-
+ //DB( g_print(" - seldata ='%s'\n", gtk_selection_data_get_data(selection_data) ) );
+ //DB( g_print(" - newseldata ='%s'\n", newseldata ) );
+
uris = g_uri_list_extract_uris (newseldata);
+ n_uris = g_strv_length(uris);
+ DB( g_print(" - dragged %d files (len=%d)\n", n_uris, slen ) );
- DB( g_print(" - dragged %d %d files\n", slen, g_strv_length(uris) ) );
+ g_free(newseldata);
- str = uris;
- //for (str = uris; *str; str++)
- if( *str )
+ //single file: check for xhb
+ if(n_uris == 1)
- {
+ {
- GError *error = NULL;
- gchar *path = g_filename_from_uri (*str, NULL, &error);
+ filetype = hb_filename_type_get_by_extension(*uris);
- if (path)
- {
- filetype = homebank_alienfile_recognize(path);
+ DB( g_print(" - filetype is homebank (%d)\n", filetype) );
- DB( g_print(" - dragged %s, type is %d\n", path, filetype ) );
+ if( filetype == FILETYPE_HOMEBANK )
+ {
+ gchar *path = g_filename_from_uri (*uris, NULL, &error);
- if( filetype == FILETYPE_HOMEBANK)
+ if( path != NULL )
{
+ DB( g_print(" - path is '%s'\n", path) );
hbfile_change_filepath(g_strdup(path));
ui_mainwindow_open_internal(GTK_WIDGET(window), NULL);
+ goto end_drop;
}
else
{
- //todo: future here to implement import for other filetype
- // ui_import_assistant_new();
- // + write a method into assistant to catch other filename
-
-
- ui_dialog_msg_infoerror(GTK_WINDOW(window), GTK_MESSAGE_ERROR,
+ g_warning ("Could not convert uri to local path: %s", error->message);
+ g_error_free (error);
+ }
+ g_free (path);
+ }
+ /* we no more manage error here
+ ui_dialog_msg_infoerror(GTK_WINDOW(window), GTK_MESSAGE_ERROR,
_("File error"),
_("The file %s is not a valid HomeBank file."),
- path
- );
-
+ path);
+ */
+ }
- }
+ //collect known filetype to import
+ DB( g_print(" - collect %d files\n", n_uris) );
-
+
- }
- else
+ gchar **paths = g_new (gchar *, n_uris + 1);
+ slen = 0;
+ for (str = uris; *str; str++)
+ {
+ filetype = hb_filename_type_get_by_extension(*str);
+ if( filetype != FILETYPE_HOMEBANK && filetype != FILETYPE_UNKNOWN )
{
- g_warning ("Could not convert uri to local path: %s", error->message);
+ gchar *path = g_filename_from_uri (*str, NULL, NULL);
- g_error_free (error);
+ if( path != NULL )
+ {
+ DB( g_print(" - append %d '%s'\n", slen, path ) );
+ paths[slen++] = path;
+ }
- }
+ }
- g_free (path);
}
-
-
+ paths[slen] = NULL;
+
+ if( slen > 0 )
+ {
+ ui_import_assistant_new( paths );
+ }
++
++
+ end_drop:
g_strfreev (uris);
-
- g_free(newseldata);
}
gtk_label_set_markup (GTK_LABEL(label), "Unstable Development Version");
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label, FALSE, FALSE, 0);
#endif
--
++
/* Add the main area */
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
//gtk_container_set_border_width (GTK_CONTAINER(vbox), SPACING_MEDIUM);
//gtk_widget_set_size_request (widget, -1, 100);
gtk_paned_pack2 (GTK_PANED(hpaned), widget, TRUE, FALSE);
-
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ data->GR_upc = box;
+ gtk_paned_pack2 (GTK_PANED(vpaned), box, TRUE, FALSE);
+
+ sidebar = gtk_stack_sidebar_new ();
+ gtk_box_pack_start (GTK_BOX (box), sidebar, FALSE, FALSE, 0);
+
+ stack = gtk_stack_new ();
+ //gtk_stack_set_transition_type (GTK_STACK (stack), GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN);
+ gtk_stack_sidebar_set_stack (GTK_STACK_SIDEBAR (sidebar), GTK_STACK (stack));
+ data->stack = stack;
+ gtk_box_pack_start (GTK_BOX (box), stack, TRUE, TRUE, 0);
-
++
+ page = ui_hub_scheduled_create(data);
+ gtk_stack_add_titled (GTK_STACK (stack), page, "sched", _("Scheduled"));
+ //gtk_paned_pack2 (GTK_PANED(vpaned), widget, TRUE, FALSE);
+
+ page = ui_hub_transaction_create(data, HUB_TXN_TYPE_FUTURE);
+ gtk_stack_add_titled (GTK_STACK (stack), page, "futur", _("Future"));
+
+ page = ui_hub_transaction_create(data, HUB_TXN_TYPE_REMIND);
+ gtk_stack_add_titled (GTK_STACK (stack), page, "remin", _("Remind"));
++
//setup, init and show window
wg = &PREFS->wal_wg;
if(PREFS->wal_vpaned > 0)
gtk_paned_set_position(GTK_PANED(data->vpaned), PREFS->wal_vpaned);
-
+ if( PREFS->pnl_list_tab != NULL )
+ gtk_stack_set_visible_child_name (GTK_STACK(data->stack), PREFS->pnl_list_tab);
+
++
//todo: move this elsewhere
DB( g_print(" - setup stuff\n") );
--- /dev/null
- #include "dsp_mainwindow.h"
- #include "dsp_account.h"
+
+#include <EXTERN.h>
+#include <perl.h>
+#include <XSUB.h>
+
+#include <string.h>
+
+#undef _
+#include "homebank.h"
+#include "ext.h"
+#include "refcount.h"
+
+extern struct HomeBank *GLOBALS;
- RETVAL = G_OBJECT(register_panel_window_new(SELF->key, SELF));
++#include "dsp-mainwindow.h"
++#include "dsp-account.h"
+#include "ui-transaction.h"
+
+
+static gint ext_perl_init(int* argc, char** argv[], char** env[]);
+static void ext_perl_term(void);
+static gboolean ext_perl_check_file(const gchar* plugin_filepath);
+static GHashTable* ext_perl_read_plugin_metadata(const gchar* plugin_filepath);
+static gint ext_perl_load_plugin(const gchar* plugin_filepath);
+static void ext_perl_unload_plugin(const gchar* plugin_filepath);
+static void ext_perl_execute_action(const gchar* plugin_filepath);
+static void ext_perl_call_hook(const gchar* hook_id, GList* args);
+
+static SV* val_to_sv(GValue* val);
+static GValue* sv_to_val(SV* sv);
+
+static gboolean gperl_value_from_sv(GValue* value, SV* sv);
+static SV* gperl_sv_from_value(const GValue* value, gboolean copy_boxed);
+
+
+static inline GValue* EXT_SV(GValue* v, SV* sv, GType type)
+{
+ g_value_init(v, type);
+ gperl_value_from_sv(v, sv);
+ return v;
+}
+
+
+#define EXT_P2C_OBJECT(PKG, ARG, VAR, TYP) \
+if (sv_derived_from(ARG, PKG)) { \
+ IV iv = SvIV((SV*)SvRV(ARG)); \
+ VAR = INT2PTR(TYP, iv); \
+} else { \
+ croak(#VAR" is not of type "PKG); \
+}
+
+#define EXT_C2P_OBJECT(PKG, ARG, VAR) \
+sv_setref_pv(ARG, PKG, (void*)VAR)
+
+
+static inline GPtrArray* SvGptrarray(const SV* sv)
+{
+ if (SvROK(sv)) {
+ sv = MUTABLE_SV(SvRV(sv));
+ }
+ if (SvTYPE(sv) == SVt_PVAV) {
+ AV* av = (AV*)sv;
+ int i;
+ int top = av_len(av);
+ GPtrArray* array = g_ptr_array_new();
+ for (i = 0; i <= top; ++i) {
+ SV** item = av_fetch(av, i, 0);
+ if (!item) continue;
+ g_ptr_array_add(array, sv_to_val(*item));
+ }
+ return array;
+ // TODO- leaking
+ } else {
+ croak("var is not an array");
+ }
+}
+
+static inline SV* newSVgptrarray(const GPtrArray* a)
+{
+ if (a) {
+ AV* av = newAV();
+ int i;
+ for (i = 0; i < a->len; ++i) {
+ GValue* item = g_ptr_array_index(a, i);
+ av_push(av, val_to_sv(item));
+ }
+ return newRV((SV*)av);
+ }
+ return &PL_sv_undef;
+}
+
+
+static inline GHashTable* SvGhashtable(const SV* sv)
+{
+ if (SvROK(sv)) {
+ sv = MUTABLE_SV(SvRV(sv));
+ }
+ if (SvTYPE(sv) == SVt_PVHV) {
+ HV* hv = (HV*)sv;
+ hv_iterinit(hv);
+ gchar* key;
+ I32 len;
+ SV* item;
+ GHashTable* hash = g_hash_table_new(g_str_hash, g_str_equal);
+ while ((item = hv_iternextsv(hv, &key, &len))) {
+ g_hash_table_insert(hash, key, sv_to_val(item));
+ }
+ return hash;
+ // TODO- leaking
+ } else {
+ croak("var is not a hash");
+ }
+}
+
+static inline SV* newSVghashtable(GHashTable* h)
+{
+ if (h) {
+ HV* hv = newHV();
+ GHashTableIter it;
+ g_hash_table_iter_init(&it, h);
+ gchar* key = NULL;
+ GValue* item = NULL;
+ while (g_hash_table_iter_next(&it, (gpointer*)&key, (gpointer*)&item)) {
+ hv_store(hv, key, -g_utf8_strlen(key, -1), val_to_sv(item), 0);
+ }
+ return newRV((SV*)hv);
+ }
+ return &PL_sv_undef;
+}
+
+
+static inline gboolean SvGboolean(SV* sv)
+{
+ if (!sv) {
+ return FALSE;
+ }
+ if (SvROK(sv)) {
+ return !!SvIV(SvRV(sv));
+ } else {
+ return SvTRUE(sv);
+ }
+}
+
+static inline SV* newSVgboolean(gboolean b)
+{
+ return sv_setref_iv(newSV(0), "HomeBank::Boolean", !!b);
+}
+
+
+static inline gchar* SvGchar_ptr(SV* sv)
+{
+ return SvPVutf8_nolen(sv);
+}
+
+static inline SV* newSVgchar_ptr(const gchar* str)
+{
+ if (!str) return &PL_sv_undef;
+
+ SV* sv = newSVpv(str, 0);
+ SvUTF8_on(sv);
+ return sv;
+}
+
+
+static inline GObject* SvGobject(const SV* sv)
+{
+ GObject* (*func)(const SV*) = ext_symbol_lookup("gperl_get_object");
+ if (func) {
+ return func(sv);
+ }
+ return NULL;
+}
+
+static inline SV* newSVgobject(const GObject* o)
+{
+ SV* (*func)(const GObject*, gboolean) = ext_symbol_lookup("gperl_new_object");
+ if (func) {
+ return func(o, FALSE);
+ }
+ return &PL_sv_undef;
+}
+
+
+static PerlInterpreter* context = NULL;
+
+
+static gint ext_perl_init(int* argc, char** argv[], char** env[])
+{
+ int ret = 0;
+
+ PERL_SYS_INIT3(argc, argv, env);
+ context = perl_alloc();
+ perl_construct(context);
+
+ PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
+ PL_origalen = 1;
+ PL_perl_destruct_level = 1;
+
+ gchar* bootstrap = g_strdup_printf("-e"
+ "use lib '%s';"
+ "use HomeBank;"
+ "HomeBank->bootstrap;",
+ homebank_app_get_pkglib_dir());
+ char *args[] = { "", bootstrap };
+
+ EXTERN_C void xs_init(pTHX);
+ if (perl_parse(context, xs_init, 2, args, NULL) || perl_run(context)) {
+ ext_perl_term();
+ ret = -1;
+ }
+
+ g_free(bootstrap);
+ return ret;
+}
+
+static void ext_perl_term(void)
+{
+ if (context) {
+ perl_destruct(context);
+ perl_free(context);
+ context = NULL;
+ }
+ PERL_SYS_TERM();
+}
+
+static gboolean ext_perl_check_file(const gchar* plugin_filepath)
+{
+ if (g_str_has_suffix(plugin_filepath, ".pl")) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static GHashTable* ext_perl_read_plugin_metadata(const gchar* plugin_filepath)
+{
+ GHashTable* table = NULL;
+
+ if (!context) return NULL;
+ PERL_SET_CONTEXT(context);
+
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ mXPUSHs(newSVgchar_ptr(plugin_filepath));
+ PUTBACK;
+
+ int ret = call_pv("HomeBank::read_metadata", G_SCALAR | G_EVAL);
+
+ SPAGAIN;
+
+ if (ret == 1) {
+ table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ SV* sv = POPs;
+ if (SvROK(sv)) {
+ sv = MUTABLE_SV(SvRV(sv));
+ }
+ if (SvTYPE(sv) == SVt_PVHV) {
+ HV* hv = (HV*)sv;
+ hv_iterinit(hv);
+ gchar* key;
+ I32 len;
+ SV* item;
+ while ((item = hv_iternextsv(hv, &key, &len))) {
+ if (SvPOK(item)) {
+ gchar* val = SvPVutf8_nolen(item);
+ g_hash_table_insert(table, g_strdup(key), g_strdup(val));
+ }
+ }
+ }
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return table;
+}
+
+static gint ext_perl_load_plugin(const gchar* plugin_filepath)
+{
+ if (!context) return -1;
+ PERL_SET_CONTEXT(context);
+
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ mXPUSHs(newSVgchar_ptr(plugin_filepath));
+ PUTBACK;
+ call_pv("HomeBank::load_plugin", G_DISCARD | G_EVAL);
+ SPAGAIN;
+
+ gint ret = 0;
+ if (SvTRUE(ERRSV)) {
+ g_printerr("%s", SvPV_nolen(ERRSV));
+ ret = -1;
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return ret;
+}
+
+static void ext_perl_unload_plugin(const gchar* plugin_filepath)
+{
+ if (!context) return;
+ PERL_SET_CONTEXT(context);
+
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ mXPUSHs(newSVgchar_ptr(plugin_filepath));
+ PUTBACK;
+ call_pv("HomeBank::unload_plugin", G_DISCARD | G_EVAL);
+ SPAGAIN;
+
+ if (SvTRUE(ERRSV)) {
+ g_printerr("%s", SvPV_nolen(ERRSV));
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+}
+
+static void ext_perl_execute_action(const gchar* plugin_filepath)
+{
+ if (!context) return;
+ PERL_SET_CONTEXT(context);
+
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ mXPUSHs(newSVgchar_ptr(plugin_filepath));
+ PUTBACK;
+ call_pv("HomeBank::execute_action", G_DISCARD | G_EVAL);
+ SPAGAIN;
+
+ if (SvTRUE(ERRSV)) {
+ g_printerr("%s", SvPV_nolen(ERRSV));
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+}
+
+static void ext_perl_call_hook(const gchar* hook_id, GList* args)
+{
+ if (!context) return;
+ PERL_SET_CONTEXT(context);
+
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ mXPUSHs(newSVgchar_ptr(hook_id));
+
+ GList *list = g_list_first(args);
+ while (list) {
+ GValue* val = list->data;
+ XPUSHs(sv_2mortal(val_to_sv(val)));
+ list = g_list_next(list);
+ }
+
+ PUTBACK;
+ call_pv("HomeBank::call_hook", G_ARRAY);
+ SPAGAIN;
+ POPi;
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+}
+
+
+static SV* val_to_sv(GValue* val)
+{
+ if (!val || !G_IS_VALUE(val) || G_VALUE_TYPE(val) == G_TYPE_NONE) {
+ return &PL_sv_undef;
+ }
+ if (G_VALUE_TYPE(val) == G_TYPE_BOOLEAN) {
+ return newSVgboolean(g_value_get_boolean(val));
+ }
+ if (G_VALUE_TYPE(val) == G_TYPE_PTR_ARRAY) {
+ return newSVgptrarray((GPtrArray*)g_value_get_boxed(val));
+ }
+ if (G_VALUE_TYPE(val) == G_TYPE_HASH_TABLE) {
+ return newSVghashtable((GHashTable*)g_value_get_boxed(val));
+ }
+#define obj(CTYPE, _2, PART, GTYPE, _5) \
+ if (G_VALUE_TYPE(val) == GTYPE) { \
+ SV* sv = newSV(0); \
+ CTYPE* ptr = (CTYPE*)g_value_get_##PART(val); \
+ EXT_C2P_OBJECT("HomeBank::"#CTYPE, sv, rc_ref(ptr)); \
+ return sv; \
+ }
+#include "ext-value.h"
+#undef obj
+ return gperl_sv_from_value(val, FALSE);
+}
+
+static GValue* sv_to_val(SV* sv)
+{
+ GValue* val = g_new0(GValue, 1);
+
+ if (SvUOK(sv)) return EXT_SV(val, sv, G_TYPE_UINT);
+ if (SvIOK(sv)) return EXT_SV(val, sv, G_TYPE_INT);
+ if (SvNOK(sv)) return EXT_SV(val, sv, G_TYPE_DOUBLE);
+ if (SvPOK(sv)) return EXT_SV(val, sv, G_TYPE_STRING);
+ if (sv_isobject(sv)) {
+ if (sv_derived_from(sv, "HomeBank::Boolean")) {
+ return EXT_BOOLEAN(val, SvGboolean(sv));
+ }
+#define obj(CTYPE, NAME, _3, _4, _5) \
+ if (sv_derived_from(sv, "HomeBank::"#CTYPE)) { \
+ CTYPE* ptr; \
+ EXT_P2C_OBJECT("HomeBank::"#CTYPE, sv, ptr, CTYPE*); \
+ return EXT_##NAME(val, ptr); \
+ }
+#include "ext-value.h"
+#undef obj
+ return EXT_SV(val, sv, G_TYPE_OBJECT);
+ }
+ if (SvROK(sv)) {
+ sv = SvRV(sv);
+ switch (SvTYPE(sv)) {
+ case SVt_IV:
+ return EXT_BOOLEAN(val, SvGboolean(sv));
+ case SVt_PVAV:
+ return EXT_ARRAY(val, SvGptrarray(sv));
+ case SVt_PVHV:
+ return EXT_HASH_TABLE(val, SvGhashtable(sv));
+ default:
+ break;
+ }
+ }
+ switch (SvTYPE(sv)) {
+ case SVt_PVAV:
+ return EXT_ARRAY(val, SvGptrarray(sv));
+ case SVt_PVHV:
+ return EXT_HASH_TABLE(val, SvGhashtable(sv));
+ default:
+ break;
+ }
+
+ g_free(val);
+ return NULL;
+}
+
+
+static gboolean gperl_value_from_sv(GValue* value, SV* sv)
+{
+ gboolean (*func)(GValue*, SV*) = ext_symbol_lookup("gperl_value_from_sv");
+ if (func) return func(value, sv);
+
+ GType type = G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(value));
+ if (!SvOK(sv)) return TRUE;
+ switch (type) {
+ case G_TYPE_CHAR:
+ {
+ gchar *tmp = SvGchar_ptr(sv);
+ g_value_set_schar(value, (gint8)(tmp ? tmp[0] : 0));
+ break;
+ }
+ case G_TYPE_UCHAR:
+ {
+ char *tmp = SvPV_nolen(sv);
+ g_value_set_uchar(value, (guchar)(tmp ? tmp[0] : 0));
+ break;
+ }
+ case G_TYPE_BOOLEAN:
+ g_value_set_boolean(value, SvTRUE(sv));
+ break;
+ case G_TYPE_INT:
+ g_value_set_int(value, SvIV(sv));
+ break;
+ case G_TYPE_UINT:
+ g_value_set_uint(value, SvIV(sv));
+ break;
+ case G_TYPE_LONG:
+ g_value_set_long(value, SvIV(sv));
+ break;
+ case G_TYPE_ULONG:
+ g_value_set_ulong(value, SvIV(sv));
+ break;
+ case G_TYPE_FLOAT:
+ g_value_set_float(value, (gfloat)SvNV(sv));
+ break;
+ case G_TYPE_DOUBLE:
+ g_value_set_double(value, SvNV(sv));
+ break;
+ case G_TYPE_STRING:
+ g_value_set_string(value, SvGchar_ptr(sv));
+ break;
+ }
+ return TRUE;
+}
+
+static SV* gperl_sv_from_value(const GValue* value, gboolean copy_boxed)
+{
+ SV* (*func)(const GValue*, gboolean) = ext_symbol_lookup("gperl_sv_from_value");
+ if (func) return func(value, copy_boxed);
+
+ GType type = G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(value));
+ switch (type) {
+ case G_TYPE_CHAR:
+ return newSViv(g_value_get_schar(value));
+ case G_TYPE_UCHAR:
+ return newSVuv(g_value_get_uchar(value));
+ case G_TYPE_BOOLEAN:
+ return newSViv(g_value_get_boolean(value));
+ case G_TYPE_INT:
+ return newSViv(g_value_get_int(value));
+ case G_TYPE_UINT:
+ return newSVuv(g_value_get_uint(value));
+ case G_TYPE_LONG:
+ return newSViv(g_value_get_long(value));
+ case G_TYPE_ULONG:
+ return newSVuv(g_value_get_ulong(value));
+ case G_TYPE_FLOAT:
+ return newSVnv(g_value_get_float(value));
+ case G_TYPE_DOUBLE:
+ return newSVnv(g_value_get_double(value));
+ case G_TYPE_STRING:
+ return newSVgchar_ptr(g_value_get_string(value));
+ }
+ return &PL_sv_undef;
+}
+
+
+static void _register(void) __attribute__((constructor));
+static void _register()
+{
+ ext_register("perl",
+ ext_perl_init,
+ ext_perl_term,
+ ext_perl_check_file,
+ ext_perl_read_plugin_metadata,
+ ext_perl_load_plugin,
+ ext_perl_unload_plugin,
+ ext_perl_execute_action,
+ ext_perl_call_hook);
+}
+
+
+MODULE = HomeBank PACKAGE = HomeBank
+
+PROTOTYPES: ENABLE
+
+const gchar*
+version(void)
+ CODE:
+ RETVAL = VERSION;
+ OUTPUT:
+ RETVAL
+
+const gchar*
+config_dir(void)
+ CODE:
+ RETVAL = homebank_app_get_config_dir();
+ OUTPUT:
+ RETVAL
+
+gboolean
+has(const gchar* CLASS, ...)
+ PREINIT:
+ int i;
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ RETVAL = TRUE;
+ for (i = 1; i < items; ++i) {
+ gchar* feature = SvGchar_ptr(ST(i));
+ if (!feature || !ext_has(feature)) {
+ RETVAL = FALSE;
+ break;
+ }
+ }
+ OUTPUT:
+ RETVAL
+
+GObject*
+main_window(void)
+ CODE:
+ RETVAL = G_OBJECT(GLOBALS->mainwindow);
+ OUTPUT:
+ RETVAL
+
+GObject*
+main_ui_manager(void)
+ PREINIT:
+ struct hbfile_data *data;
+ CODE:
+ RETVAL = NULL;
+ if (GLOBALS->mainwindow) {
+ data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GLOBALS->mainwindow, GTK_TYPE_WINDOW)), "inst_data");
+ if (data) {
+ RETVAL = G_OBJECT(data->manager);
+ }
+ }
+ OUTPUT:
+ RETVAL
+
+void
+info(const gchar* CLASS, const gchar* title, const gchar* text)
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ ext_run_modal(title, text, "info");
+
+void
+warn(const gchar* CLASS, const gchar* title, const gchar* text)
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ ext_run_modal(title, text, "warn");
+
+void
+error(const gchar* CLASS, const gchar* title, const gchar* text)
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ ext_run_modal(title, text, "error");
+
+void
+hook(const gchar* CLASS, const gchar* hook_name, ...)
+ PREINIT:
+ int i;
+ GList* list = NULL;
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ for (i = 2; i < items; ++i) {
+ SV* sv = ST(i);
+ GValue *val = sv_to_val(sv);
+ list = g_list_append(list, val);
+ }
+ CLEANUP:
+ ext_vhook(hook_name, list);
+ g_list_free(list);
+ // TODO free all the things
+
+GObject*
+open_prefs(const gchar* CLASS)
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ RETVAL = G_OBJECT(defpref_dialog_new(PREF_GENERAL));
+ OUTPUT:
+ RETVAL
+
+
+MODULE = HomeBank PACKAGE = HomeBank::File
+
+const gchar*
+owner(const gchar* CLASS, ...)
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ if (1 < items) {
+ hbfile_change_owner(g_strdup(SvGchar_ptr(ST(1))));
+ }
+ RETVAL = GLOBALS->owner;
+ OUTPUT:
+ RETVAL
+
+void
+transactions(const gchar* CLASS)
+ PPCODE:
+ PERL_UNUSED_ARG(CLASS);
+
+ GList* acc_list = g_hash_table_get_values(GLOBALS->h_acc);
+ GList* acc_link = g_list_first(acc_list);
+ for (; acc_link; acc_link = g_list_next(acc_link)) {
+ Account *acc = acc_link->data;
+
+ GList* txn_link = g_queue_peek_head_link(acc->txn_queue);
+ for (; txn_link; txn_link = g_list_next(txn_link)) {
+ Transaction* txn = txn_link->data;
+
+ GValue val = G_VALUE_INIT;
+ SV* sv = val_to_sv(EXT_TRANSACTION(&val, txn));
+ mXPUSHs(sv);
+ }
+ }
+
+ g_list_free(acc_list);
+
+void
+anonymize(void)
+ CODE:
+ hbfile_anonymize();
+
+void
+baz(const gchar* CLASS, Account* account)
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ g_print("hello: %s\n", account->name);
+
+GPtrArray*
+meh(const gchar* CLASS, GPtrArray* asdf)
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ g_print("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\n");
+ if (asdf) {
+ ;
+ } else {
+ g_print("the array is nil\n");
+ }
+ RETVAL = asdf;
+ OUTPUT:
+ RETVAL
+ CLEANUP:
+ g_ptr_array_unref(asdf);
+
+GHashTable*
+foo(const gchar* CLASS, GHashTable* asdf)
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ g_print("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\n");
+ if (asdf) {
+ GHashTableIter it;
+ g_hash_table_iter_init(&it, asdf);
+ gchar* key = NULL;
+ GValue* item = NULL;
+ while (g_hash_table_iter_next(&it, (gpointer*)&key, (gpointer*)&item)) {
+ g_print("hash with key: %s\n", key);
+ }
+ } else {
+ g_print("the hash is nil\n");
+ }
+ RETVAL = asdf;
+ OUTPUT:
+ RETVAL
+ CLEANUP:
+ g_hash_table_unref(asdf);
+
+
+MODULE = HomeBank PACKAGE = HomeBank::Account
+
+void
+compute_balances(const gchar* CLASS)
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ account_compute_balances();
+
+Account*
+new(void)
+ CODE:
+ RETVAL = da_acc_malloc();
+ OUTPUT:
+ RETVAL
+
+void
+DESTROY(Account* SELF)
+ CODE:
+ da_acc_free(SELF);
+
+Account*
+get(const gchar* CLASS, guint key)
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ RETVAL = rc_ref(da_acc_get(key));
+ OUTPUT:
+ RETVAL
+
+Account*
+get_by_name(const gchar* CLASS, const gchar* name)
+ CODE:
+ PERL_UNUSED_ARG(CLASS);
+ RETVAL = rc_ref(da_acc_get_by_name((gchar*)name));
+ OUTPUT:
+ RETVAL
+
+const gchar*
+name(Account* SELF, ...)
+ CODE:
+ if (1 < items) {
+ account_rename(SELF, SvGchar_ptr(ST(1)));
+ }
+ RETVAL = SELF->name;
+ OUTPUT:
+ RETVAL
+
+const gchar*
+number(Account* SELF, ...)
+ CODE:
+ if (1 < items) {
+ g_free(SELF->number);
+ SELF->number = g_strdup(SvGchar_ptr(ST(1)));
+ }
+ RETVAL = SELF->number;
+ OUTPUT:
+ RETVAL
+
+const gchar*
+bankname(Account* SELF, ...)
+ CODE:
+ if (1 < items) {
+ g_free(SELF->bankname);
+ SELF->bankname = g_strdup(SvGchar_ptr(ST(1)));
+ }
+ RETVAL = SELF->bankname;
+ OUTPUT:
+ RETVAL
+
+gdouble
+initial(Account* SELF, ...)
+ CODE:
+ if (1 < items) {
+ SELF->initial = SvNV(ST(1));
+ }
+ RETVAL = SELF->initial;
+ OUTPUT:
+ RETVAL
+
+gdouble
+minimum(Account* SELF, ...)
+ CODE:
+ if (1 < items) {
+ SELF->minimum = SvNV(ST(1));
+ }
+ RETVAL = SELF->minimum;
+ OUTPUT:
+ RETVAL
+
+guint
+cheque1(Account* SELF, ...)
+ ALIAS:
+ check1 = 1
+ CODE:
+ PERL_UNUSED_VAR(ix);
+ if (1 < items) {
+ SELF->cheque1 = SvUV(ST(1));
+ }
+ RETVAL = SELF->cheque1;
+ OUTPUT:
+ RETVAL
+
+guint
+cheque2(Account* SELF, ...)
+ ALIAS:
+ check2 = 1
+ CODE:
+ PERL_UNUSED_VAR(ix);
+ if (1 < items) {
+ SELF->cheque2 = SvUV(ST(1));
+ }
+ RETVAL = SELF->cheque2;
+ OUTPUT:
+ RETVAL
+
+gdouble
+balance(Account* SELF)
+ ALIAS:
+ bank_balance = 1
+ future_balance = 2
+ CODE:
+ switch (ix) {
+ case 1:
+ RETVAL = SELF->bal_bank;
+ break;
+ case 2:
+ RETVAL = SELF->bal_future;
+ break;
+ default:
+ RETVAL = SELF->bal_today;
+ break;
+ }
+ OUTPUT:
+ RETVAL
+
+gboolean
+is_inserted(Account* SELF)
+ CODE:
+ RETVAL = da_acc_get(SELF->key) == SELF;
+ OUTPUT:
+ RETVAL
+
+gboolean
+is_used(Account* SELF)
+ CODE:
+ RETVAL = account_is_used(SELF->key);
+ OUTPUT:
+ RETVAL
+
+gboolean
+insert(Account* SELF)
+ CODE:
+ if (SELF->key == 0 || account_is_used(SELF->key))
+ RETVAL = da_acc_append(rc_ref(SELF));
+ else
+ RETVAL = da_acc_insert(rc_ref(SELF));
+ OUTPUT:
+ RETVAL
+
+void
+remove(Account* SELF)
+ CODE:
+ da_acc_remove(SELF->key);
+
+void
+transactions(Account* SELF)
+ PPCODE:
+ GList* list = g_queue_peek_head_link(SELF->txn_queue);
+ for (; list; list = g_list_next(list)) {
+ Transaction* txn = list->data;
+ GValue val = G_VALUE_INIT;
+ SV* sv = val_to_sv(EXT_TRANSACTION(&val, txn));
+ mXPUSHs(sv);
+ }
+
+GObject*
+open(Account* SELF)
+ CODE:
- RETVAL = G_OBJECT(create_deftransaction_window(NULL, TRANSACTION_EDIT_MODIFY, FALSE));
++ RETVAL = G_OBJECT(register_panel_window_new(SELF));
+ OUTPUT:
+ RETVAL
+
+
+MODULE = HomeBank PACKAGE = HomeBank::Transaction
+
+Transaction*
+new(void)
+ CODE:
+ RETVAL = da_transaction_malloc();
+ OUTPUT:
+ RETVAL
+
+void
+DESTROY(Transaction* SELF)
+ CODE:
+ da_transaction_free(SELF);
+
+gdouble
+amount(Transaction* SELF, ...)
+ CODE:
+ if (1 < items) {
+ SELF->amount = SvNV(ST(1));
+ }
+ RETVAL = SELF->amount;
+ OUTPUT:
+ RETVAL
+
+guint
+account_num(Transaction* SELF, ...)
+ CODE:
+ if (1 < items) {
+ SELF->kacc = SvIV(ST(1));
+ }
+ RETVAL = SELF->kacc;
+ OUTPUT:
+ RETVAL
+
+guint
+paired_account_num(Transaction* SELF, ...)
+ CODE:
+ if (1 < items) {
+ SELF->kxferacc = SvIV(ST(1));
+ }
+ RETVAL = SELF->kxferacc;
+ OUTPUT:
+ RETVAL
+
+void
+date(Transaction* SELF, ...)
+ PPCODE:
+ if (1 < items) {
+ SELF->date = SvIV(ST(1));
+ }
+ if (GIMME_V == G_ARRAY) {
+ GDate* d = g_date_new_julian(SELF->date);
+ mXPUSHp("day", 3);
+ mXPUSHi(g_date_get_day(d));
+ mXPUSHp("month", 5);
+ mXPUSHi(g_date_get_month(d));
+ mXPUSHp("year", 4);
+ mXPUSHi(g_date_get_year(d));
+ g_date_free(d);
+ XSRETURN(6);
+ } else {
+ XSRETURN_IV(SELF->date);
+ }
+
+const gchar*
+memo(Transaction* SELF, ...)
+ CODE:
+ if (1 < items) {
+ if (SELF->memo) g_free(SELF->memo);
+ SELF->memo = g_strdup(SvGchar_ptr(ST(1)));
+ }
+ RETVAL = SELF->memo ? SELF->memo : "";
+ OUTPUT:
+ RETVAL
+
+const gchar*
+info(Transaction* SELF, ...)
+ CODE:
+ if (1 < items) {
+ if (SELF->info) g_free(SELF->info);
+ SELF->info = g_strdup(SvGchar_ptr(ST(1)));
+ }
+ RETVAL = SELF->info ? SELF->info : "";
+ OUTPUT:
+ RETVAL
+
+GObject*
+open(Transaction* SELF)
+ CODE:
- other = ui_dialog_transaction_xfer_select_child(SELF, list);
++ RETVAL = G_OBJECT(create_deftransaction_window(NULL, TRANSACTION_EDIT_MODIFY, FALSE, 0));
+ deftransaction_set_transaction(GTK_WIDGET(RETVAL), SELF);
+ OUTPUT:
+ RETVAL
+
+Transaction*
+pair_with(Transaction* SELF, Transaction* other, ...)
+ PREINIT:
+ int i;
+ GList* list = NULL;
+ CODE:
+ if (2 < items) {
+ list = g_list_append(list, other);
+ for (i = 2; i < items; ++i) {
+ Transaction* ptr = NULL;
+ SV* sv = ST(i);
+ EXT_P2C_OBJECT("HomeBank::Transaction", sv, ptr, Transaction*);
+ list = g_list_append(list, ptr);
+ }
++ ui_dialog_transaction_xfer_select_child(NULL, SELF, list, &other);
+ }
+ if (other) {
+ transaction_xfer_change_to_child(SELF, other);
+ SELF->paymode = PAYMODE_INTXFER;
+ }
+ RETVAL = other;
+ OUTPUT:
+ RETVAL
+ CLEANUP:
+ g_list_free(list);
+
+void
+dump(Transaction* SELF)
+ CODE:
+ g_print("txn: %p (%s) at %u (%d/%d) flags:%d, paymode:%d, kpay:%d, kcat:%d", SELF,
+ SELF->memo, SELF->date, SELF->kacc, SELF->kxferacc, SELF->flags, SELF->paymode, SELF->kpay, SELF->kcat);
+
g_free(item->number);
g_free(item->bankname);
g_free(item->notes);
--
++
g_queue_free (item->txn_queue);
--
- g_free(item);
++
+ rc_free(item);
}
}
Account *item;
DB( g_print("da_acc_malloc\n") );
- item = g_malloc0(sizeof(Account));
+ item = rc_alloc(sizeof(Account));
+ item->kcur = GLOBALS->kcur;
item->txn_queue = g_queue_new ();
return item;
}
DB( g_print("da_acc_append\n") );
- /* ensure no duplicate */
- g_strstrip(item->name);
- if(item->name != NULL)
+ existitem = da_acc_get_by_name( item->name );
+ if( existitem == NULL )
{
- existitem = da_acc_get_by_name( item->name );
- if( existitem == NULL )
- {
- new_key = g_new0(guint32, 1);
- *new_key = da_acc_get_max_key() + 1;
- item->key = *new_key;
- item->pos = da_acc_length() + 1;
+ item->key = da_acc_get_max_key() + 1;
+ item->pos = da_acc_length() + 1;
+ da_acc_insert(item);
+
- DB( g_print(" -> insert id: %d\n", *new_key) );
++ GValue item_val = G_VALUE_INIT;
++ ext_hook("account_inserted", EXT_ACCOUNT(&item_val, item), NULL);
+
- g_hash_table_insert(GLOBALS->h_acc, new_key, item);
-
- GValue item_val = G_VALUE_INIT;
- ext_hook("account_inserted", EXT_ACCOUNT(&item_val, item), NULL);
-
- return TRUE;
- }
+ return TRUE;
}
DB( g_print(" -> %s already exist: %d\n", item->name, item->key) );
*
*/
Account *
- da_acc_get_by_name(gchar *name)
+ da_acc_get_by_name(gchar *rawname)
{
+ Account *retval = NULL;
+ gchar *stripname;
+
DB( g_print("da_acc_get_by_name\n") );
- return g_hash_table_find(GLOBALS->h_acc, (GHRFunc)da_acc_name_grfunc, name);
- }
+ if( rawname )
+ {
+ stripname = g_strdup(rawname);
+ g_strstrip(stripname);
+ if( strlen(stripname) > 0 )
+ retval = g_hash_table_find(GLOBALS->h_acc, (GHRFunc)da_acc_name_grfunc, stripname);
- Account *
- da_acc_get_by_imp_name(gchar *name)
- {
- DB( g_print("da_acc_get_by_imp_name\n") );
+ g_free(stripname);
+ }
- return g_hash_table_find(GLOBALS->h_acc, (GHRFunc)da_acc_imp_name_grfunc, name);
- return retval;
++ return retval;
}
while (lnk_acc != NULL)
{
Account *acc = lnk_acc->data;
--
++
if(acc->key != key)
{
lnk_txn = g_queue_peek_head_link(acc->txn_queue);
while (lnk_txn != NULL)
{
Transaction *entry = lnk_txn->data;
--
++
if( key == entry->kxferacc)
{
retval = TRUE;
Account *existitem;
gchar *stripname = account_get_stripname(newname);
- existitem = da_acc_get_by_name(stripname);
- if( existitem == NULL )
+ if( strlen(stripname) > 0 )
{
- g_free(item->name);
- item->name = g_strdup(stripname);
- return TRUE;
- }
+ existitem = da_acc_get_by_name(stripname);
+ if( existitem == NULL )
+ {
+ g_free(item->name);
+ item->name = g_strdup(stripname);
+ return TRUE;
+ }
- g_free(stripname);
+ g_free(stripname);
+ }
-
+
return FALSE;
}
--/*
++/*
* change the account currency
* change every txn to currency
* ensure dst xfer transaction account will be set to same currency
acc->kcur = kcur;
DB( g_print(" - '%s'\n", acc->name) );
--
++
for(i=1;i<maxkey;i++)
{
DB( g_print(" - %d '%d'\n", i, xfer_list[i]) );
while (lnk_acc != NULL)
{
Account *acc = lnk_acc->data;
--
++
/* set initial amount */
acc->bal_bank = acc->initial;
acc->bal_today = acc->initial;
acc->bal_future = acc->initial;
--
++
/* add every txn */
lnk_txn = g_queue_peek_head_link(acc->txn_queue);
while (lnk_txn != NULL)
{
Transaction *txn = lnk_txn->data;
--
++
if(!(txn->status == TXN_STATUS_REMIND))
{
account_balances_add_internal(acc, txn);
}
lnk_txn = g_list_next(lnk_txn);
}
--
++
lnk_acc = g_list_next(lnk_acc);
}
g_list_free(lst_acc);
Archive *da_archive_malloc(void)
{
- return rc_alloc(sizeof(Archive));
+ Archive *item;
+
- item = g_malloc0(sizeof(Archive));
++ item = rc_alloc(sizeof(Archive));
+ item->key = 1;
+ return item;
}
{
if(item->memo != NULL)
g_free(item->memo);
-
- da_splits_free(item->splits);
- //item->flags &= ~(OF_SPLIT); //Flag that Splits are cleared
-
+ if(item->splits != NULL)
+ da_split_destroy(item->splits);
- g_free(item);
+ rc_free(item);
}
}
}
- max_key = MAX(item->key, max_key);
+ /* append a fav with an existing key (from xml file only) */
+ gboolean
+ da_archive_append(Archive *item)
+ {
+ GLOBALS->arc_list = g_list_append(GLOBALS->arc_list, item);
+ return TRUE;
+ }
+
+
+ gboolean
+ da_archive_append_new(Archive *item)
+ {
+ item->key = da_archive_get_max_key() + 1;
+ GLOBALS->arc_list = g_list_append(GLOBALS->arc_list, item);
+ return TRUE;
+ }
+
+
+ guint32
+ da_archive_get_max_key(void)
+ {
+ GList *tmplist = g_list_first(GLOBALS->arc_list);
+ guint32 max_key = 0;
+
+ while (tmplist != NULL)
+ {
+ Archive *item = tmplist->data;
+
-
++ max_key = MAX(item->key, max_key);
+ tmplist = g_list_next(tmplist);
+ }
++
+ return max_key;
+ }
+
+
+ Archive *
+ da_archive_get(guint32 key)
+ {
+ GList *tmplist;
+ Archive *retval = NULL;
+
+ tmplist = g_list_first(GLOBALS->arc_list);
+ while (tmplist != NULL)
+ {
+ Archive *item = tmplist->data;
+
+ if(item->key == key)
+ {
+ retval = item;
+ break;
+ }
+ tmplist = g_list_next(tmplist);
+ }
+ return retval;
+ }
+
+
void da_archive_consistency(Archive *item)
{
Account *acc;
item->kcat = 0;
GLOBALS->changes_count++;
}
-
- split_cat_consistency(item->splits);
-
+
- //#1340142 check split category
++ //#1340142 check split category
+ if( item->splits != NULL )
+ {
+ nbsplit = da_splits_consistency(item->splits);
+ //# 1416624 empty category when split
+ if(nbsplit > 0 && item->kcat > 0)
+ {
+ g_warning("txn consistency: fixed invalid cat on split txn");
+ item->kcat = 0;
+ GLOBALS->changes_count++;
+ }
+ }
-
++
// check payee exists
pay = da_pay_get(item->kpay);
if(pay == NULL)
arc->kpay = txn->kpay;
arc->kcat = txn->kcat;
if(txn->memo != NULL)
- arc->memo = g_strdup(txn->memo);
+ arc->memo = g_strdup(txn->memo);
else
- arc->memo = g_strdup(_("(new archive)"));
+ arc->memo = g_strdup(_("(new archive)"));
- if( da_splits_clone(txn->splits, arc->splits) > 0)
+ arc->tags = tags_clone(txn->tags);
+ arc->splits = da_splits_clone(txn->splits);
+ if( da_splits_length (arc->splits) > 0 )
arc->flags |= OF_SPLIT; //Flag that Splits are active
--
++
return arc;
}
/* get the final post date and free */
nextpostdate = g_date_get_julian(tmpdate);
--
++
return nextpostdate;
}
finalpostdate = postdate;
--
++
tmpdate = g_date_new_julian(finalpostdate);
/* manage weekend exception */
if( arc->weekend > 0 )
}
}
}
--
++
/* get the final post date and free */
finalpostdate = g_date_get_julian(tmpdate);
g_date_free(tmpdate);
--
++
return finalpostdate;
}
if(arc->flags & OF_LIMIT)
nblate = MIN(nblate, arc->limit);
--
++
nblate = MIN(nblate, 11);
*/
--
++
// pre 5.1 way
post_date = g_date_new();
}
arc->daygap = CLAMP(lastday - g_date_get_day(post_date), 0, 3);
--
++
DB( g_print(" daygap is %d\n", arc->daygap) );
}
else
DB( g_print("\n[scheduled] date_get_post_max\n") );
//add until xx of the next month (excluded)
-- if(GLOBALS->auto_smode == 0)
++ if(GLOBALS->auto_smode == 0)
{
DB( g_print(" - max is %d of next month\n", GLOBALS->auto_weekday) );
--
++
today = g_date_new_julian(GLOBALS->today);
//we compute user xx weekday of next month
g_date_set_day(maxdate, GLOBALS->auto_weekday);
if(g_date_get_day (today) >= GLOBALS->auto_weekday)
g_date_add_months(maxdate, 1);
--
++
nbdays = g_date_days_between(today, maxdate);
--
++
g_date_free(maxdate);
g_date_free(today);
}
maxpostdate = scheduled_date_get_post_max();
txn = da_transaction_malloc();
--
++
list = g_list_first(GLOBALS->arc_list);
while (list != NULL)
{
while(mydate < maxpostdate)
{
DB( hb_print_date(mydate, arc->memo) );
--
++
da_transaction_init_from_template(txn, arc);
txn->date = scheduled_get_postdate(arc, mydate);
/* todo: ? fill in cheque number */
}
da_transaction_free (txn);
--
++
return count;
}
DB( g_print(" => %d, %s\n", item->key, item->name) );
g_free(item->name);
- g_free(item);
+ g_free(item->fullname);
+ rc_free(item);
}
}
return g_hash_table_foreach_remove(GLOBALS->h_cat, (GHRFunc)da_cat_remove_grfunc, &key);
}
-
+
+ static void
+ da_cat_build_fullname(Category *item)
+ {
+ Category *parent;
+
+ g_free(item->fullname);
+ if( item->parent == 0 )
+ item->fullname = g_strdup(item->name);
+ else
+ {
+ parent = da_cat_get(item->parent);
+ if( parent != NULL )
+ item->fullname = g_strconcat(parent->name, ":", item->name, NULL);
+ }
-
++
+ DB( g_print("- updated %d:'%s' fullname='%s'\n", item->key, item->name, item->fullname) );
+
+ }
+
+
+ static void
+ da_cat_rename(Category *item, gchar *newname)
+ {
+
+ DB( g_print("- renaming %s' => '%s'\n", item->name, newname) );
-
++
+ g_free(item->name);
+ item->name = g_strdup(newname);
+ da_cat_build_fullname(item);
-
++
+ if( item->parent == 0 )
+ {
+ GHashTableIter iter;
+ gpointer value;
+
+ DB( g_print("- updating subcat fullname\n") );
-
++
+ g_hash_table_iter_init (&iter, GLOBALS->h_cat);
+ while (g_hash_table_iter_next (&iter, NULL, &value))
+ {
+ Category *subcat = value;
++
+ if( subcat->parent == item->key )
+ da_cat_build_fullname(subcat);
+ }
+
+ }
+ }
+
+
/**
* da_cat_insert:
*
{
guint32 *new_key;
- DB( g_print("da_cat_insert\n") );
+ DB( g_print("\nda_cat_insert\n") );
+
+ DB( g_print("- '%s'\n", item->name) );
-
+
new_key = g_new0(guint32, 1);
*new_key = item->key;
g_hash_table_insert(GLOBALS->h_cat, new_key, item);
-
+ da_cat_build_fullname(item);
++
return TRUE;
}
da_cat_append(Category *cat)
{
Category *existitem;
- guint32 *new_key;
- gchar *fullname;
-
- DB( g_print("da_cat_append\n") );
-
- if( cat->name != NULL)
- {
-
- fullname = da_cat_get_fullname(cat);
- existitem = da_cat_get_by_fullname( fullname );
- g_free(fullname);
- if( existitem == NULL )
- {
- new_key = g_new0(guint32, 1);
- *new_key = da_cat_get_max_key() + 1;
- cat->key = *new_key;
-
- DB( g_print(" -> insert id: %d\n", *new_key) );
+ DB( g_print("\nda_cat_append\n") );
- g_hash_table_insert(GLOBALS->h_cat, new_key, cat);
- return TRUE;
- }
+ if( !cat->fullname )
+ da_cat_build_fullname(cat);
-
+
+ existitem = da_cat_get_by_fullname( cat->fullname );
+ if( existitem == NULL )
+ {
+ cat->key = da_cat_get_max_key() + 1;
+ da_cat_insert(cat);
+ return TRUE;
}
DB( g_print(" -> %s already exist\n", cat->name) );
}
- /* fullname i.e. car:refuel */
- struct fullcatcontext
+ static gchar **da_cat_get_by_fullname_split_clean(gchar *rawfullname, guint *outlen)
{
- guint parent;
- gchar *name;
- };
+ gchar **partstr = g_strsplit(rawfullname, ":", 2);
+ guint len = g_strv_length(partstr);
+ gboolean valid = TRUE;
+ DB( g_print("- spliclean '%s' - %d parts\n", rawfullname, g_strv_length(partstr)) );
- static gboolean
- da_cat_fullname_grfunc(gpointer key, Category *item, struct fullcatcontext *ctx)
- {
+ if( outlen != NULL )
+ *outlen = len;
-
+
- //DB( g_print("'%s' == '%s'\n", ctx->name, item->name) );
- if( item->parent == ctx->parent )
+ if(len >= 1)
{
- if(!strcasecmp(ctx->name, item->name))
- return TRUE;
+ g_strstrip(partstr[0]);
+ if( strlen(partstr[0]) == 0 )
+ valid = FALSE;
+
+ if(len == 2)
+ {
+ g_strstrip(partstr[1]);
+ if( strlen(partstr[1]) == 0 )
+ valid = FALSE;
+ }
}
- return FALSE;
+
+ if(valid == TRUE)
+ return partstr;
+
+ DB( g_print("- is invalid\n") );
+
+ g_strfreev(partstr);
+ return NULL;
}
+
Category *
- da_cat_get_by_fullname(gchar *fullname)
+ da_cat_get_by_fullname(gchar *rawfullname)
{
- struct fullcatcontext ctx;
- gchar **typestr;
- Category *item = NULL;
+ gchar **partstr;
+ Category *parent = NULL;
+ Category *retval = NULL;
+ guint len;
-
+
- DB( g_print("da_cat_get_by_fullname\n") );
+ DB( g_print("\nda_cat_get_by_fullname\n") );
- typestr = g_strsplit(fullname, ":", 2);
- if( g_strv_length(typestr) == 2 )
+ if( rawfullname )
{
- ctx.parent = 0;
- ctx.name = typestr[0];
- DB( g_print(" [x:x] try to find the parent : '%s'\n", typestr[0]) );
-
- Category *parent = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
- if( parent != NULL )
+ if( (partstr = da_cat_get_by_fullname_split_clean(rawfullname, &len)) != NULL )
{
- ctx.parent = parent->key;
- ctx.name = typestr[1];
+ if( len >= 1 )
+ {
+ parent = da_cat_get_by_name_find_internal(0, partstr[0]);
+ retval = parent;
+ }
-
+
- DB( g_print(" [x:x] and searching sub %d '%s'\n", ctx.parent, ctx.name) );
+ if( len == 2 && parent != NULL )
+ {
+ retval = da_cat_get_by_name_find_internal(parent->key, partstr[1]);
+ }
- item = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
+ g_strfreev(partstr);
}
}
- else
- {
- ctx.parent = 0;
- ctx.name = fullname;
-
- DB( g_print(" [x] try to '%s'\n", fullname) );
-
- item = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
- }
-
- g_strfreev(typestr);
-
+
- DB( g_print(" return value %p\n", item) );
-
- return item;
+ return retval;
}
*
*/
Category *
- da_cat_append_ifnew_by_fullname(gchar *fullname, gboolean imported)
+ da_cat_append_ifnew_by_fullname(gchar *rawfullname)
{
- struct fullcatcontext ctx;
- gchar **typestr;
- Category *newcat, *item, *retval = NULL;
- guint32 *new_key;
+ gchar **partstr;
+ Category *parent = NULL;
+ Category *newcat = NULL;
+ Category *retval = NULL;
+ guint len;
- DB( g_print("da_cat_append_ifnew_by_fullname\n") );
+ DB( g_print("\nda_cat_append_ifnew_by_fullname\n") );
- DB( g_print(" -> fullname: '%s' %d\n", fullname, strlen(fullname)) );
-
- if( strlen(fullname) > 0 )
+ if( rawfullname )
{
- typestr = g_strsplit(fullname, ":", 2);
-
- /* if we have a subcategory : aaaa:bbb */
- if( g_strv_length(typestr) == 2 )
+ if( (partstr = da_cat_get_by_fullname_split_clean(rawfullname, &len)) != NULL )
{
- ctx.parent = 0;
- ctx.name = typestr[0];
- DB( g_print(" try to find the parent:'%s'\n", typestr[0]) );
-
- Category *parent = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
- if( parent == NULL )
- {
- DB( g_print(" -> not found\n") );
-
- // append a new category
- new_key = g_new0(guint32, 1);
- *new_key = da_cat_get_max_key() + 1;
-
- newcat = da_cat_malloc();
- newcat->key = *new_key;
- newcat->name = g_strdup(typestr[0]);
- newcat->imported = imported;
-
- parent = newcat;
-
- DB( g_print(" -> insert cat '%s' id: %d\n", newcat->name, newcat->key) );
-
- g_hash_table_insert(GLOBALS->h_cat, new_key, newcat);
- }
-
- ctx.parent = parent->key;
- ctx.name = typestr[1];
- DB( g_print(" searching %d '%s'\n", ctx.parent, ctx.name) );
-
- item = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
- if( item == NULL )
+ if( len >= 1 )
{
- // append a new subcategory
- new_key = g_new0(guint32, 1);
- *new_key = da_cat_get_max_key() + 1;
-
- newcat = da_cat_malloc();
- newcat->key = *new_key;
- newcat->parent = parent->key;
- newcat->name = g_strdup(typestr[1]);
- newcat->imported = imported;
-
- newcat->flags |= GF_SUB;
- //#1713413 take parent type into account
- if(parent->flags & GF_INCOME)
- newcat->flags |= GF_INCOME;
-
- DB( g_print(" -> insert subcat '%s' id: %d\n", newcat->name, newcat->key) );
-
- g_hash_table_insert(GLOBALS->h_cat, new_key, newcat);
-
- retval = newcat;
+ parent = da_cat_get_by_name_find_internal(0, partstr[0]);
+ if( parent == NULL )
+ {
+ parent = da_cat_malloc();
+ parent->key = da_cat_get_max_key() + 1;
+ parent->name = g_strdup(partstr[0]);
+ da_cat_insert(parent);
+ }
+ retval = parent;
}
- else
- retval = item;
- }
- /* this a single category : aaaa */
- else
- {
- ctx.parent = 0;
- ctx.name = typestr[0];
- DB( g_print(" searching %d '%s'\n", ctx.parent, ctx.name) );
-
+
- item = g_hash_table_find(GLOBALS->h_cat, (GHRFunc)da_cat_fullname_grfunc, &ctx);
- if( item == NULL )
+ /* if we have a subcategory - xxx:xxx */
+ if( len == 2 && parent != NULL )
{
- // append a new category
- new_key = g_new0(guint32, 1);
- *new_key = da_cat_get_max_key() + 1;
-
- newcat = da_cat_malloc();
- newcat->key = *new_key;
- newcat->name = g_strdup(typestr[0]);
- newcat->imported = imported;
-
- DB( g_print(" -> insert cat '%s' id: %d\n", newcat->name, newcat->key) );
-
- g_hash_table_insert(GLOBALS->h_cat, new_key, newcat);
-
+ newcat = da_cat_get_by_name_find_internal(parent->key, partstr[1]);
+ if( newcat == NULL )
+ {
+ newcat = da_cat_malloc();
+ newcat->key = da_cat_get_max_key() + 1;
+ newcat->parent = parent->key;
+ newcat->name = g_strdup(partstr[1]);
+ newcat->flags |= GF_SUB;
+ //#1713413 take parent type into account
+ if(parent->flags & GF_INCOME)
+ newcat->flags |= GF_INCOME;
+ da_cat_insert(newcat);
+ }
retval = newcat;
}
- else
- retval = item;
-
+
+ g_strfreev(partstr);
}
-
- g_strfreev(typestr);
}
return retval;
GLOBALS->changes_count++;
}
}
-
- g_strstrip(item->name);
+
+ if( item->name != NULL )
+ g_strstrip(item->name);
+ else
+ {
+ item->name = g_strdup("void");
+ da_cat_build_fullname(item);
+ g_warning("category consistency: fixed null name");
+ GLOBALS->changes_count++;
+ }
-
++
}
}
--void
++void
category_delete_unused(void)
{
GList *lcat, *list;
--
++
lcat = list = g_hash_table_get_values(GLOBALS->h_cat);
while (list != NULL)
{
}
--static void
++static void
category_fill_usage_count(guint32 kcat)
{
Category *cat = da_cat_get (kcat);
//#1689308 count split as well
if( txn->flags & OF_SPLIT )
{
- nbsplit = da_splits_count(txn->splits);
+ nbsplit = da_splits_length(txn->splits);
for(i=0;i<nbsplit;i++)
{
- Split *split = txn->splits[i];
-
+ Split *split = da_splits_get(txn->splits, i);
-
++
category_fill_usage_count(split->kcat);
}
}
else
-- category_fill_usage_count(txn->kcat);
++ category_fill_usage_count(txn->kcat);
lnk_txn = g_list_next(lnk_txn);
}
//#1689308 count split as well
if( entry->flags & OF_SPLIT )
{
- nbsplit = da_splits_count(entry->splits);
+ nbsplit = da_splits_length(entry->splits);
for(i=0;i<nbsplit;i++)
{
- Split *split = entry->splits[i];
-
+ Split *split = da_splits_get(entry->splits, i);
-
++
category_fill_usage_count(split->kcat);
}
}
while (lnk_txn != NULL)
{
Transaction *txn = lnk_txn->data;
--
++
if(txn->kcat == key1)
{
txn->kcat = key2;
lnk_txn = g_list_next(lnk_txn);
}
--
++
lnk_acc = g_list_next(lnk_acc);
}
g_list_free(lst_acc);
}
+ gchar
+ category_get_type_char(Category *item)
+ {
+ return (item->flags & GF_INCOME) ? '+' : '-';
+ }
+
- static gint category_change_type_eval(Category *item, gboolean isIncome)
-static gint
++static gint
+ category_change_type_eval(Category *item, gboolean isIncome)
{
if( (item->flags & (GF_INCOME)) && !isIncome )
return 1;
}
- gint category_change_type(Category *item, gboolean isIncome)
-gint
++gint
+ category_change_type(Category *item, gboolean isIncome)
{
gint changes = 0;
GList *lcat, *list;
changes += category_change_type_eval(item, isIncome);
--
++
item->flags &= ~(GF_INCOME); //delete flag
if(isIncome == TRUE)
item->flags |= GF_INCOME;
#include "hb-tag.h"
#include "hb-split.h"
+#include "ext.h"
+#include "refcount.h"
+
/****************************************************************************/
- /* Debug macros */
+ /* Debug macro */
/****************************************************************************/
#define MYDEBUG 0
}
+ Transaction *da_transaction_set_default_template(Transaction *txn)
+ {
+ Account *acc;
+ Archive *arc;
+
+ DB( g_print("da_transaction_set_default_template\n") );
+
+ acc = da_acc_get(txn->kacc);
+ if(acc != NULL && acc->karc > 0)
+ {
+ arc = da_archive_get(acc->karc);
+ if( arc )
+ {
+ DB( g_print(" - init with default template\n") );
+ da_transaction_init_from_template(txn, arc);
+ }
+ }
+
+ return txn;
+ }
+
+
Transaction *da_transaction_clone(Transaction *src_item)
{
-Transaction *new_item = g_memdup(src_item, sizeof(Transaction));
+Transaction *new_item = rc_dup(src_item, sizeof(Transaction));
DB( g_print("da_transaction_clone\n") );
if(newope->paymode == PAYMODE_INTXFER)
{
- transaction_xfer_search_or_add_child(NULL, newope, FALSE);
+ transaction_xfer_search_or_add_child(parent, newope, newope->kxferacc);
}
+
+ GValue txn_value = G_VALUE_INIT;
+ ext_hook("transaction_inserted", EXT_TRANSACTION(&txn_value, newope), NULL);
}
return newope;
gint retval = XML_OK;
GError *error = NULL;
+ GValue filename_val = G_VALUE_INIT;
+ ext_hook("save_file", EXT_STRING(&filename_val, filename), NULL);
+
io = g_io_channel_new_file(filename, "w", &error);
- if(io == NULL)
+ if(error)
{
- g_message("file error on: %s", filename);
- retval = XML_IO_ERROR;
-
- if(error)
- g_print("failed: %s\n", error->message);
-
+ g_warning("unable to save file %s: %s", filename, error->message);
g_error_free(error);
+ return(XML_IO_ERROR);
}
- else
- {
- g_io_channel_write_chars(io, "<?xml version=\"1.0\"?>\n", -1, NULL, NULL);
- outstr = g_strdup_printf("<homebank v=\"%s\" d=\"%06d\">\n", g_ascii_dtostr (buf1, sizeof (buf1), FILE_VERSION), HB_VERSION_NUM);
- g_io_channel_write_chars(io, outstr, -1, NULL, NULL);
- g_free(outstr);
+ g_io_channel_write_chars(io, "<?xml version=\"1.0\"?>\n", -1, NULL, NULL);
- retval = homebank_save_xml_prop(io);
- retval = homebank_save_xml_cur(io);
- retval = homebank_save_xml_acc(io);
- retval = homebank_save_xml_pay(io);
- retval = homebank_save_xml_cat(io);
- retval = homebank_save_xml_tag(io);
- retval = homebank_save_xml_asg(io);
- retval = homebank_save_xml_arc(io);
- retval = homebank_save_xml_ope(io);
+ outstr = g_strdup_printf("<homebank v=\"%s\" d=\"%06d\">\n", g_ascii_dtostr (buf1, sizeof (buf1), FILE_VERSION), HB_VERSION_NUM);
+ g_io_channel_write_chars(io, outstr, -1, NULL, NULL);
+ g_free(outstr);
- g_io_channel_write_chars(io, "</homebank>\n", -1, NULL, NULL);
+ retval = homebank_save_xml_prop(io);
+ retval = homebank_save_xml_cur(io);
+ retval = homebank_save_xml_acc(io);
+ retval = homebank_save_xml_pay(io);
+ retval = homebank_save_xml_cat(io);
+ //retval = homebank_save_xml_tag(io);
+ retval = homebank_save_xml_asg(io);
+ retval = homebank_save_xml_arc(io);
+
+ retval = homebank_save_xml_ope(io);
+
+ g_io_channel_write_chars(io, "</homebank>\n", -1, NULL, NULL);
+
+ g_io_channel_unref (io);
- g_io_channel_unref (io);
- }
return retval;
}
#include "homebank.h"
+#include "ext.h"
- #include "dsp_mainwindow.h"
+ #include "dsp-mainwindow.h"
#include "hb-preferences.h"
#include "language.h"
#include "homebank.h"
#include "ui-pref.h"
- #include "dsp_mainwindow.h"
+ #include "dsp-mainwindow.h"
#include "gtk-chart-colors.h"
+#include "ext.h"
+
#include "ui-currency.h"
static gchar *pref_iconname[PREF_MAX] = {
"prf-general",
"prf-interface",
+ "prf-locale",
"prf-columns",
- "prf-display",
-//"prf-display",
++//"prf-display",
"prf-import",
"prf-report",
+ "prf-backup",
+ "prf-folder",
"prf-euro", // to be renamed
+"prf-plugins",
//"prf_charts.svg"
};
static gchar *pref_name[PREF_MAX] = {
N_("General"),
N_("Interface"),
+ N_("Locale"),
N_("Transactions"),
- N_("Display format"),
N_("Import/Export"),
N_("Report"),
-N_("Euro minor")
+ N_("Backup"),
+ N_("Folders"),
+N_("Euro minor"),
+N_("Plugins")
//
};
gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
-
+
label = make_label_group(_("OFX/QFX options"));
gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
-
+
row = 1;
- label = make_label_widget(_("_Name field:"));
+ label = make_label_widget(_("OFX _Name:"));
//----------------------------------------- l, r, t, b
gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
widget = make_cycle(label, CYA_IMPORT_OFXNAME);
gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
-
+
label = make_label_group(_("QIF options"));
gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
-
+
row = 1;
- label = make_label_widget(_("Memos:"));
- gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
- widget = gtk_check_button_new_with_mnemonic (_("_Import"));
+ widget = gtk_check_button_new_with_mnemonic (_("_Import memos"));
data->CM_dtex_qifmemo = widget;
- gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
- widget = gtk_check_button_new_with_mnemonic (_("_Swap with payees"));
+ gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 1, 1);
+ widget = gtk_check_button_new_with_mnemonic (_("_Swap memos with payees"));
data->CM_dtex_qifswap = widget;
- gtk_grid_attach (GTK_GRID (group_grid), widget, 3, row, 1, 1);
-
+ gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
- // group :: Files folder
+ // group :: other options
group_grid = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
-
+
- label = make_label_group(_("Files folder"));
+ label = make_label_group(_("Other options"));
gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
row = 1;
- label = make_label_widget(_("_Import:"));
- //----------------------------------------- l, r, t, b
- gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
-
- hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_widget_set_hexpand (hbox, TRUE);
- gtk_grid_attach (GTK_GRID (group_grid), hbox, 2, row, 1, 1);
-
- widget = make_string(label);
- data->ST_path_import = widget;
- gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(widget)), GTK_STYLE_CLASS_LINKED);
- gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
-
- //widget = gtk_button_new_with_label("...");
- widget = gtk_button_new_from_icon_name(ICONNAME_FOLDER, GTK_ICON_SIZE_BUTTON);
- data->BT_path_import = widget;
- gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
-
- row++;
- label = make_label_widget(_("_Export:"));
- //----------------------------------------- l, r, t, b
- gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
-
- hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_widget_set_hexpand (hbox, TRUE);
- gtk_grid_attach (GTK_GRID (group_grid), hbox, 2, row, 1, 1);
-
- widget = make_string(label);
- data->ST_path_export = widget;
- gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(widget)), GTK_STYLE_CLASS_LINKED);
- gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
+ widget = gtk_check_button_new_with_mnemonic (_("Sentence _case memo/payee"));
+ data->CM_dtex_ucfirst = widget;
+ gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 1, 1);
-
+
- //widget = gtk_button_new_with_label("...");
- widget = gtk_button_new_from_icon_name(ICONNAME_FOLDER, GTK_ICON_SIZE_BUTTON);
- data->BT_path_export = widget;
- gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
return content_grid;
}
gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
-
+
label = make_label_group(_("Initial filter"));
gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
-
+
row = 1;
- label = make_label_widget(_("Date _range:"));
+ label = make_label_widget(_("_Range:"));
//----------------------------------------- l, r, t, b
gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
widget = make_daterange(label, FALSE);
gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
-
+
- label = make_label_group(_("Date"));
+ label = make_label_group(_("User interface"));
gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
row = 1;
data->CM_herit_date = widget;
gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 2, 1);
-
+ // group :: Memo autocomplete
+ group_grid = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
+ gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
+ gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
++
+ label = make_label_group(_("Memo autocomplete"));
+ gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
+
+ row = 1;
+ widget = gtk_check_button_new_with_mnemonic (_("Active"));
+ data->CM_memoacp = widget;
+ gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 2, 1);
+
+ row++;
+ widget = make_numeric(NULL, 0, 1460);
+ data->ST_memoacp_days = widget;
+ gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
+ label = make_label(_("rolling days"), 0, 0.5);
+ gtk_grid_attach (GTK_GRID (group_grid), label, 3, row, 1, 1);
+
// group :: Column list
/*
group_grid = gtk_grid_new ();
//----------------------------------------- l, r, t, b
gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
+ data->GR_colors = hbox;
gtk_grid_attach (GTK_GRID (group_grid), hbox, 2, row, 1, 1);
-
+
widget = gtk_color_button_new ();
data->CP_exp_color = widget;
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
-
+
- label = make_label_group(_("Program start"));
+ label = make_label_group(_("Backup"));
gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
row = 1;
gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
-
+
- label = make_label_group(_("Fiscal year"));
+ label = make_label_group(_("HomeBank files"));
gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
row = 1;
gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
-
+
- label = make_label_group(_("Main window reports"));
+ label = make_label_group(_("Exchange files"));
gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
-
+
row = 1;
- label = make_label_widget(_("Date _range:"));
+ label = make_label_widget(_("_Import:"));
+ //----------------------------------------- l, r, t, b
gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
- widget = make_daterange(label, FALSE);
- data->CY_daterange_wal = widget;
- gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
- // group :: Files folder
- group_grid = gtk_grid_new ();
- gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
- gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
- gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_widget_set_hexpand (hbox, TRUE);
+ gtk_grid_attach (GTK_GRID (group_grid), hbox, 2, row, 1, 1);
- label = make_label_group(_("Files folder"));
- gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
+ widget = make_string(label);
+ data->ST_path_import = widget;
+ gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(widget)), GTK_STYLE_CLASS_LINKED);
+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
- row = 1;
- label = make_label_widget(_("_Default:"));
+ //widget = gtk_button_new_with_label("...");
+ widget = gtk_button_new_from_icon_name(ICONNAME_FOLDER, GTK_ICON_SIZE_BUTTON);
+ data->BT_path_import = widget;
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+ row++;
+ label = make_label_widget(_("_Export:"));
+ //----------------------------------------- l, r, t, b
gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
//widget = gtk_button_new_with_label("...");
widget = gtk_button_new_from_icon_name(ICONNAME_FOLDER, GTK_ICON_SIZE_BUTTON);
- data->BT_path_hbfile = widget;
+ data->BT_path_export = widget;
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
-
+
+
+ return content_grid;
+ }
+
+
+ static GtkWidget *defpref_page_general (struct defpref_data *data)
+ {
+ GtkWidget *content_grid, *group_grid, *label, *widget;
+ gint crow, row;
+
+ content_grid = gtk_grid_new();
+ gtk_grid_set_row_spacing (GTK_GRID (content_grid), SPACING_LARGE);
+ gtk_orientable_set_orientation(GTK_ORIENTABLE(content_grid), GTK_ORIENTATION_VERTICAL);
+
+ crow = 0;
+ // group :: Program start
+ group_grid = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
+ gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
+ gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
-
++
+ label = make_label_group(_("Program start"));
+ gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
+
+ row = 1;
+ widget = gtk_check_button_new_with_mnemonic (_("Show splash screen"));
+ data->CM_show_splash = widget;
+ gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 2, 1);
+
+ row++;
+ widget = gtk_check_button_new_with_mnemonic (_("Load last opened file"));
+ data->CM_load_last = widget;
+ gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 2, 1);
+
+ row++;
+ widget = gtk_check_button_new_with_mnemonic (_("Post pending scheduled transactions"));
+ data->CM_append_scheduled = widget;
+ gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 2, 1);
+
+ row++;
+ widget = gtk_check_button_new_with_mnemonic (_("Update currencies online"));
+ data->CM_do_update_currency = widget;
+ gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 2, 1);
+
+
+ // group :: Main window reports
+ group_grid = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
+ gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
+ gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
++
+ label = make_label_group(_("Main window reports"));
+ gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
+
+ row = 1;
+ label = make_label(_("_Range:"), 0, 0.5);
+ gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
+ widget = make_daterange(label, FALSE);
+ data->CY_daterange_wal = widget;
+ gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
+
return content_grid;
}
//connect all our signals
g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
- g_signal_connect (G_OBJECT (data.BT_clear), "clicked", G_CALLBACK (defpref_clear), NULL);
+ g_signal_connect (data.CM_bak_is_automatic, "toggled", G_CALLBACK (defpref_backuptoggle), NULL);
+
-
+
//path selector
- g_signal_connect (data.BT_path_hbfile, "pressed", G_CALLBACK (defpref_pathselect), GINT_TO_POINTER(1));
- g_signal_connect (data.BT_path_import, "pressed", G_CALLBACK (defpref_pathselect), GINT_TO_POINTER(2));
- g_signal_connect (data.BT_path_export, "pressed", G_CALLBACK (defpref_pathselect), GINT_TO_POINTER(3));
+ g_signal_connect (data.BT_path_hbfile, "pressed", G_CALLBACK (defpref_pathselect), GINT_TO_POINTER(PRF_PATH_WALLET));
+ g_signal_connect (data.BT_path_import, "pressed", G_CALLBACK (defpref_pathselect), GINT_TO_POINTER(PRF_PATH_IMPORT));
+ g_signal_connect (data.BT_path_export, "pressed", G_CALLBACK (defpref_pathselect), GINT_TO_POINTER(PRF_PATH_EXPORT));
g_signal_connect (data.CM_custom_colors, "toggled", G_CALLBACK (defpref_colortoggle), NULL);
g_signal_connect (data.CY_colors, "changed", G_CALLBACK (defpref_colorpreset), NULL);
g_free(old_lang);
break;
+
+ case 55:
+ defpref_reset (window, NULL);
+ break;
}
-
+
// cleanup and destroy
//defhbfile_cleanup(&data, result);
GtkWidget *BT_go_up;
GtkWidget *BT_go_down;
- GtkWidget *NB_fiscyearday;
- GtkWidget *CY_fiscyearmonth;
--
++
GtkWidget *CM_runwizard;
- GtkWidget *ST_path_hbfile, *BT_path_hbfile;
GtkWidget *ST_path_import, *BT_path_import;
GtkWidget *ST_path_export, *BT_path_export;
GtkWidget *CY_daterange_txn;
GtkWidget *ST_datefuture_nbdays;
GtkWidget *CY_daterange_rep;
--
++
/* currencies */
GtkWidget *LB_default;
-- GtkWidget *BT_default;
--
++ GtkWidget *BT_default;
++
GtkWidget *CM_euro_enable;
GtkWidget *GRP_currency;
GtkWidget *GRP_rate;
GtkWidget *GRP_format;
--
++
GtkWidget *CY_euro_preset;
GtkWidget *ST_euro_country;
GtkWidget *NB_euro_value;
GtkWidget *ST_euro_symbol;
GtkWidget *CM_euro_isprefix;
-- GtkWidget *ST_euro_decimalchar;
-- GtkWidget *ST_euro_groupingchar;
++ GtkWidget *ST_euro_decimalchar;
++ GtkWidget *ST_euro_groupingchar;
GtkWidget *NB_euro_fracdigits;
GtkWidget *LB_numbereuro;
gint country;
+ GtkWidget *PI_plugin_columns;
};
- PREF_TRANSACTIONS,
- PREF_DISPLAY_FORMAT,
- PREF_IMPORT_EXPORT,
+enum
+{
+ PREF_GENERAL,
+ PREF_INTERFACE,
- PREF_EURO_MINOR,
++ PREF_LOCALE, //old DISPLAY
++ PREF_TXN, //old COLUMNS
++ PREF_IMPORT,
+ PREF_REPORT,
++ PREF_BACKUP,
++ PREF_FOLDERS,
++ PREF_EURO,
+ PREF_PLUGINS,
+ PREF_MAX
+};
-typedef struct
+
- typedef struct
++typedef struct
{
gchar *locale;
gchar *name;
hicolor_status_48x48_prf-general.png \
hicolor_status_48x48_prf-import.png \
hicolor_status_48x48_prf-interface.png \
+ hicolor_status_48x48_prf-locale.png \
hicolor_status_48x48_prf-report.png \
+ hicolor_status_48x48_prf-plugins.png \
+ hicolor_actions_scalable_edit-split-symbolic.svg \
hicolor_actions_scalable_toggle-sign-symbolic.svg \
- hicolor_actions_scalable_btn-collapse-symbolic.svg \
- hicolor_actions_scalable_btn-expand-symbolic.svg \
+ hicolor_actions_scalable_list-collapse-all-symbolic.svg \
+ hicolor_actions_scalable_list-expand-all-symbolic.svg \
$(NULL)