]> Dogcows Code - chaz/homebank/blobdiff - src/hub-account.c
import homebank-5.2.4
[chaz/homebank] / src / hub-account.c
diff --git a/src/hub-account.c b/src/hub-account.c
new file mode 100644 (file)
index 0000000..1255437
--- /dev/null
@@ -0,0 +1,498 @@
+/*  HomeBank -- Free, easy, personal accounting for everyone.
+ *  Copyright (C) 1995-2019 Maxime DOYEN
+ *
+ *  This file is part of HomeBank.
+ *
+ *  HomeBank is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  HomeBank is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "homebank.h"
+
+#include "hub-account.h"
+#include "dsp-mainwindow.h"
+#include "list-account.h"
+
+
+/****************************************************************************/
+/* Debug macros                                                             */
+/****************************************************************************/
+#define MYDEBUG 0
+
+#if MYDEBUG
+#define DB(x) (x);
+#else
+#define DB(x);
+#endif
+
+/* our global datas */
+extern struct HomeBank *GLOBALS;
+extern struct Preferences *PREFS;
+
+
+extern HbKvData CYA_ACC_TYPE[];
+
+
+static void ui_hub_account_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_hub_account_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 void ui_hub_account_groups_free(GHashTable *h_group)
+{
+GHashTableIter grp_iter;
+gpointer key, value;
+
+       DB( g_print("\n[hub-account] groups free\n") );
+
+       g_hash_table_iter_init (&grp_iter, h_group);
+       while (g_hash_table_iter_next (&grp_iter, &key, &value))
+       {
+       PnlAccGrp *group = value;
+       
+               g_ptr_array_free (group->acclist, TRUE);
+               g_free(group);
+       }
+
+       g_hash_table_destroy (h_group);  
+}
+
+
+static GHashTable *ui_hub_account_groups_get(GtkTreeView *treeview, gint groupby, gboolean showall)
+{
+GHashTable *h_group;
+GList *lacc, *elt;
+gchar *groupname;
+gint nballoc;
+       
+       DB( g_print("\n[hub-account] groups get\n") );
+
+       nballoc = da_acc_length ();
+       
+       DB( g_print(" %d accounts\n", nballoc) );
+       
+       h_group = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL);
+
+       lacc = g_hash_table_get_values(GLOBALS->h_acc);
+       elt = g_list_first(lacc);
+       while (elt != NULL)
+       {
+       Account *acc = elt->data;
+       PnlAccGrp *group;
+       
+               //#1674045 ony rely on nosummary
+               //if( showall || !(acc->flags & (AF_CLOSED|AF_NOSUMMARY)) )
+               if( showall || !(acc->flags & AF_NOSUMMARY) )
+               {
+                       switch( groupby )
+                       {
+                               case DSPACC_GROUP_BY_BANK:
+                               {
+                                       groupname = _("(no institution)");
+                                       if( (acc->bankname != NULL) && strlen(acc->bankname) > 0 ) 
+                                               groupname = acc->bankname;
+                               }
+                               break;
+
+                               default:
+                                       //pre 5.1.3 historical by type display
+                                       groupname = hbtk_get_label(CYA_ACC_TYPE, acc->type);
+                               break;
+                       }
+
+                       //#1820853 groupname could be NULL
+                       if( groupname != NULL )
+                       {
+                               if( g_hash_table_contains(h_group, groupname) == FALSE )
+                               {
+                                       group = g_malloc0(sizeof(PnlAccGrp));
+                                       if( group )
+                                       {
+                                               group->acclist = g_ptr_array_sized_new(nballoc);
+                                               group->expanded = list_account_level1_expanded(treeview, groupname);
+                                               g_hash_table_insert(h_group, g_strdup(groupname), group );
+                                               DB( g_print(" grp '%s' exp:%d\n", groupname, group->expanded) );
+                                       }
+                               }
+
+                               group = g_hash_table_lookup(h_group, groupname);
+                               if( group != NULL )
+                               {
+                                       g_ptr_array_add(group->acclist, (gpointer)acc);
+                                       DB( g_print(" + acc '%s'\n", acc->name) );
+                               }
+                       }
+               }
+               elt = g_list_next(elt);
+       }
+
+       g_list_free(lacc);
+       
+       return h_group;
+}
+
+
+
+
+
+void ui_hub_account_populate(GtkWidget *widget, gpointer user_data)
+{
+struct hbfile_data *data;
+GtkTreeModel *model;
+GtkTreeIter  iter1, child_iter;
+Account *acc;
+guint j, nbtype;
+gdouble gtbank, gttoday, gtfuture;
+GHashTable *h_group;
+GHashTableIter grp_iter;
+gpointer key, value;
+
+       DB( g_print("\n[hub-account] populate\n") );
+
+       data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
+       h_group = ui_hub_account_groups_get(GTK_TREE_VIEW(data->LV_acc), PREFS->pnl_acc_show_by, data->showall);
+
+       DB( g_print("\n\n populate listview, %d group(s)\n", g_hash_table_size(h_group)) );
+
+       nbtype = 0;
+       gtbank = gttoday = gtfuture = 0;
+       model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_acc));
+       gtk_tree_store_clear (GTK_TREE_STORE(model));
+
+       g_hash_table_iter_init (&grp_iter, h_group);
+       while (g_hash_table_iter_next (&grp_iter, &key, &value))
+       {
+       PnlAccGrp *group = value;
+       gdouble tbank, ttoday, tfuture;
+       gint position;
+
+               if(group != NULL)
+               {
+                       nbtype++;
+                       //1: Header: Bank, Cash, ...
+                       DB( g_print(" g '%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].name != NULL && t < 32)
+                               {
+                                       if( !strcmp(CYA_ACC_TYPE[t].name, 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);
+
+                       //2: Accounts for real
+                       tbank = ttoday = tfuture = 0;
+                       for(j=0;j<group->acclist->len;j++)
+                       {
+                               acc = g_ptr_array_index(group->acclist, 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("  + '%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(group->acclist->len > 1)
+                       {
+                               DB( g_print("  + 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);
+
+                       if( group->expanded == TRUE )
+                       {
+                       GtkTreePath *tmppath = gtk_tree_model_get_path(model, &iter1);
+
+                               DB( g_print(" expanding '%s'\n", (gchar *)key) );
+                               gtk_tree_view_expand_row(GTK_TREE_VIEW(data->LV_acc), tmppath, TRUE);
+                               gtk_tree_path_free(tmppath);
+                       }
+                       
+                       /* add to grand total */
+                       gtbank += tbank;
+                       gttoday += ttoday;
+                       gtfuture += tfuture;
+
+               }
+
+       }
+
+       DB( g_print(" + grand total :: %.2f %.2f %.2f\n", gtbank, gttoday, gtfuture) );
+
+       // Grand total
+       if( nbtype > 1 )
+       {
+               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);
+       }
+
+       //gtk_tree_view_expand_all(GTK_TREE_VIEW(data->LV_acc));
+       
+       ui_hub_account_groups_free(h_group);
+
+}
+
+
+
+/* Callback function for the undo action */
+/*static void
+activate_action (GSimpleAction *action, GVariant *parameter, gpointer user_data)
+{
+  g_print ("Action %s activated\n", g_action_get_name (G_ACTION (action)));
+}*/
+
+static void
+ui_hub_account_activate_toggle (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_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_hub_account_populate(GLOBALS->mainwindow, NULL);
+
+  g_simple_action_set_state (action, new_state);
+  g_variant_unref (old_state);
+}
+
+static void
+ui_hub_account_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_hub_account_populate(GLOBALS->mainwindow, NULL);
+
+  g_simple_action_set_state (action, new_state);
+  g_variant_unref (old_state);
+}
+
+
+static const GActionEntry actions[] = {
+//     name, function(), type, state, 
+//  { "paste", activate_action, NULL, NULL,      NULL, {0,0,0} },
+       { "showall", ui_hub_account_activate_toggle, NULL, "false" , NULL, {0,0,0} },
+       { "groupby", ui_hub_account_activate_radio ,  "s", "'type'", NULL, {0,0,0} }
+};
+
+
+void ui_hub_account_setup(struct hbfile_data *data)
+{
+GAction *action;
+GVariant *new_state;
+
+       if( !G_IS_SIMPLE_ACTION_GROUP(data->action_group_acc) )
+               return;
+
+       action = g_action_map_lookup_action (G_ACTION_MAP (data->action_group_acc), "showall");
+       if( action )
+       {
+               new_state = g_variant_new_boolean (data->showall);
+               g_simple_action_set_state (G_SIMPLE_ACTION(action), new_state);
+       }
+       
+       action = g_action_map_lookup_action (G_ACTION_MAP (data->action_group_acc), "groupby");
+       if( action )
+       {
+               const gchar *value = "type";
+               if( PREFS->pnl_acc_show_by == DSPACC_GROUP_BY_BANK )
+                       value = "bank";
+               
+               new_state = g_variant_new_string (value);
+               g_simple_action_set_state (G_SIMPLE_ACTION (action), new_state);
+       }
+
+}
+
+
+GtkWidget *ui_hub_account_create(struct hbfile_data *data)
+{
+GtkWidget *hub, *label, *widget, *sw, *tbar, *hbox, *image;
+GtkToolItem *toolitem;
+
+       DB( g_print("\n[hub-account] create\n") );
+
+
+       hub = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+       gtk_container_set_border_width(GTK_CONTAINER(hub), 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_box_pack_start (GTK_BOX (hub), sw, TRUE, TRUE, 0);
+       widget = (GtkWidget *)create_list_account();
+       data->LV_acc = widget;
+       gtk_container_add (GTK_CONTAINER (sw), widget);
+
+       //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 (hub), 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)
+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 institution"), "actions.groupby::bank");
+       g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
+       g_object_unref (section);
+
+
+       GSimpleActionGroup *group = g_simple_action_group_new ();
+       data->action_group_acc = group;
+       g_action_map_add_action_entries (G_ACTION_MAP (group), actions, G_N_ELEMENTS (actions), data);
+
+
+       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);
+
+       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));
+
+       g_signal_connect (G_OBJECT (data->BT_expandall  ), "clicked"      , G_CALLBACK (ui_hub_account_expand_all), NULL);
+       g_signal_connect (G_OBJECT (data->BT_collapseall), "clicked"      , G_CALLBACK (ui_hub_account_collapse_all), NULL);
+
+       
+       return hub;
+}
+
This page took 0.025108 seconds and 4 git commands to generate.