# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.52)
- AC_INIT([homebank], [5.1.2])
+ AC_INIT([homebank], [5.1.3])
#AC_INIT([homebank], [x.x-rc])
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE([1.9 foreign])
+LT_PREREQ([2.2])
+LT_INIT([dlopen])
+AC_CONFIG_MACRO_DIR([m4])
+
# If the source code has changed at all, increment REVISION
# If any interfaces have been added, removed, or changed, increment CURRENT, and set REVISION to 0.
# If any interfaces have been added since the last public release, then increment AGE.
AC_PROG_INTLTOOL
# Checks for libraries.
-PKG_CHECK_MODULES(DEPS, gtk+-3.0 >= 3.12 glib-2.0 >= 2.39)
+PKG_CHECK_MODULES(DEPS, gtk+-3.0 >= 3.12 glib-2.0 >= 2.39 gmodule-2.0 >= 2.39)
AC_SUBST(DEPS_CFLAGS)
AC_SUBST(DEPS_LIBS)
AC_CHECK_LIB(m, pow)
AC_SUBST(LIBSOUP_CFLAGS)
AC_SUBST(LIBSOUP_LIBS)
- # general usage flags
+ # release flags
CFLAGS="${CFLAGS} -Wall -Wmissing-prototypes"
# disable deprecated warnings
then
AC_CHECK_LIB(ofx, ofx_set_status_cb, OFX_0_7="-DOFX_ENABLE")
DEPS_LIBS="-lofx ${DEPS_LIBS}"
- CFLAGS="${CFLAGS} $OFX_0_7"
+ CPPFLAGS="${CPPFLAGS} $OFX_0_7"
else
noofx=true
AC_MSG_RESULT([Libofx header missing. Check your libofx installation])
fi
AM_CONDITIONAL(NOOFX, test x$noofx = xtrue)
+AC_ARG_WITH(perl,
+ [ --with-perl build with perl plug-in support [default=without]],
+ [build_perl=$withval],
+ [build_perl=no]
+)
+if test x$build_perl != xno
+then
+ test x$build_perl != xyes -a -x "$build_perl" && PERL=$build_perl
+ AC_PATH_PROG(PERL, perl, perl)
+ AC_MSG_CHECKING(if perl can be embedded)
+ if $PERL -MExtUtils::Embed -e "use v5.8" >/dev/null 2>&1
+ then
+ AC_MSG_RESULT(yes)
+ CPPFLAGS="${CPPFLAGS} -DPERL_ENABLE"
+ PERL_CPPFLAGS="`$PERL -MExtUtils::Embed -e ccopts`"
+ PERL_OBJS="ext-perl.o perlxsi.o"
+ PERL_PRIVLIBEXP="`$PERL -MConfig -e 'print $Config{privlibexp}'`"
+ PERL_SITELIBEXP="`$PERL -MConfig -e 'print $Config{sitelibexp}'`"
+ DEPS_LIBS="`$PERL -MExtUtils::Embed -e ldopts` ${DEPS_LIBS}"
+ if test -e "$PERL_SITELIBEXP/ExtUtils/xsubpp"
+ then
+ XSUBPP="$PERL $PERL_SITELIBEXP/ExtUtils/xsubpp"
+ else
+ XSUBPP="$PERL $PERL_PRIVLIBEXP/ExtUtils/xsubpp"
+ fi
+ else
+ AC_MSG_ERROR([no working perl found, or perl not version >= 5.8])
+ fi
+fi
+AC_SUBST(PERL_CPPFLAGS)
+AC_SUBST(PERL_OBJS)
+AC_SUBST(PERL_PRIVLIBEXP)
+AC_SUBST(PERL_SITELIBEXP)
+AC_SUBST(XSUBPP)
+
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([libintl.h locale.h stdlib.h string.h])
po/Makefile.in
doc/Makefile
doc/images/Makefile
+plugins/Makefile
])
AC_OUTPUT
echo
echo Compiler................ : $CC
echo Build with OFX support.. : $build_ofx
+echo Build with perl support. : $build_perl
if test "x$noofx" = "xtrue" ; then
echo ........................ : **error** libofx header is missing, ofx feature will be disabled. Check your libofx installation
fi
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
#include "dsp_mainwindow.h"
+#include "ext.h"
+
#include "list_account.h"
#include "list_upcoming.h"
#include "list_topspending.h"
static void ui_mainwindow_action_anonymize(void);
static void ui_mainwindow_action_file_statistics(void);
+static void ui_mainwindow_action_pluginprefs(void);
+
static void ui_mainwindow_action_help(void);
void ui_mainwindow_action_help_welcome(void);
static void ui_mainwindow_action_help_online(void);
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);
+
extern gchar *CYA_ACC_TYPE[];
gchar *CYA_CATSUBCAT[] = {
{ "TxnMenu" , NULL, N_("_Transactions"), NULL, NULL, NULL },
{ "ReportMenu" , NULL, N_("_Reports"), NULL, NULL, NULL },
{ "ToolsMenu" , NULL, N_("_Tools"), NULL, NULL, NULL },
+ { "PluginMenu" , NULL, N_("_Plugins"), NULL, NULL, NULL },
{ "HelpMenu" , NULL, N_("_Help"), NULL, NULL, NULL },
// { "Import" , NULL, N_("Import") },
{ "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) },
" <separator/>"
" <menuitem action='Anonymize'/>"
" </menu>"
+" <menu action='PluginMenu'>"
+" <separator/>"
+" <menuitem action='PluginPreferences'/>"
+" <separator/>"
+" </menu>"
" <menu action='HelpMenu'>"
" <menuitem action='Contents'/>"
" <separator/>"
" <toolitem action='RBalance'/>"
" <toolitem action='RBudget'/>"
" <toolitem action='RVehiculeCost'/>"
+" <separator/>"
" </toolbar>"
"</ui>";
static const gchar *authors[] = {
"Lead developer:\n" \
"Maxime DOYEN",
- "\nContributor:\n" \
+ "\nContributors:\n" \
+ "Charles MCGARVEY (Plugin system, Perl support)\n" \
"Ga\xc3\xabtan LORIDANT (Maths formulas for charts)\n",
NULL
};
};
*/
- static const gchar *copyright = "Copyright \xc2\xa9 1995-2016 - Maxime DOYEN";
+ static const gchar *copyright = "Copyright \xc2\xa9 1995-2017 - Maxime DOYEN";
}
+static void ui_mainwindow_action_pluginprefs(void)
+{
+ ui_mainwindow_showprefs(PREF_PLUGINS);
+}
+
+
static void ui_mainwindow_action_properties(void)
{
create_defhbfile_dialog();
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");
- defpref_dialog_new();
+ defpref_dialog_new(page);
if(!PREFS->euro_active)
{
GtkToggleAction *action = (GtkToggleAction *)gtk_ui_manager_get_action(data->manager, "/MenuBar/ViewMenu/AsMinor");
// top spending
gtk_chart_show_minor(GTK_CHART(data->RE_pie), GLOBALS->minor);
- hb_label_set_amount(GTK_LABEL(data->TX_topamount), data->toptotal, GLOBALS->kcur, GLOBALS->minor);
+
+ ui_panel_topspending_update(data->window, data);
}
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;
+
hbfile_cleanup(file_clear);
hbfile_setup(file_clear);
/* init the transaction */
date = homebank_app_date_get_julian();
- //todo: maybe think about set a default account here
- account = 1;
+
+ //#1656531
+ account = 0;
if(data->acc != NULL)
account = data->acc->key;
gdouble value;
};
+
+ #define MAX_TOPSPENDING 5
+
+
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)
+ {
+ struct hbfile_data *data;
+ GtkTreeModel *model;
+ gchar *title;
+ gchar strbuffer[G_ASCII_DTOSTR_BUF_SIZE];
+
+ DB( g_print("\n[ui-mainwindow] topspending_update\n") );
+
+ data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
+
+ 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);
+
+ 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(title);
+
+ //future usage
+ gchar *fu = _("Top %d spending"); title = fu;
+ }
+
+
static void ui_mainwindow_populate_topspending(GtkWidget *widget, gpointer user_data)
{
struct hbfile_data *data;
gdouble total, other;
Account *acc;
- #define MAX_TOPSPENDING 5
DB( g_print("\n[ui-mainwindow] populate_topspending\n") );
gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_top), model);
g_object_unref(model);
- data->toptotal = total;
- hb_label_set_amount(GTK_LABEL(data->TX_topamount), total, GLOBALS->kcur, GLOBALS->minor);
-
- 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, NULL, NULL);
- //gtk_chart_show_legend(GTK_CHART(data->RE_pie), FALSE);
-
- /* update info range text */
+
+ // 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);
}
+ 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;
+
+ nballoc = da_acc_length ();
+ 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;
+
+ if( showall || !(acc->flags & (AF_CLOSED|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;
GtkTreeIter iter1, child_iter;
GList *lacc, *elt;
Account *acc;
- guint i, j, nbtype;
+ 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 */
-
- GPtrArray *typeacc[ACC_TYPE_MAXVALUE] = {0};
lacc = elt = g_hash_table_get_values(GLOBALS->h_acc);
- while (elt != NULL)
- {
- acc = elt->data;
- //#1339572
- if( !(acc->flags & (AF_CLOSED|AF_NOSUMMARY)) )
- {
- DB( g_print(" - insert %d:%s\n", acc->key, acc->name) );
-
- if(typeacc[acc->type] == NULL)
- typeacc[acc->type] = g_ptr_array_sized_new(da_acc_length ());
-
- g_ptr_array_add(typeacc[acc->type], (gpointer)acc);
- }
- elt = g_list_next(elt);
- }
+
+ 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\n") );
+ gtbank = gttoday = gtfuture = 0;
+ DB( g_print(" populate listview\n") );
- /* then populate the listview */
model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_acc));
gtk_tree_store_clear (GTK_TREE_STORE(model));
nbtype = 0;
- for(i=0;i<ACC_TYPE_MAXVALUE;i++)
+ g_hash_table_iter_init (&grp_iter, h_group);
+ while (g_hash_table_iter_next (&grp_iter, &key, &value))
{
- GPtrArray *gpa = typeacc[i];
+ GPtrArray *gpa = value;
gdouble tbank, ttoday, tfuture;
if(gpa != NULL)
{
nbtype++;
//1: Header: Bank, Cash, ...
- DB( g_print(" - append type '%s'\n", CYA_ACC_TYPE[i]) );
+ //DB( g_print(" - append type '%s'\n", CYA_ACC_TYPE[i]) );
+ DB( g_print("\n - append type '%d'\n", key) );
gtk_tree_store_append (GTK_TREE_STORE(model), &iter1, NULL);
gtk_tree_store_set (GTK_TREE_STORE(model), &iter1,
LST_DSPACC_DATATYPE, DSPACC_TYPE_HEADER,
- LST_DSPACC_NAME, _(CYA_ACC_TYPE[i]),
+ LST_DSPACC_NAME, key,
-1);
tbank = ttoday = tfuture = 0;
}
/* set balance to header to display when collasped */
+ DB( g_print(" - enrich totals to 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,
DB( g_print(" - free ressources\n") );
-
- /* free all temp stuff */
- for(i=0;i<ACC_TYPE_MAXVALUE;i++)
+ g_hash_table_iter_init (&grp_iter, h_group);
+ while (g_hash_table_iter_next (&grp_iter, &key, &value))
{
- GPtrArray *gpa = typeacc[i];
-
- if(gpa != NULL)
- g_ptr_array_free (gpa, TRUE);
+ g_ptr_array_free (value, TRUE);
}
-
+ g_hash_table_destroy (h_group);
}
gchar *basename;
gchar *changed;
- DB( g_print(" + 1: wintitle %x\n", (gint)data->wintitle) );
+ DB( g_print(" + 1: wintitle %x\n", data->wintitle) );
basename = g_path_get_basename(GLOBALS->xhb_filepath);
DB( g_print(" + 2: disabled, opelist count\n") );
- selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_acc));
+ //#1656531
+ data->acc = NULL;
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_acc));
active = gtk_tree_selection_get_selected(selection, &model, &iter);
if(active)
{
gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, LST_DSPACC_DATAS, &acc, -1);
data->acc = acc;
-
}
else
active = FALSE;
}
- else
- {
- //ensure data->acc will not be null
- data->acc = da_acc_get(1);
- }
// no change: disable save
struct WinGeometry *wg;
gboolean retval = FALSE;
+ GValue widget_value = G_VALUE_INIT;
+ ext_hook("main_window_disposal", EXT_OBJECT(&widget_value, widget), NULL);
+
DB( g_print("\n[ui-mainwindow] dispose\n") );
//store position and size
}
else
{
- DB( g_print(" free wintitle %x\n", (gint)data->wintitle) );
+ DB( g_print(" free wintitle %x\n", data->wintitle) );
gtk_widget_destroy(data->LV_top);
GtkSelectionData *selection_data,
guint info, guint time, GtkWindow *window)
{
- gchar **uris, **str;
- gchar *newseldata;
- gint filetype, slen;
+ gchar **uris, **str;
+ gchar *newseldata;
+ gint filetype, slen;
if (info != TARGET_URI_LIST)
return;
uris = g_uri_list_extract_uris (newseldata);
+ DB( g_print(" - dragged %d %d files\n", slen, g_strv_length(uris) ) );
+
str = uris;
//for (str = uris; *str; str++)
if( *str )
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,
_("File error"),
static void ui_mainwindow_create_menu_bar_and_toolbar(struct hbfile_data *data, GtkWidget *mainvbox)
{
GtkUIManager *manager;
- GtkActionGroup *action_group;
+ GtkActionGroup *actions;
GtkAction *action;
GError *error = NULL;
gtk_window_add_accel_group (GTK_WINDOW (data->window),
gtk_ui_manager_get_accel_group(manager));
- action_group = gtk_action_group_new ("MainWindow");
- gtk_action_group_set_translation_domain(action_group, GETTEXT_PACKAGE);
+ actions = gtk_action_group_new ("MainWindow");
+ gtk_action_group_set_translation_domain(actions, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (action_group,
+ gtk_action_group_add_actions (actions,
entries,
n_entries,
NULL);
- gtk_action_group_add_toggle_actions (action_group,
+ gtk_action_group_add_toggle_actions (actions,
toggle_entries,
n_toggle_entries,
NULL);
- gtk_ui_manager_insert_action_group (data->manager, action_group, 0);
- g_object_unref (action_group);
- data->actions = action_group;
+ gtk_ui_manager_insert_action_group (data->manager, actions, 0);
+ g_object_unref (actions);
+ data->actions = actions;
/* set short labels to use in the toolbar */
- action = gtk_action_group_get_action(action_group, "Open");
+ action = gtk_action_group_get_action(actions, "Open");
g_object_set(action, "short_label", _("Open"), NULL);
//action = gtk_action_group_get_action(action_group, "Save");
//g_object_set(action, "is_important", TRUE, NULL);
- action = gtk_action_group_get_action(action_group, "Account");
+ action = gtk_action_group_get_action(actions, "Account");
g_object_set(action, "short_label", _("Account"), NULL);
- action = gtk_action_group_get_action(action_group, "Payee");
+ action = gtk_action_group_get_action(actions, "Payee");
g_object_set(action, "short_label", _("Payee"), NULL);
- action = gtk_action_group_get_action(action_group, "Category");
+ action = gtk_action_group_get_action(actions, "Category");
g_object_set(action, "short_label", _("Category"), NULL);
- action = gtk_action_group_get_action(action_group, "Archive");
+ action = gtk_action_group_get_action(actions, "Archive");
//TRANSLATORS: an archive is stored transaction buffers (kind of bookmark to prefill manual insertion)
g_object_set(action, "short_label", _("Archive"), NULL);
- action = gtk_action_group_get_action(action_group, "Budget");
+ action = gtk_action_group_get_action(actions, "Budget");
g_object_set(action, "short_label", _("Budget"), NULL);
- action = gtk_action_group_get_action(action_group, "ShowOpe");
+ action = gtk_action_group_get_action(actions, "ShowOpe");
g_object_set(action, "short_label", _("Show"), NULL);
- action = gtk_action_group_get_action(action_group, "AddOpe");
+ action = gtk_action_group_get_action(actions, "AddOpe");
g_object_set(action, "is_important", TRUE, "short_label", _("Add"), NULL);
- action = gtk_action_group_get_action(action_group, "RStatistics");
+ action = gtk_action_group_get_action(actions, "RStatistics");
g_object_set(action, "short_label", _("Statistics"), NULL);
- action = gtk_action_group_get_action(action_group, "RBudget");
+ action = gtk_action_group_get_action(actions, "RBudget");
g_object_set(action, "short_label", _("Budget"), NULL);
- action = gtk_action_group_get_action(action_group, "RBalance");
+ action = gtk_action_group_get_action(actions, "RBalance");
g_object_set(action, "short_label", _("Balance"), NULL);
- action = gtk_action_group_get_action(action_group, "RVehiculeCost");
+ action = gtk_action_group_get_action(actions, "RVehiculeCost");
g_object_set(action, "short_label", _("Vehicle cost"), NULL);
/* now load the UI definition */
}
- static GtkWidget *ui_mainwindow_create_youraccounts(struct hbfile_data *data)
+ /* Callback function for the undo action */
+ /*static void
+ activate_action (GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
- GtkWidget *mainvbox, *label, *widget, *sw;
+ g_print ("Action %s activated\n", g_action_get_name (G_ACTION (action)));
+ }*/
- mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ static void
+ activate_toggle (GSimpleAction *action, GVariant *parameter, gpointer user_data)
+ {
+ struct hbfile_data *data = user_data;
+ GVariant *old_state, *new_state;
- label = make_label_group(_("Your accounts"));
- gtk_widget_set_margin_top(GTK_WIDGET(label), SPACING_SMALL/2);
- gtk_widget_set_margin_bottom(GTK_WIDGET(label), SPACING_SMALL/2);
- gtk_widget_set_margin_start(GTK_WIDGET(label), SPACING_SMALL);
- gtk_widget_set_margin_end(GTK_WIDGET(label), SPACING_SMALL);
- gtk_box_pack_start (GTK_BOX (mainvbox), label, FALSE, FALSE, 0);
+ old_state = g_action_get_state (G_ACTION (action));
+ new_state = g_variant_new_boolean (!g_variant_get_boolean (old_state));
+
+ DB( g_print ("Toggle action %s activated, state changes from %d to %d\n",
+ g_action_get_name (G_ACTION (action)),
+ g_variant_get_boolean (old_state),
+ g_variant_get_boolean (new_state)) );
+
+ data->showall = g_variant_get_boolean (new_state);
+ ui_mainwindow_populate_accounts(GLOBALS->mainwindow, NULL);
+
+ g_simple_action_set_state (action, new_state);
+ g_variant_unref (old_state);
+ }
+
+ static void
+ activate_radio (GSimpleAction *action, GVariant *parameter, gpointer user_data)
+ {
+ //struct hbfile_data *data = user_data;
+ GVariant *old_state, *new_state;
+
+ old_state = g_action_get_state (G_ACTION (action));
+ new_state = g_variant_new_string (g_variant_get_string (parameter, NULL));
+
+ DB( g_print ("Radio action %s activated, state changes from %s to %s\n",
+ g_action_get_name (G_ACTION (action)),
+ g_variant_get_string (old_state, NULL),
+ g_variant_get_string (new_state, NULL)) );
+
+ PREFS->pnl_acc_show_by = DSPACC_GROUP_BY_TYPE;
+ if( !strcmp("bank", g_variant_get_string(new_state, NULL)) )
+ PREFS->pnl_acc_show_by = DSPACC_GROUP_BY_BANK;
+
+ ui_mainwindow_populate_accounts(GLOBALS->mainwindow, NULL);
+
+ g_simple_action_set_state (action, new_state);
+ g_variant_unref (old_state);
+ }
+
+
+ static const GActionEntry actions[] = {
+ // { "paste", activate_action, NULL, NULL, NULL, {0,0,0} },
+ { "showall" , activate_toggle, NULL, "false", NULL, {0,0,0} },
+ { "groupby", activate_radio, "s", "'type'", NULL, {0,0,0} }
+ };
+
+
+ static GtkWidget *ui_mainwindow_create_youraccounts(struct hbfile_data *data)
+ {
+ GtkWidget *panel, *label, *widget, *sw, *tbar, *hbox, *image;
+ GtkToolItem *toolitem;
+
+ panel = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(panel), SPACING_SMALL);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- //gtk_widget_set_margin_top(GTK_WIDGET(sw), 0);
- gtk_widget_set_margin_bottom(GTK_WIDGET(sw), SPACING_SMALL);
- gtk_widget_set_margin_start(GTK_WIDGET(sw), 2*SPACING_SMALL);
- gtk_widget_set_margin_end(GTK_WIDGET(sw), SPACING_SMALL);
- gtk_box_pack_start (GTK_BOX (mainvbox), sw, TRUE, TRUE, 0);
-
+ gtk_box_pack_start (GTK_BOX (panel), sw, TRUE, TRUE, 0);
widget = (GtkWidget *)create_list_account();
data->LV_acc = widget;
gtk_container_add (GTK_CONTAINER (sw), widget);
- return mainvbox;
+ //list toolbar
+ tbar = gtk_toolbar_new();
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR(tbar), GTK_ICON_SIZE_MENU);
+ gtk_toolbar_set_style(GTK_TOOLBAR(tbar), GTK_TOOLBAR_ICONS);
+ gtk_style_context_add_class (gtk_widget_get_style_context (tbar), GTK_STYLE_CLASS_INLINE_TOOLBAR);
+ gtk_box_pack_start (GTK_BOX (panel), tbar, FALSE, FALSE, 0);
+
+ label = make_label_group(_("Your accounts"));
+ toolitem = gtk_tool_item_new();
+ gtk_container_add (GTK_CONTAINER(toolitem), label);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
+
+ toolitem = gtk_separator_tool_item_new ();
+ gtk_tool_item_set_expand (toolitem, TRUE);
+ gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ toolitem = gtk_tool_item_new();
+ gtk_container_add (GTK_CONTAINER(toolitem), hbox);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
+
+ widget = make_image_button(ICONNAME_HB_BUTTON_EXPAND, _("Expand all"));
+ data->BT_expandall = widget;
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+ widget = make_image_button(ICONNAME_HB_BUTTON_COLLAPSE, _("Collapse all"));
+ data->BT_collapseall = widget;
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+ toolitem = gtk_separator_tool_item_new ();
+ gtk_tool_item_set_expand (toolitem, FALSE);
+ gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
+
+
+ //gmenu test (see test folder into gtk)
+ widget = gtk_menu_button_new();
+ gtk_menu_button_set_direction (GTK_MENU_BUTTON(widget), GTK_ARROW_UP);
+ gtk_widget_set_halign (widget, GTK_ALIGN_END);
+ image = gtk_image_new_from_icon_name (ICONNAME_EMBLEM_SYSTEM, GTK_ICON_SIZE_MENU);
+ g_object_set (widget, "image", image, NULL);
+
+ toolitem = gtk_tool_item_new();
+ gtk_container_add (GTK_CONTAINER(toolitem), widget);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
+
+ GMenu *menu, *section;
+
+ menu = g_menu_new ();
+ //g_menu_append (menumodel, "About", "actions.undo");
+ //g_menu_append (menumodel, "Test", "actions.redo");
+ section = g_menu_new ();
+ g_menu_append (section, _("Show all"), "actions.showall");
+ g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
+ g_object_unref (section);
+
+ section = g_menu_new ();
+ g_menu_append (section, _("By type"), "actions.groupby::type");
+ g_menu_append (section, _("By institition"), "actions.groupby::bank");
+ g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
+ g_object_unref (section);
+
+
+ GSimpleActionGroup *group = g_simple_action_group_new ();
+ g_action_map_add_action_entries (G_ACTION_MAP (group), actions, G_N_ELEMENTS (actions), data);
+
+ //init radio
+ GAction *action = g_action_map_lookup_action (G_ACTION_MAP (group), "groupby");
+ const gchar *value = (PREFS->pnl_acc_show_by == DSPACC_GROUP_BY_TYPE) ? "type" : "bank";
+ g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_string (value));
+
+ gtk_widget_insert_action_group (widget, "actions", G_ACTION_GROUP(group));
+
+ gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (widget), G_MENU_MODEL (menu));
+
+ return panel;
}
static GtkWidget *ui_mainwindow_create_topspending(struct hbfile_data *data)
{
- GtkWidget *mainvbox, *hbox, *vbox;
+ GtkWidget *panel, *hbox, *tbar;
GtkWidget *label, *widget;
+ GtkToolItem *toolitem;
- mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- data->GR_top = mainvbox;
+ widget = (GtkWidget *)create_list_topspending();
+ data->LV_top = widget;
+
+ panel = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(panel), SPACING_SMALL);
+ data->GR_top = panel;
+
+ /* chart + listview */
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_pack_start (GTK_BOX (panel), hbox, TRUE, TRUE, 0);
+
+ widget = gtk_chart_new(CHART_TYPE_PIE);
+ data->RE_pie = widget;
+ gtk_chart_set_minor_prefs(GTK_CHART(widget), PREFS->euro_value, PREFS->minor_cur.symbol);
+ gtk_chart_show_legend(GTK_CHART(data->RE_pie), TRUE, TRUE);
+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
+
+ //list toolbar
+ tbar = gtk_toolbar_new();
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR(tbar), GTK_ICON_SIZE_MENU);
+ gtk_toolbar_set_style(GTK_TOOLBAR(tbar), GTK_TOOLBAR_ICONS);
+ gtk_style_context_add_class (gtk_widget_get_style_context (tbar), GTK_STYLE_CLASS_INLINE_TOOLBAR);
+ gtk_box_pack_start (GTK_BOX (panel), tbar, FALSE, FALSE, 0);
label = make_label_group(_("Where your money goes"));
- gtk_widget_set_margin_top(GTK_WIDGET(label), SPACING_SMALL/2);
- gtk_widget_set_margin_bottom(GTK_WIDGET(label), SPACING_SMALL/2);
- gtk_widget_set_margin_start(GTK_WIDGET(label), SPACING_SMALL);
- gtk_widget_set_margin_end(GTK_WIDGET(label), SPACING_SMALL);
- gtk_box_pack_start (GTK_BOX (mainvbox), label, FALSE, FALSE, 0);
+ toolitem = gtk_tool_item_new();
+ gtk_container_add (GTK_CONTAINER(toolitem), label);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
+ toolitem = gtk_separator_tool_item_new ();
+ gtk_tool_item_set_expand (toolitem, TRUE);
+ gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_SMALL);
- //gtk_widget_set_margin_top(GTK_WIDGET(vbox), 0);
- gtk_widget_set_margin_bottom(GTK_WIDGET(vbox), SPACING_SMALL);
- gtk_widget_set_margin_start(GTK_WIDGET(vbox), 2*SPACING_SMALL);
- gtk_widget_set_margin_end(GTK_WIDGET(vbox), SPACING_SMALL);
- gtk_box_pack_start (GTK_BOX (mainvbox), vbox, TRUE, TRUE, 0);
-
/* total + date range */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
- label = make_label(_("Top spending"), 0.0, 0.5);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ toolitem = gtk_tool_item_new();
+ gtk_container_add (GTK_CONTAINER(toolitem), hbox);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
- label = make_label(NULL, 0.0, 0.5);
- data->TX_topamount = label;
- gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
-
data->CY_range = make_daterange(label, FALSE);
gtk_box_pack_end (GTK_BOX (hbox), data->CY_range, FALSE, FALSE, 0);
data->RA_type = widget;
gtk_box_pack_end (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
- /* pie + listview */
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
-
- widget = gtk_chart_new(CHART_TYPE_PIE);
- data->RE_pie = widget;
- gtk_chart_set_minor_prefs(GTK_CHART(widget), PREFS->euro_value, PREFS->minor_cur.symbol);
- gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
-
- /*
- sw = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_box_pack_start (GTK_BOX (hbox), sw, FALSE, FALSE, 0);
- */
-
- widget = (GtkWidget *)create_list_topspending();
- data->LV_top = widget;
-
- gtk_chart_show_legend(GTK_CHART(data->RE_pie), TRUE, TRUE);
-
- // gtk_container_add (GTK_CONTAINER (sw), widget);
-
- return mainvbox;
+ return panel;
}
static GtkWidget *ui_mainwindow_scheduled_create(struct hbfile_data *data)
{
- GtkWidget *mainvbox, *hbox, *vbox, *bbox, *sw, *tbar;
+ GtkWidget *panel, *hbox, *vbox, *bbox, *sw, *tbar;
GtkWidget *label, *widget;
GtkToolItem *toolitem;
- mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- data->GR_upc = mainvbox;
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
- gtk_box_pack_start (GTK_BOX (mainvbox), hbox, FALSE, FALSE, 0);
+ panel = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(panel), SPACING_SMALL);
+ data->GR_upc = panel;
- label = make_label_group(_("Scheduled transactions"));
- gtk_widget_set_margin_top(GTK_WIDGET(label), SPACING_SMALL/2);
- gtk_widget_set_margin_bottom(GTK_WIDGET(label), SPACING_SMALL/2);
- gtk_widget_set_margin_start(GTK_WIDGET(label), SPACING_SMALL);
- gtk_widget_set_margin_end(GTK_WIDGET(label), SPACING_SMALL);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
- label = make_label(_("maximum post date"), 0.0, 0.7);
- gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
- label = make_label(NULL, 0.0, 0.7);
- data->LB_maxpostdate = label;
- gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
//gtk_widget_set_margin_top(GTK_WIDGET(vbox), 0);
- gtk_widget_set_margin_bottom(GTK_WIDGET(vbox), SPACING_SMALL);
- gtk_widget_set_margin_start(GTK_WIDGET(vbox), 2*SPACING_SMALL);
- gtk_widget_set_margin_end(GTK_WIDGET(vbox), SPACING_SMALL);
- gtk_box_pack_start (GTK_BOX (mainvbox), vbox, TRUE, TRUE, 0);
+ //gtk_widget_set_margin_bottom(GTK_WIDGET(vbox), SPACING_SMALL);
+ //gtk_widget_set_margin_start(GTK_WIDGET(vbox), 2*SPACING_SMALL);
+ //gtk_widget_set_margin_end(GTK_WIDGET(vbox), SPACING_SMALL);
+ gtk_box_pack_start (GTK_BOX (panel), vbox, TRUE, TRUE, 0);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
gtk_style_context_add_class (gtk_widget_get_style_context (tbar), GTK_STYLE_CLASS_INLINE_TOOLBAR);
gtk_box_pack_start (GTK_BOX (vbox), tbar, FALSE, FALSE, 0);
+ label = make_label_group(_("Scheduled transactions"));
+ toolitem = gtk_tool_item_new();
+ gtk_container_add (GTK_CONTAINER(toolitem), label);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
+
+ toolitem = gtk_separator_tool_item_new ();
+ gtk_tool_item_set_expand (toolitem, FALSE);
+ gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
+
+
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
toolitem = gtk_tool_item_new();
gtk_container_add (GTK_CONTAINER(toolitem), bbox);
gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
- widget = gtk_button_new_with_label(_("Skip"));
- data->BT_sched_skip = widget;
- gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
-
- widget = gtk_button_new_with_label(_("Edit & Post"));
- data->BT_sched_editpost = widget;
- gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
+ widget = gtk_button_new_with_label(_("Skip"));
+ data->BT_sched_skip = widget;
+ gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
- //TRANSLATORS: Posting a scheduled transaction is the action to materialize it into its target account.
- //TRANSLATORS: Before that action the automated transaction occurrence is pending and not yet really existing.
- widget = gtk_button_new_with_label (_("Post"));
- data->BT_sched_post = widget;
- gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
+ widget = gtk_button_new_with_label(_("Edit & Post"));
+ data->BT_sched_editpost = widget;
+ gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
+ //TRANSLATORS: Posting a scheduled transaction is the action to materialize it into its target account.
+ //TRANSLATORS: Before that action the automated transaction occurrence is pending and not yet really existing.
+ widget = gtk_button_new_with_label (_("Post"));
+ data->BT_sched_post = widget;
+ gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
- /* image = gtk_image_new_from_icon_name (ICONNAME_HB_SCHED_SKIP, GTK_ICON_SIZE_MENU);
- toolitem = gtk_tool_button_new(image, NULL);
- data->BT_sched_skip = toolitem;
+ toolitem = gtk_separator_tool_item_new ();
+ gtk_tool_item_set_expand (toolitem, FALSE);
+ gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
- gtk_widget_set_tooltip_text(GTK_WIDGET(toolitem), _("Skip"));
- image = gtk_image_new_from_icon_name (ICONNAME_HB_SCHED_POST, GTK_ICON_SIZE_MENU);
- toolitem = gtk_tool_button_new(image, NULL);
- data->BT_sched_post = toolitem;
+ hbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ gtk_widget_set_valign (hbox, GTK_ALIGN_CENTER);
+ toolitem = gtk_tool_item_new();
+ gtk_container_add (GTK_CONTAINER(toolitem), hbox);
gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
- gtk_widget_set_tooltip_text(GTK_WIDGET(toolitem), _("Post"));
- */
-
- return mainvbox;
+ label = make_label(_("maximum post date"), 0.0, 0.7);
+ gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
+ gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ label = make_label(NULL, 0.0, 0.7);
+ data->LB_maxpostdate = label;
+ gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
+ gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ return panel;
}
+
/*
** the window creation
*/
//store our window private data
g_object_set_data(G_OBJECT(window), "inst_data", (gpointer)data);
- DB( g_print(" - new window=%x, inst_data=%0x\n", (gint)window, (gint)data) );
+ DB( g_print(" - new window=%x, inst_data=%0x\n", window, data) );
// this is our mainwindow, so store it to GLOBALS data
data->window = window;
ui_mainwindow_create_menu_bar_and_toolbar (data, mainvbox);
- #if HB_UNSTABLE == TRUE
+ #if HB_UNSTABLE_SHOW == TRUE
GtkWidget *bar, *label;
bar = gtk_info_bar_new ();
filter_default_all_set(data->filter);
gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_range), PREFS->date_range_wal);
-
-
action = gtk_ui_manager_get_action(data->manager, "/MenuBar/ViewMenu/Toolbar");
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), PREFS->wal_toolbar);
action = gtk_ui_manager_get_action(data->manager, "/MenuBar/ViewMenu/Spending");
g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_acc)), "changed", G_CALLBACK (ui_mainwindow_selection), NULL);
- g_signal_connect (GTK_TREE_VIEW(data->LV_acc), "row-activated", G_CALLBACK (ui_mainwindow_onRowActivated), GINT_TO_POINTER(2));
+ g_signal_connect (GTK_TREE_VIEW(data->LV_acc ), "row-activated", G_CALLBACK (ui_mainwindow_onRowActivated), GINT_TO_POINTER(2));
+ g_signal_connect (G_OBJECT (data->BT_expandall ), "clicked" , G_CALLBACK (ui_panel_accounts_expand_all), NULL);
+ g_signal_connect (G_OBJECT (data->BT_collapseall), "clicked" , G_CALLBACK (ui_panel_accounts_collapse_all), NULL);
g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_upc)), "changed", G_CALLBACK (ui_mainwindow_scheduled_selection_cb), NULL);
g_signal_connect (GTK_TREE_VIEW(data->LV_upc), "row-activated", G_CALLBACK (ui_mainwindow_scheduled_onRowActivated), NULL);
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
#include "homebank.h"
#include "hb-account.h"
+#include "ext.h"
+#include "refcount.h"
+
/****************************************************************************/
/* Debug macros */
/****************************************************************************/
da_acc_free(Account *item)
{
DB( g_print("da_acc_free\n") );
- if(item != NULL)
+ if(rc_unref(item))
{
DB( g_print(" => %d, %s\n", item->key, item->name) );
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->txn_queue = g_queue_new ();
return item;
}
*new_key = item->key;
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;
}
DB( g_print(" -> insert id: %d\n", *new_key) );
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;
}
}
lnk_txn = g_queue_peek_head_link(acc->txn_queue);
while (lnk_txn != NULL)
{
- account_balances_add_internal(acc, lnk_txn->data);
+ Transaction *txn = lnk_txn->data;
+
+ if(!(txn->status == TXN_STATUS_REMIND))
+ {
+ account_balances_add_internal(acc, txn);
+ }
lnk_txn = g_list_next(lnk_txn);
}
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
#include "hb-archive.h"
#include "hb-split.h"
+#include "ext.h"
+#include "refcount.h"
+
/****************************************************************************/
/* Debug macros */
/****************************************************************************/
Archive *da_archive_malloc(void)
{
- return g_malloc0(sizeof(Archive));
+ return rc_alloc(sizeof(Archive));
}
Archive *da_archive_clone(Archive *src_item)
{
-Archive *new_item = g_memdup(src_item, sizeof(Archive));
+Archive *new_item = rc_dup(src_item, sizeof(Archive));
if(new_item)
{
void da_archive_free(Archive *item)
{
- if(item != NULL)
+ if(rc_unref(item))
{
if(item->wording != NULL)
g_free(item->wording);
da_splits_free(item->splits);
//item->flags &= ~(OF_SPLIT); //Flag that Splits are cleared
- g_free(item);
+ rc_free(item);
}
}
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
#include "homebank.h"
#include "hb-assign.h"
+#include "ext.h"
+#include "refcount.h"
+
#define MYDEBUG 0
#if MYDEBUG
da_asg_free(Assign *item)
{
DB( g_print("da_asg_free\n") );
- if(item != NULL)
+ if(rc_unref(item))
{
DB( g_print(" => %d, %s\n", item->key, item->text) );
g_free(item->text);
- g_free(item);
+ rc_free(item);
}
}
da_asg_malloc(void)
{
DB( g_print("da_asg_malloc\n") );
- return g_malloc0(sizeof(Assign));
+ return rc_alloc(sizeof(Assign));
}
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
#include "homebank.h"
#include "hb-category.h"
+#include "ext.h"
+#include "refcount.h"
+
/****************************************************************************/
/* Debug macros */
Category *
da_cat_clone(Category *src_item)
{
-Category *new_item = g_memdup(src_item, sizeof(Category));
+Category *new_item = rc_dup(src_item, sizeof(Category));
DB( g_print("da_cat_clone\n") );
if(new_item)
da_cat_free(Category *item)
{
DB( g_print("da_cat_free\n") );
- if(item != NULL)
+ if(rc_unref(item))
{
DB( g_print(" => %d, %s\n", item->key, item->name) );
g_free(item->name);
- g_free(item);
+ rc_free(item);
}
}
da_cat_malloc(void)
{
DB( g_print("da_cat_malloc\n") );
- return g_malloc0(sizeof(Category));
+ return rc_alloc(sizeof(Category));
}
if( tmpstr != NULL )
{
DB( g_print(" + strip %s\n", tmpstr) );
-
hb_string_strip_crlf(tmpstr);
DB( g_print(" + split\n") );
-
str_array = g_strsplit (tmpstr, ";", 3);
// type; sign; name
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
#include "homebank.h"
#include "hb-payee.h"
+#include "ext.h"
+#include "refcount.h"
+
/****************************************************************************/
/* Debug macros */
da_pay_free(Payee *item)
{
DB( g_print("da_pay_free\n") );
- if(item != NULL)
+ if(rc_unref(item))
{
DB( g_print(" => %d, %s\n", item->key, item->name) );
g_free(item->name);
- g_free(item);
+ rc_free(item);
}
}
da_pay_malloc(void)
{
DB( g_print("da_pay_malloc\n") );
- return g_malloc0(sizeof(Payee));
+ return rc_alloc(sizeof(Payee));
}
*
* append a new payee into the GHashTable
*
- * Return value: a new Payee or NULL
+ * Return value: true/false + new payee
*
*/
- Payee *
- payee_append_if_new(gchar *name)
+ gboolean
+ payee_append_if_new(gchar *name, Payee **newpayee)
{
- gchar *stripname;
+ gboolean retval = FALSE;
+ gchar *stripname = g_strdup(name);
Payee *item;
- stripname = g_strdup(name);
g_strstrip(stripname);
item = da_pay_get_by_name(stripname);
-
if(item == NULL)
{
item = da_pay_malloc();
item->name = g_strdup(stripname);
da_pay_append(item);
+ retval = TRUE;
}
- else
- item = NULL;
+ if( newpayee != NULL )
+ *newpayee = item;
g_free(stripname);
- return item;
+ return retval;
}
static gint
- void
- payee_load_csv(gchar *filename)
+ gboolean
+ payee_load_csv(gchar *filename, gchar **error)
{
+ gboolean retval;
GIOChannel *io;
gchar *tmpstr;
gint io_stat;
+ gchar **str_array;
const gchar *encoding;
+ gint nbcol;
encoding = homebank_file_getencoding(filename);
+ retval = TRUE;
+ *error = NULL;
io = g_io_channel_new_file(filename, "r", NULL);
if(io != NULL)
{
{
if( tmpstr != NULL)
{
+ DB( g_print("\n + strip\n") );
hb_string_strip_crlf(tmpstr);
- DB( g_print(" read %s\n", tmpstr) );
+ DB( g_print(" + split '%s'\n", tmpstr) );
+ str_array = g_strsplit (tmpstr, ";", 2);
+ // payee;category : later paymode?
- if( payee_append_if_new( tmpstr ) )
+ nbcol = g_strv_length (str_array);
+ if( nbcol > 2 )
{
- GLOBALS->changes_count++;
+ *error = _("invalid CSV format");
+ retval = FALSE;
+ DB( g_print(" + error %s\n", *error) );
}
-
+ else
+ {
+ gboolean added;
+ Payee *pay = NULL;
+
+ if( nbcol >= 1 )
+ {
+ DB( g_print(" add pay:'%s' ?\n", str_array[0]) );
+ added = payee_append_if_new(str_array[0], &pay);
+ if( added )
+ {
+ DB( g_print(" added: %p\n", pay) );
+ GLOBALS->changes_count++;
+ }
+ }
+
+ if( nbcol == 2 )
+ {
+ Category *cat;
+
+ DB( g_print(" add cat:'%s'\n", str_array[1]) );
+ cat = da_cat_append_ifnew_by_fullname(str_array[1], FALSE);
+
+ DB( g_print(" cat: %p %p\n", cat, pay) );
+ if( cat != NULL )
+ {
+ if( pay != NULL)
+ {
+ DB( g_print(" set default cat to %d\n", cat->key) );
+ pay->kcat = cat->key;
+ }
+ GLOBALS->changes_count++;
+ }
+ }
+ }
+ g_strfreev (str_array);
}
g_free(tmpstr);
}
g_io_channel_unref (io);
}
+ return retval;
}
while (list != NULL)
{
Payee *item = list->data;
+ gchar *fullcatname;
if(item->key != 0)
{
- outstr = g_strdup_printf("%s\n", item->name);
- g_io_channel_write_chars(io, outstr, -1, NULL, NULL);
+ fullcatname = NULL;
+ if( item->kcat > 0 )
+ {
+ Category *cat = da_cat_get(item->kcat);
+
+ if( cat != NULL )
+ {
+ fullcatname = da_cat_get_fullname (cat);
+ }
+ }
+
+ if( fullcatname != NULL )
+ outstr = g_strdup_printf("%s;%s\n", item->name, fullcatname);
+ else
+ outstr = g_strdup_printf("%s;\n", item->name);
- DB( g_print("%s", outstr) );
+ DB( g_print(" + export %s\n", outstr) );
+
+ g_io_channel_write_chars(io, outstr, -1, NULL, NULL);
g_free(outstr);
+ g_free(fullcatname);
+
}
list = g_list_next(list);
}
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
g_free(PREFS->minor_cur.decimal_char);
g_free(PREFS->minor_cur.grouping_char);
+ g_strfreev(PREFS->ext_path);
+ g_list_free_full(PREFS->ext_whitelist, g_free);
+
memset(PREFS, 0, sizeof(struct Preferences));
}
PREFS->wal_vpaned = 600/2;
PREFS->wal_hpaned = 1024/2;
+ PREFS->pnl_acc_col_acc_width = -1;
+ PREFS->pnl_acc_show_by = 0;
+ PREFS->pnl_upc_col_pay_width = -1;
+ PREFS->pnl_upc_col_mem_width = -1;
i = 0;
PREFS->vehicle_unit_ismile = FALSE;
PREFS->vehicle_unit_isgal = FALSE;
+ gchar** plugin_path = g_new0(gchar*, 4);
+ i = 0;
+ const gchar* env = g_getenv("HOMEBANK_PLUGINS");
+ if (env) {
+ if (g_path_is_absolute(env)) {
+ plugin_path[i++] = g_strdup(env);
+ } else {
+ gchar* cur = g_get_current_dir();
+ plugin_path[i++] = g_build_filename(cur, env, NULL);
+ g_free(cur);
+ }
+ }
+ plugin_path[i++] = g_build_filename(homebank_app_get_config_dir(), "plugins", NULL);
+ plugin_path[i++] = g_build_filename(homebank_app_get_pkglib_dir(), "plugins", NULL);
+ PREFS->ext_path = plugin_path;
+ PREFS->ext_whitelist = NULL;
+
_homebank_pref_init_measurement_units();
}
homebank_pref_get_boolean(keyfile, group, "WalSpending", &PREFS->wal_spending);
homebank_pref_get_boolean(keyfile, group, "WalUpcoming", &PREFS->wal_upcoming);
+ //since 5.1.3
+ group = "Panels";
+
+ DB( g_print(" -> ** Panels\n") );
+
+ homebank_pref_get_short(keyfile, group, "AccColAccW", &PREFS->pnl_acc_col_acc_width);
+ homebank_pref_get_short(keyfile, group, "AccShowBy" , &PREFS->pnl_acc_show_by);
+
+ homebank_pref_get_short(keyfile, group, "UpcColPayW", &PREFS->pnl_upc_col_pay_width);
+ homebank_pref_get_short(keyfile, group, "UpcColMemW", &PREFS->pnl_upc_col_mem_width);
+
group = "Format";
//PREFS->chart_legend = g_key_file_get_boolean (keyfile, group, "Legend", NULL);
+ group = "Plugins";
+ {
+ DB( g_print(" -> ** Plugins\n") );
+
+ gchar** strv = g_key_file_get_string_list(keyfile, group, "Path", NULL, NULL);
+ if (strv) {
+ g_strfreev(PREFS->ext_path);
+ PREFS->ext_path = strv;
+ }
+
+ strv = g_key_file_get_string_list(keyfile, group, "Whitelist", NULL, NULL);
+ if (strv) {
+ gchar** it;
+ for (it = strv; it && *it; ++it) {
+ PREFS->ext_whitelist = g_list_append(PREFS->ext_whitelist, g_strdup(*it));
+ }
+ g_strfreev(strv);
+ }
+ }
+
+
/*
#if MYDEBUG == 1
gsize length;
g_key_file_set_boolean (keyfile, group, "WalSpending", PREFS->wal_spending);
g_key_file_set_boolean (keyfile, group, "WalUpcoming", PREFS->wal_upcoming);
+ //since 5.1.3
+ DB( g_print(" -> ** Panels\n") );
+
+ group = "Panels";
+ g_key_file_set_integer(keyfile, group, "AccColAccW", PREFS->pnl_acc_col_acc_width);
+ g_key_file_set_integer(keyfile, group, "AccShowBy" , PREFS->pnl_acc_show_by);
+
+ g_key_file_set_integer(keyfile, group, "UpcColPayW", PREFS->pnl_upc_col_pay_width);
+ g_key_file_set_integer(keyfile, group, "UpcColMemW", PREFS->pnl_upc_col_mem_width);
+
DB( g_print(" -> ** format\n") );
//group = "Chart";
//g_key_file_set_boolean (keyfile, group, "Legend", PREFS->chart_legend);
+ group = "Plugins";
+ {
+ g_key_file_set_string_list(keyfile, group, "Path", (const gchar* const*)PREFS->ext_path, g_strv_length(PREFS->ext_path));
+
+ gsize len = g_list_length(PREFS->ext_whitelist);
+ gchar** strv = g_new0(gchar*, len + 1);
+ guint i;
+
+ for (i = 0; i < len; ++i) {
+ strv[i] = g_list_nth_data(PREFS->ext_whitelist, i);
+ }
+ g_key_file_set_string_list(keyfile, group, "Whitelist", (const gchar* const*)strv, len);
+ g_free(strv);
+ }
+
//g_key_file_set_string (keyfile, group, "", PREFS->);
//g_key_file_set_boolean (keyfile, group, "", PREFS->);
//g_key_file_set_integer (keyfile, group, "", PREFS->);
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
/* windows/dialogs size an position */
struct WinGeometry wal_wg;
struct WinGeometry acc_wg;
+
struct WinGeometry sta_wg;
struct WinGeometry tme_wg;
struct WinGeometry ove_wg;
struct WinGeometry txn_wg;
+ // main window stuffs
gboolean wal_toolbar;
gboolean wal_spending;
gboolean wal_upcoming;
gint wal_vpaned;
gint wal_hpaned;
+ //home panel
+ gshort pnl_acc_col_acc_width;
+ gshort pnl_acc_show_by;
+ gshort pnl_upc_col_pay_width;
+ gshort pnl_upc_col_mem_width;
+
+
//vehiclecost units (mile/gal or km/liters)
gchar *vehicle_unit_dist;
gchar *vehicle_unit_100;
gchar *vehicle_unit_distbyvol;
+ // plugins
+ gchar** ext_path;
+ GList* ext_whitelist;
+
};
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
#include "homebank.h"
#include "hb-tag.h"
+#include "ext.h"
+#include "refcount.h"
+
#define MYDEBUG 0
#if MYDEBUG
void da_tag_free(Tag *item)
{
DB( g_print("da_tag_free\n") );
- if(item != NULL)
+ if(rc_unref(item))
{
DB( g_print(" => %d, %s\n", item->key, item->name) );
g_free(item->name);
- g_free(item);
+ rc_free(item);
}
}
Tag *da_tag_malloc(void)
{
DB( g_print("da_tag_malloc\n") );
- return g_malloc0(sizeof(Tag));
+ return rc_alloc(sizeof(Tag));
}
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
#include "hb-tag.h"
#include "hb-split.h"
+#include "ext.h"
+#include "refcount.h"
+
/****************************************************************************/
/* Debug macros */
/****************************************************************************/
void
da_transaction_free(Transaction *item)
{
- if(item != NULL)
+ if(rc_unref(item))
{
da_transaction_clean(item);
- g_free(item);
+ rc_free(item);
}
}
Transaction *
da_transaction_malloc(void)
{
- return g_malloc0(sizeof(Transaction));
+ return rc_alloc(sizeof(Transaction));
}
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") );
Account *acc;
gchar swap;
- DB( g_print("\n[transaction] transaction_xfer_create_child\n") );
+ DB( g_print("\n[transaction] xfer_create_child\n") );
if( ope->kxferacc > 0 )
{
DB( g_print(" + strong link to %d\n", ope->kxfer) );
- DB( g_print(" + add transfer, %p\n", child) );
+ DB( g_print(" + add transfer, %p to acc %d\n", child, acc->key) );
da_transaction_insert_sorted(child);
account_balances_add (child);
+ GValue txn_value = G_VALUE_INIT;
+ ext_hook("transaction_inserted", EXT_TRANSACTION(&txn_value, child), NULL);
+
}
}
{
gboolean retval = FALSE;
+ //DB( g_print("\n[transaction] xfer_child_might\n") );
+
if(stxn == dtxn)
return FALSE;
GList *lst_acc, *lnk_acc;
GList *list, *matchlist = NULL;
- DB( g_print("\n[transaction]xfer_get_potential_child\n") );
+ //DB( g_print("\n[transaction] xfer_child_might_list_get\n") );
lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
lnk_acc = g_list_first(lst_acc);
GList *matchlist;
gint count;
- DB( g_print("\n[transaction] transaction_xfer_search_or_add_child\n") );
+ DB( g_print("\n[transaction] xfer_search_or_add_child\n") );
matchlist = transaction_xfer_child_might_list_get(ope);
count = g_list_length(matchlist);
- DB( g_print(" - found result is %d, switching\n", count) );
+ DB( g_print(" - found %d might match, switching\n", count) );
switch(count)
{
default: //the user must choose himself
{
- Transaction *child;
+ Transaction *child;
child = ui_dialog_transaction_xfer_select_child(ope, matchlist);
- if(child == NULL)
- transaction_xfer_create_child(ope);
- else
- transaction_xfer_change_to_child(ope, child);
+ if(child == NULL)
+ transaction_xfer_create_child(ope);
+ else
+ transaction_xfer_change_to_child(ope, child);
}
}
Account *dstacc;
GList *list;
- DB( g_print("\n[transaction] transaction_xfer_child_strong_get\n") );
+ DB( g_print("\n[transaction] xfer_child_strong_get\n") );
dstacc = da_acc_get(src->kxferacc);
if( !dstacc || src->kxfer <= 0 )
{
Account *dstacc;
- DB( g_print("\n[transaction] transaction_xfer_change_to_child\n") );
+ DB( g_print("\n[transaction] xfer_change_to_child\n") );
if(ope->kcur != child->kcur)
return;
void transaction_xfer_sync_child(Transaction *s_txn, Transaction *child)
{
- DB( g_print("\n[transaction] transaction_xfer_sync_child\n") );
+ DB( g_print("\n[transaction] xfer_sync_child\n") );
account_balances_sub (child);
{
Transaction *dst;
- DB( g_print("\n[transaction] transaction_xfer_remove_child\n") );
+ DB( g_print("\n[transaction] xfer_remove_child\n") );
dst = transaction_xfer_child_strong_get( src );
Account *acc;
GList *list;
- DB( g_print("\n[transaction] transaction_get_child_transfer\n") );
+ DB( g_print("\n[transaction] get_child_transfer\n") );
//DB( g_print(" search: %d %s %f %d=>%d\n", src->date, src->wording, src->amount, src->account, src->kxferacc) );
acc = da_acc_get(src->kxferacc);
Transaction *newope;
Account *acc;
- DB( g_print("\n[transaction] transaction add\n") );
+ DB( g_print("\n[transaction] transaction_add\n") );
//controls accounts valid (archive scheduled maybe bad)
acc = da_acc_get(ope->kacc);
if(acc == NULL) return;
+ DB( g_print(" acc is '%s' %d\n", acc->name, acc->key) );
+
ope->kcur = acc->kcur;
if(ope->paymode == PAYMODE_INTXFER)
ope->flags &= ~(OF_SPLIT); //Flag that Splits are cleared
}
+
//allocate a new entry and copy from our edited structure
newope = da_transaction_clone(ope);
{
acc->flags |= AF_ADDED;
- DB( g_print(" + add normal %p\n", newope) );
+ DB( g_print(" + add normal %p to acc %d\n", newope, acc->key) );
//da_transaction_append(newope);
da_transaction_insert_sorted(newope);
{
transaction_xfer_search_or_add_child(NULL, newope, FALSE);
}
+
+ GValue txn_value = G_VALUE_INIT;
+ ext_hook("transaction_inserted", EXT_TRANSACTION(&txn_value, newope), NULL);
}
}
//GtkTreePath *path;
//GtkTreeSelection *sel;
- DB( g_print("\n[transaction] transaction add treeview\n") );
+ DB( g_print("\n[transaction] add_treeview\n") );
if(ope->kacc == accnum)
{
{
Account *oacc, *nacc;
+ DB( g_print("\n[transaction] acc_move\n") );
+
oacc = da_acc_get(okacc);
nacc = da_acc_get(nkacc);
if( oacc && nacc )
if(text == NULL)
return FALSE;
- DB( g_print("match RE %s in %s\n", searchtext, text) );
+ DB( g_print("- match RE %s in %s\n", searchtext, text) );
if( searchtext != NULL )
{
match = g_regex_match_simple(searchtext, text, ((exact == TRUE)?0:G_REGEX_CASELESS) | G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY );
{
Assign *rule = NULL;
GList *list;
-
+
+ DB( g_print("\n[transaction] auto_assign_eval_txn\n") );
+
DB( g_print("- eval every rules, and return the last that match\n") );
list = g_list_first(l_rul);
{
Assign *rule = NULL;
GList *list;
+
+ DB( g_print("\n[transaction] auto_assign_eval\n") );
DB( g_print("- eval every rules, and return the last that match\n") );
GList *l_rul;
gint changes = 0;
- DB( g_print("\n[transaction] transaction_auto_assign\n") );
+ DB( g_print("\n[transaction] auto_assign\n") );
l_rul = g_hash_table_get_values(GLOBALS->h_rul);
guint count = 0;
guint32 *ptr = ope->tags;
- DB( g_print("(transaction_tags_count)\n") );
+ //DB( g_print("\n[transaction] tags_count\n") );
if( ope->tags == NULL )
return 0;
guint count, i;
Tag *tag;
- DB( g_print("(transaction_tags_parse)\n") );
+ DB( g_print("\n[transaction] tags_parse\n") );
DB( g_print(" - tagstring='%s'\n", tagstring) );
gchar *tagstring;
Tag *tag;
- DB( g_print("transaction_tags_tostring\n") );
+ DB( g_print("\n[transaction] tags_tostring\n") );
DB( g_print(" -> tags at=%p\n", ope->tags) );
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
#include "hb-transaction.h"
#include "hb-xml.h"
+#include "ext.h"
+
#include "ui-dialogs.h"
/****************************************************************************/
DB( g_print("\n[hb-xml] homebank_load_xml\n") );
+ GValue filename_val = G_VALUE_INIT;
+ ext_hook("load_file", EXT_STRING(&filename_val, filename), NULL);
+
retval = XML_OK;
if (!g_file_get_contents (filename, &buffer, &length, &error))
{
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)
{
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
*/
#include "homebank.h"
+#include "ext.h"
#include "dsp_mainwindow.h"
#include "hb-preferences.h"
static gchar *locale_dir = NULL;
static gchar *help_dir = NULL;
static gchar *datas_dir = NULL;
+static gchar *pkglib_dir = NULL;
//#define MARKUP_STRING "<span size='small'>%s</span>"
return datas_dir;
}
+const gchar *
+homebank_app_get_pkglib_dir (void)
+{
+ return pkglib_dir;
+}
+
/* build package paths at runtime */
static void
pixmaps_dir = g_build_filename (prefix, "share", PACKAGE, "icons", NULL);
help_dir = g_build_filename (prefix, "share", PACKAGE, "help", NULL);
datas_dir = g_build_filename (prefix, "share", PACKAGE, "datas", NULL);
+ pkglib_dir = g_build_filename (prefix, "lib", PACKAGE, NULL);
#ifdef PORTABLE_APP
DB( g_print(" - app is portable under windows\n") );
config_dir = g_build_filename(prefix, "config", NULL);
pixmaps_dir = g_build_filename (DATA_DIR, PACKAGE, "icons", NULL);
help_dir = g_build_filename (DATA_DIR, PACKAGE, "help", NULL);
datas_dir = g_build_filename (DATA_DIR, PACKAGE, "datas", NULL);
+ pkglib_dir = g_build_filename (PKGLIB_DIR, NULL);
config_dir = g_build_filename(g_get_user_config_dir(), HB_DATA_PATH, NULL);
//#870023 Ubuntu packages the help files in "/usr/share/doc/homebank-data/help/" for some strange reason
DB( g_print(" - locale_dir : %s\n", locale_dir) );
DB( g_print(" - help_dir : %s\n", help_dir) );
DB( g_print(" - datas_dir : %s\n", datas_dir) );
+ DB( g_print(" - pkglib_dir : %s\n", pkglib_dir) );
}
g_free (pixmaps_dir);
g_free (locale_dir);
g_free (help_dir);
+ g_free (pkglib_dir);
}
int
-main (int argc, char *argv[])
+main (int argc, char *argv[], char *env[])
{
GOptionContext *option_context;
GOptionGroup *option_group;
/* change the locale if a language is specified */
language_init (PREFS->language);
+ DB( g_print(" - loading plugins\n") );
+ ext_init(&argc, &argv, &env);
+
+ GList* it;
+ for (it = PREFS->ext_whitelist; it; it = g_list_next(it)) {
+ ext_load_plugin(it->data);
+ }
+
+ gchar** plugins = ext_list_plugins();
+ gchar** plugins_it;
+ for (plugins_it = plugins; *plugins_it; ++plugins_it) {
+ gboolean loaded = ext_is_plugin_loaded(*plugins_it);
+ g_print("found plugin: %s, loaded: %d\n", *plugins_it, loaded);
+ }
+ g_strfreev(plugins);
+
if( PREFS->showsplash == TRUE )
{
splash = homebank_construct_splash();
mainwin = (GtkWidget *)create_hbfile_window (NULL);
+ GValue mainwin_val = G_VALUE_INIT;
+ ext_hook("create_main_window", EXT_OBJECT(&mainwin_val, mainwin), NULL);
+
if(mainwin)
{
/* update the mainwin display */
ui_mainwindow_update(mainwin, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_BALANCE+UF_VISUAL));
+ ext_hook("enter_main_loop", NULL);
+
DB( g_print(" - gtk_main()\n" ) );
gtk_main ();
+
+ ext_hook("exit_main_loop", NULL);
}
+ DB( g_print(" - unloading plugins\n") );
+ ext_term();
+
}
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
#define HB_UNSTABLE FALSE
+ #define HB_UNSTABLE_SHOW FALSE
+
#define HB_VERSION_MAJOR 5
#define HB_VERSION_MINOR 1
- #define HB_VERSION_MICRO 2
+ #define HB_VERSION_MICRO 3
- #define HB_VERSION "5.1.2"
+ #define HB_VERSION "5.1.3"
#define HB_VERSION_NUM (HB_VERSION_MAJOR*10000) + (HB_VERSION_MINOR*100) + HB_VERSION_MICRO
#define FILE_VERSION 1.2
- #define PREF_VERSION 512
+ #define PREF_VERSION 513
#if HB_UNSTABLE == FALSE
#define PROGNAME "HomeBank"
#define ICONNAME_REFRESH "view-refresh"
#define ICONNAME_FOLDER "folder-symbolic"
+ #define ICONNAME_EMBLEM_SYSTEM "emblem-system-symbolic"
+
#define ICONNAME_LIST_ADD "list-add-symbolic"
#define ICONNAME_LIST_REMOVE "list-remove-symbolic"
#define ICONNAME_HB_FILE_VALID "hb-file-valid"
#define ICONNAME_HB_FILE_INVALID "hb-file-invalid"
- #define ICONNAME_HB_BUTTON_COLLAPSE "btn-collapse"
- #define ICONNAME_HB_BUTTON_EXPAND "btn-expand"
+ #define ICONNAME_HB_BUTTON_COLLAPSE "btn-collapse-symbolic"
+ #define ICONNAME_HB_BUTTON_EXPAND "btn-expand-symbolic"
#define ICONNAME_HB_BUTTON_SPLIT "btn-split"
#define ICONNAME_HB_OPE_AUTO "hb-ope-auto" //?
const gchar *homebank_app_get_locale_dir (void);
const gchar *homebank_app_get_help_dir (void);
const gchar *homebank_app_get_datas_dir (void);
+const gchar *homebank_app_get_pkglib_dir (void);
guint32 homebank_app_date_get_julian(void);
/* - - - - obsolete things - - - - */
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
#include "dsp_mainwindow.h"
#include "gtk-chart-colors.h"
+#include "ext.h"
+
#include "ui-currency.h"
enum
{
- PREF_GENERAL,
- PREF_INTERFACE,
- PREF_COLUMNS,
- PREF_DISPLAY,
- PREF_IMPORT,
- PREF_REPORT,
- PREF_EURO,
- PREF_MAX
+ EXT_COLUMN_ENABLED = 0,
+ EXT_COLUMN_LABEL,
+ EXT_COLUMN_TOOLTIP,
+ EXT_COLUMN_PLUGIN_NAME,
+ EXT_NUM_COLUMNS
};
"prf-import",
"prf-report",
"prf-euro", // to be renamed
+"prf-plugins",
//"prf_charts.svg"
};
N_("Display format"),
N_("Import/Export"),
N_("Report"),
-N_("Euro minor")
+N_("Euro minor"),
+N_("Plugins")
//
};
typedef struct
{
+ gshort id;
gchar *iso;
gchar *name;
gdouble value;
*/
static EuroParams euro_params[] =
{
- // , rate , symb , prfx , dec, grp, frac
+ // , rate , symb , prfx , dec, grp, frac
// ---------------------------------------------------------------------
- { "" , "--------" , 1.0 , "" , FALSE, ",", ".", 2 },
- { "ATS", "Austria" , 13.7603 , "S" , TRUE , ",", ".", 2 }, // -S 1.234.567,89
- { "BEF", "Belgium" , 40.3399 , "BF" , TRUE , ",", ".", 2 }, // BF 1.234.567,89 -
- { "FIM", "Finland" , 5.94573 , "mk" , FALSE, ",", " ", 2 }, // -1 234 567,89 mk
- { "FRF", "France" , 6.55957 , "F" , FALSE, ",", " ", 2 }, // -1 234 567,89 F
- { "DEM", "Germany" , 1.95583 , "DM" , FALSE, ",", ".", 2 }, // -1.234.567,89 DM
- { "GRD", "Greece" , 340.750 , "d" , TRUE , ".", ",", 2 }, // ??
- { "IEP", "Ireland" , 0.787564 , "£" , TRUE , ".", ",", 2 }, // -£1,234,567.89
- { "ITL", "Italy" , 1936.27 , "L" , TRUE , "" , ".", 0 }, // L -1.234.567
- { "LUF", "Luxembourg" , 40.3399 , "LU" , TRUE , ",", ".", 2 }, // LU 1.234.567,89 -
- { "NLG", "Netherlands" , 2.20371 , "F" , TRUE , ",", ".", 2 }, // F 1.234.567,89-
- { "PTE", "Portugal" , 200.482 , "Esc.", FALSE, "$", ".", 2 }, // -1.234.567$89 Esc.
- { "ESP", "Spain" , 166.386 , "Pts" , TRUE , "" , ".", 0 }, // -Pts 1.234.567
- /* 2007 */
- { "SIT", "Slovenia" , 239.640 , "tol" , TRUE , ",", ".", 2 }, //
- /* 2008 */
- { "CYP", "Cyprus" , 0.585274 , "£" , TRUE , ",", "" , 2 }, //
- { "MTL", "Malta" , 0.429300 , "Lm" , TRUE , ",", "" , 2 }, //
- /* 2009 */
- { "SKK", "Slovaquia" , 30.12600 , "Sk" , FALSE, ",", " ", 2 }, //
- /* 2011 */
- { "EEK", "Estonia" , 15.6466 , "kr" , FALSE, ",", " ", 2 }, //
- /* 2014 */
- { "LVL", "Latvia" , 0.702804 , "lat.", FALSE, ",", "" , 2 }, // jan. 2014
- /* 2016 */
- { "LTL", "Lithuania" , 3.45280 , "Lt." , TRUE , ",", "" , 2 }, // jan. 2015
-
- /* future */
- { "BGN", "Bulgaria" , 1.95583 , "лв." , TRUE , ",", " ", 2 }, // non-fixé - 2014 target for euro
- { "HUF", "Hungary" , 261.51 , "Ft" , TRUE , ",", " ", 2 }, // non-fixé - No current target for euro
- { "RON", "Romania" , 3.5155 , "Leu" , FALSE, ",", ".", 2 }, // non-fixé - 2015 target for euro earliest
- { "CZK", "Czech republic", 28.36 , "Kč" , FALSE, ",", " ", 2 }, // non-fixé - 2015 earliest
- { "HRK", "Croatia" , 1.0000 , "kn" , FALSE, "" , ".", 0 }, // non-fixé - 2015 target for euro earliest
- { "PLN", "Poland" , 0.25 , "zł" , FALSE, ",", "" , 2 }, // non-fixé - No current target for euro
-
+ { 0, "" , "--------" , 1.0 , "" , FALSE, ",", ".", 2 },
+ { 1, "ATS", "Austria" , 13.7603 , "S" , TRUE , ",", ".", 2 }, // -S 1.234.567,89
+ { 2, "BEF", "Belgium" , 40.3399 , "BF" , TRUE , ",", ".", 2 }, // BF 1.234.567,89 -
+ { 20, "BGN", "Bulgaria" , 1.95583 , "лв." , TRUE , ",", " ", 2 }, // non-fixé - 2014 target for euro
+ { 24, "HRK", "Croatia" , 1.0000 , "kn" , FALSE, "" , ".", 0 }, // non-fixé - 2015 target for euro earliest
+ { 14, "CYP", "Cyprus" , 0.585274 , "£" , TRUE , ",", "" , 2 }, //
+ { 23, "CZK", "Czech Republic" , 28.36 , "Kč" , FALSE, ",", " ", 2 }, // non-fixé - 2015 earliest
+ // Denmark
+ { 17, "EEK", "Estonia" , 15.6466 , "kr" , FALSE, ",", " ", 2 }, //
+ { 3, "FIM", "Finland" , 5.94573 , "mk" , FALSE, ",", " ", 2 }, // -1 234 567,89 mk
+ { 4, "FRF", "France" , 6.55957 , "F" , FALSE, ",", " ", 2 }, // -1 234 567,89 F
+ { 5, "DEM", "Germany" , 1.95583 , "DM" , FALSE, ",", ".", 2 }, // -1.234.567,89 DM
+ { 6, "GRD", "Greece" , 340.750 , "d" , TRUE , ".", ",", 2 }, // ??
+ { 21, "HUF", "Hungary" , 261.51 , "Ft" , TRUE , ",", " ", 2 }, // non-fixé - No current target for euro
+ { 7, "IEP", "Ireland" , 0.787564 , "£" , TRUE , ".", ",", 2 }, // -£1,234,567.89
+ { 8, "ITL", "Italy" , 1936.27 , "L" , TRUE , "" , ".", 0 }, // L -1.234.567
+ { 18, "LVL", "Latvia" , 0.702804 , "lat.", FALSE, ",", "" , 2 }, // jan. 2014
+ { 19, "LTL", "Lithuania" , 3.45280 , "Lt" , FALSE, ",", "" , 2 }, // jan. 2015
+ { 9, "LUF", "Luxembourg" , 40.3399 , "LU" , TRUE , ",", ".", 2 }, // LU 1.234.567,89 -
+ { 15, "MTL", "Malta" , 0.429300 , "Lm" , TRUE , ",", "" , 2 }, //
+ { 10, "NLG", "Netherlands" , 2.20371 , "F" , TRUE , ",", ".", 2 }, // F 1.234.567,89-
+ { 25, "PLN", "Poland" , 0.25 , "zł" , FALSE, ",", "" , 2 }, // non-fixé - No current target for euro
+ { 11, "PTE", "Portugal" , 200.482 , "Esc.", FALSE, "$", ".", 2 }, // -1.234.567$89 Esc.
+ { 22, "RON", "Romania" , 3.5155 , "Leu" , FALSE, ",", ".", 2 }, // non-fixé - 2015 target for euro earliest
+ { 16, "SKK", "Slovak Republic", 30.12600 , "Sk" , FALSE, ",", " ", 2 }, //
+ { 13, "SIT", "Slovenia" , 239.640 , "tol" , TRUE , ",", ".", 2 }, //
+ { 12, "ESP", "Spain" , 166.386 , "Pts" , TRUE , "" , ".", 0 }, // -Pts 1.234.567
+ //Sweden
+ //United Kingdom
// { " ", "" , 1.00000 , "" , "" , FALSE, ",", "", 2 },
-
};
static void list_txn_colpref_get(GtkTreeView *treeview, gboolean *columns);
+static void list_ext_colpref_get(GtkTreeView *treeview, GList **columns);
{ "an", "Aragonese" },
{ "ar", "Arabic" },
{ "as", "Assamese" },
- { "ast", "Asturian, Bable, Leonese, Asturleonese" },
+ { "ast", "Asturian, Bable, Leonese, Asturleonese" },
{ "av", "Avaric" },
{ "ay", "Aymara" },
{ "az", "Azerbaijani" },
{ "na", "Nauru" },
{ "nb", "Norwegian Bokmål" },
{ "nd", "North Ndebele" },
- { "nds", "Low German, Low Saxon" },
+ { "nds", "Low German, Low Saxon" },
{ "ne", "Nepali" },
{ "ng", "Ndonga" },
{ "nl", "Dutch" },
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
+ static gint ui_euro_combobox_id_to_active(gint id)
+ {
+ guint i, retval;
- /*
- **
- */
- static GtkWidget *make_euro_presets(GtkWidget *label)
+ DB( g_print("\n[ui-pref] ui_euro_combobox_id_to_active\n") );
+
+ retval = 0;
+ for (i = 0; i < G_N_ELEMENTS (euro_params); i++)
+ {
+ if( euro_params[i].id == id )
+ {
+ retval = i;
+ DB( g_print("- id (country)=%d => %d - %s\n", id, i, euro_params[i].name) );
+ break;
+ }
+ }
+
+ return retval;
+ }
+
+
+
+ static gint ui_euro_combobox_active_to_id(gint active)
+ {
+ gint id;
+
+ DB( g_print("\n[ui-pref] ui_euro_combobox_active_to_id\n") );
+
+ DB( g_print("- to %d\n", active) );
+
+ id = 0;
+ if( active < (gint)G_N_ELEMENTS (euro_params) )
+ {
+ id = euro_params[active].id;
+ DB( g_print("- id (country)=%d '%s'\n", id, euro_params[active].name) );
+ }
+ return id;
+ }
+
+
+ static GtkWidget *ui_euro_combobox_new(GtkWidget *label)
{
GtkWidget *combobox;
guint i;
/*
** set euro value widget from a country
*/
- static void defpref_eurosetcurrency(GtkWidget *widget, gpointer user_data)
+ static void defpref_eurosetcurrency(GtkWidget *widget, gint country)
{
struct defpref_data *data;
- EuroParams *euro = user_data;
+ EuroParams *euro;
gchar *buf;
-
+ gint active;
DB( g_print("\n[ui-pref] eurosetcurrency\n") );
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
+ active = ui_euro_combobox_id_to_active(country);
+ euro = &euro_params[active];
buf = g_strdup_printf("%s - %s", euro->iso, euro->name);
-
gtk_label_set_markup(GTK_LABEL(data->ST_euro_country), buf);
-
g_free(buf);
}
-
/*
** set euro value widget from a country
*/
static void defpref_europreset(GtkWidget *widget, gpointer user_data)
{
struct defpref_data *data;
- gint country;
+ gint active;
DB( g_print("\n[ui-pref] euro preset\n") );
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
- country = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_euro_preset));
- data->country = country;
+ active = gtk_combo_box_get_active (GTK_COMBO_BOX(data->CY_euro_preset));
+ data->country = ui_euro_combobox_active_to_id (active);;
- defpref_eurosetcurrency(widget, &euro_params[country]);
+ defpref_eurosetcurrency(widget, data->country);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->NB_euro_value), euro_params[country].value);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->NB_euro_value), euro_params[active].value);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->NB_euro_fracdigits), euro_params[country].frac_digits);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->NB_euro_fracdigits), euro_params[active].frac_digits);
- gtk_entry_set_text(GTK_ENTRY(data->ST_euro_symbol) , euro_params[country].symbol);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->CM_euro_isprefix), euro_params[country].sym_prefix);
- gtk_entry_set_text(GTK_ENTRY(data->ST_euro_decimalchar) , euro_params[country].decimal_char);
- gtk_entry_set_text(GTK_ENTRY(data->ST_euro_groupingchar), euro_params[country].grouping_char);
+ gtk_entry_set_text(GTK_ENTRY(data->ST_euro_symbol) , euro_params[active].symbol);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->CM_euro_isprefix), euro_params[active].sym_prefix);
+ gtk_entry_set_text(GTK_ENTRY(data->ST_euro_decimalchar) , euro_params[active].decimal_char);
+ gtk_entry_set_text(GTK_ENTRY(data->ST_euro_groupingchar), euro_params[active].grouping_char);
}
gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_toolbar), PREFS->toolbar_style);
//gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->NB_image_size), PREFS->image_size);
+
+
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->CM_custom_colors), PREFS->custom_colors);
gdk_rgba_parse(&rgba, PREFS->color_exp);
/* euro */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->CM_euro_enable), PREFS->euro_active);
//gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_euro_preset), PREFS->euro_country);
-
data->country = PREFS->euro_country;
- defpref_eurosetcurrency(data->window, &euro_params[PREFS->euro_country]);
+ defpref_eurosetcurrency(data->window, data->country);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->NB_euro_value), PREFS->euro_value);
//PREFS->chart_legend = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_chartlegend));
+ list_ext_colpref_get(GTK_TREE_VIEW(data->PI_plugin_columns), &(PREFS->ext_whitelist));
}
label = make_label_widget(_("_Preset:"));
//----------------------------------------- l, r, t, b
gtk_grid_attach (GTK_GRID (group_grid), label, 2, row, 1, 1);
- widget = make_euro_presets(label);
+ widget = ui_euro_combobox_new (label);
data->CY_euro_preset = widget;
gtk_widget_set_margin_left (label, 2*SPACING_LARGE);
//gtk_grid_attach (GTK_GRID (group_grid), data->CY_option[FILTER_DATE], 1, 2, row, row+1);
return content_grid;
}
+
+void plugin_execute_action(GtkTreeView* treeview, GtkTreePath* path, GtkTreeViewColumn* col, gpointer userdata);
+
+static void
+toggle_plugin(GtkCellRendererToggle *cell, gchar* path_str, gpointer data)
+{
+ GtkTreeModel *model = (GtkTreeModel*)data;
+ GtkTreeIter iter;
+ GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
+
+ const gchar* plugin;
+
+ gtk_tree_model_get_iter(model, &iter, path);
+ gtk_tree_model_get(model, &iter, EXT_COLUMN_PLUGIN_NAME, &plugin, -1);
+
+ gboolean enabled = ext_is_plugin_loaded(plugin);
+ if (enabled) {
+ ext_unload_plugin(plugin);
+ enabled = FALSE;
+ } else {
+ enabled = (ext_load_plugin(plugin) == 0);
+ if (!enabled) {
+ ext_run_modal(_("Plugin Error"), _("The plugin failed to load properly."), "error");
+ }
+ }
+
+ /* set new value */
+ gtk_list_store_set(GTK_LIST_STORE (model), &iter, EXT_COLUMN_ENABLED, enabled, -1);
+
+ /* clean up */
+ gtk_tree_path_free(path);
+}
+
+
+void plugin_execute_action(GtkTreeView* treeview, GtkTreePath* path, GtkTreeViewColumn* col, gpointer userdata)
+{
+ GtkTreeModel* model = gtk_tree_view_get_model(treeview);
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_get_iter(model, &iter, path)) {
+ gchar* plugin_filename;
+ gtk_tree_model_get(model, &iter, EXT_COLUMN_PLUGIN_NAME, &plugin_filename, -1);
+ ext_execute_action(plugin_filename);
+ g_free(plugin_filename);
+ }
+}
+
+static GtkWidget *defpref_page_plugins (struct defpref_data *data)
+{
+ GtkWidget *container;
+ GtkListStore *store;
+ GtkTreeIter it;
+ GtkWidget* view;
+
+ container = gtk_vbox_new(FALSE, 0);
+
+ store = gtk_list_store_new(EXT_NUM_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ gchar** plugins = ext_list_plugins();
+ gchar** plugins_it;
+ for (plugins_it = plugins; *plugins_it; ++plugins_it) {
+
+ gboolean enabled = ext_is_plugin_loaded(*plugins_it);
+ GHashTable* metadata = ext_read_plugin_metadata(*plugins_it);
+ if (!metadata) {
+ metadata = g_hash_table_new(g_str_hash, g_str_equal);
+ }
+
+ gchar* tmp = NULL;
+
+ // NAME
+ gchar* name = g_hash_table_lookup(metadata, "name");
+ if (!name || *name == '\0') {
+ name = *plugins_it;
+ }
+ name = g_markup_escape_text(name, -1);
+ gchar* label = g_strdup_printf("<b>%s</b>", name);
+ gchar* tooltip = g_strdup_printf("<span size='x-large' weight='bold'>%s</span>", name);
+ g_free(name);
+
+ // VERSION
+ gchar* version = g_hash_table_lookup(metadata, "version");
+ if (version) {
+ version = g_markup_escape_text(version, -1);
+ tmp = label;
+ label = g_strdup_printf("%s %s", tmp, version);
+ g_free(tmp);
+ tmp = tooltip;
+ tooltip = g_strdup_printf("%s %s", tmp, version);
+ g_free(tmp);
+ g_free(version);
+ }
+
+ // ABSTRACT
+ gchar* abstract = g_hash_table_lookup(metadata, "abstract");
+ if (abstract) {
+ abstract = g_markup_escape_text(abstract, -1);
+ tmp = label;
+ label = g_strdup_printf("%s\n%s", tmp, abstract);
+ g_free(tmp);
+ g_free(abstract);
+ }
+
+ // AUTHOR
+ gchar* author = g_hash_table_lookup(metadata, "author");
+ if (author) {
+ author = g_markup_escape_text(author, -1);
+ tmp = tooltip;
+ tooltip = g_strdup_printf("%s\n%s", tmp, author);
+ g_free(tmp);
+ g_free(author);
+ }
+
+ // WEBSITE
+ gchar* website = g_hash_table_lookup(metadata, "website");
+ if (website) {
+ website = g_markup_escape_text(website, -1);
+ tmp = tooltip;
+ tooltip = g_strdup_printf("%s\n<b>%s:</b> %s", tmp, _("Website"), website);
+ g_free(tmp);
+ g_free(website);
+ }
+
+ // FILEPATH
+ tmp = ext_find_plugin(*plugins_it);
+ gchar* full = g_markup_escape_text(tmp, -1);
+ g_free(tmp);
+ tmp = tooltip;
+ tooltip = g_strdup_printf("%s\n<b>%s:</b> %s", tmp, _("File"), full);
+ g_free(tmp);
+ g_free(full);
+
+ g_hash_table_unref(metadata);
+
+ gtk_list_store_append(store, &it);
+ gtk_list_store_set(store, &it,
+ EXT_COLUMN_ENABLED, enabled,
+ EXT_COLUMN_LABEL, label,
+ EXT_COLUMN_TOOLTIP, tooltip,
+ EXT_COLUMN_PLUGIN_NAME, *plugins_it,
+ -1);
+
+ g_free(label);
+ g_free(tooltip);
+ }
+ g_strfreev(plugins);
+
+ view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+ g_object_unref(store);
+
+ g_signal_connect(view, "row-activated", (GCallback)plugin_execute_action, NULL);
+
+ gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(view), TRUE);
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), TRUE);
+ gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(view), EXT_COLUMN_TOOLTIP);
+
+
+ GtkTreeViewColumn *col;
+ GtkCellRenderer *renderer;
+
+
+ col = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_title(col, _("Enabled"));
+ gtk_tree_view_column_set_sort_column_id(col, EXT_COLUMN_ENABLED);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
+
+ renderer = gtk_cell_renderer_toggle_new();
+ gtk_tree_view_column_pack_start(col, renderer, TRUE);
+ gtk_tree_view_column_add_attribute(col, renderer, "active", 0);
+ g_signal_connect(renderer, "toggled", G_CALLBACK(toggle_plugin), store);
+
+ col = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_title(col, _("Plugin"));
+ gtk_tree_view_column_set_sort_column_id(col, EXT_COLUMN_LABEL);
+ gtk_tree_view_column_set_expand(col, TRUE);
+ /*gtk_tree_view_column_set_sort_order(col, GTK_SORT_ASCENDING);*/
+ gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
+
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ gtk_tree_view_column_pack_start(col, renderer, TRUE);
+ gtk_tree_view_column_add_attribute(col, renderer, "markup", EXT_COLUMN_LABEL);
+
+ data->PI_plugin_columns = view;
+
+ GtkWidget* sw = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_container_add(GTK_CONTAINER(sw), view);
+
+ gtk_box_pack_start(GTK_BOX(container), sw, TRUE, TRUE, 0);
+
+ return(container);
+}
+
+
static void defpref_selection(GtkTreeSelection *treeselection, gpointer user_data)
{
struct defpref_data *data;
// the window creation
-GtkWidget *defpref_dialog_new (void)
+GtkWidget *defpref_dialog_new (gint initial_selection)
{
struct defpref_data data;
GtkWidget *window, *content, *mainvbox;
page = defpref_page_euro(&data);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, NULL);
+ //plugins
+ page = defpref_page_plugins(&data);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, NULL);
+
//todo:should move this
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data.CM_euro_enable), PREFS->euro_active);
//select first row
- GtkTreePath *path = gtk_tree_path_new_first ();
+ GtkTreePath *path = gtk_tree_path_new_from_indices(initial_selection, -1);
+
gtk_tree_selection_select_path (gtk_tree_view_get_selection(GTK_TREE_VIEW(data.LV_page)), path);
gtk_tree_path_free(path);
gtk_widget_show_all (window);
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), initial_selection);
gint result;
gchar *old_lang;
return(view);
}
+
+static void list_ext_colpref_get(GtkTreeView *treeview, GList **columns)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_list_free_full(*columns, g_free);
+ *columns = NULL;
+
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
+
+ gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
+ while (valid) {
+ gboolean enabled = FALSE;
+ const gchar* name;
+
+ gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
+ EXT_COLUMN_ENABLED, &enabled,
+ EXT_COLUMN_PLUGIN_NAME, &name,
+ -1);
+
+ if (enabled) {
+ *columns = g_list_append(*columns, g_strdup(name));
+ }
+
+ valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
+ }
+}
+
/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2016 Maxime DOYEN
+ * Copyright (C) 1995-2017 Maxime DOYEN
*
* This file is part of HomeBank.
*
gint country;
+ GtkWidget *PI_plugin_columns;
+};
+
+enum
+{
+ PREF_GENERAL,
+ PREF_INTERFACE,
+ PREF_TRANSACTIONS,
+ PREF_DISPLAY_FORMAT,
+ PREF_IMPORT_EXPORT,
+ PREF_REPORT,
+ PREF_EURO_MINOR,
+ PREF_PLUGINS,
+ PREF_MAX
};
void free_pref_icons(void);
void load_pref_icons(void);
-GtkWidget *defpref_dialog_new (void);
+GtkWidget *defpref_dialog_new (gint initial_selection);
#endif
hicolor_status_48x48_prf-import.png \
hicolor_status_48x48_prf-interface.png \
hicolor_status_48x48_prf-report.png \
+ hicolor_status_48x48_prf-plugins.png \
hicolor_actions_scalable_toggle-sign-symbolic.svg \
+ hicolor_actions_scalable_btn-collapse-symbolic.svg \
+ hicolor_actions_scalable_btn-expand-symbolic.svg \
$(NULL)