~mdoyen/homebank/5.7.x

« back to all changes in this revision

Viewing changes to src/hub-reptotal.c

  • Committer: Maxime Doyen
  • Date: 2023-09-06 19:22:10 UTC
  • Revision ID: homebank@free.fr-20230906192210-kal1pe00sty1jt2g
5.7 release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  HomeBank -- Free, easy, personal accounting for everyone.
 
2
 *  Copyright (C) 1995-2023 Maxime DOYEN
 
3
 *
 
4
 *  This file is part of HomeBank.
 
5
 *
 
6
 *  HomeBank is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 2 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  HomeBank is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include "homebank.h"
 
21
 
 
22
#include "dsp-mainwindow.h"
 
23
 
 
24
#include "hub-reptotal.h"
 
25
#include "gtk-chart.h"
 
26
#include "list-report.h"
 
27
 
 
28
 
 
29
/****************************************************************************/
 
30
/* Debug macros                                                             */
 
31
/****************************************************************************/
 
32
#define MYDEBUG 0
 
33
 
 
34
#if MYDEBUG
 
35
#define DB(x) (x);
 
36
#else
 
37
#define DB(x);
 
38
#endif
 
39
 
 
40
 
 
41
#define SHOW_TREE_VIEW  0
 
42
 
 
43
 
 
44
/* our global datas */
 
45
extern struct HomeBank *GLOBALS;
 
46
extern struct Preferences *PREFS;
 
47
 
 
48
 
 
49
static gint list_topspending_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
 
50
{
 
51
gint sortcol = GPOINTER_TO_INT(userdata);
 
52
gint pos1, pos2, retval = 0;
 
53
gdouble val1, val2;
 
54
 
 
55
        gtk_tree_model_get(model, a,
 
56
                LST_TOPSPEND_POS, &pos1,
 
57
                LST_TOPSPEND_AMOUNT, &val1,
 
58
                -1);
 
59
        gtk_tree_model_get(model, b,
 
60
                LST_TOPSPEND_POS, &pos2,
 
61
                LST_TOPSPEND_AMOUNT, &val2,
 
62
                -1);
 
63
 
 
64
        //#1933164 should return
 
65
        // > 0 if a sorts before b 
 
66
        // = 0 if a sorts with b
 
67
        // < 0 if a sorts after b
 
68
 
 
69
        switch(sortcol)
 
70
        {
 
71
                case LST_TOPSPEND_POS:
 
72
                        retval = pos1 - pos2;
 
73
                        //DB( g_print(" sort %3d = %3d :: %d\n", pos1, pos2, retval) );
 
74
                        break;
 
75
                case LST_TOPSPEND_AMOUNT:
 
76
                        //retval = (ABS(val1) - ABS(val2)) > 0 ? -1 : 1;
 
77
                        retval = (val1 - val2) > 0 ? -1 : 1;
 
78
                        //DB( g_print(" sort %.2f = %.2f :: %d\n", val1, val2, retval) );
 
79
                        break;
 
80
        }
 
81
 
 
82
        return retval;
 
83
}
 
84
 
 
85
 
 
86
static GtkWidget *create_list_topspending(void)
 
87
{
 
88
GtkTreeStore *store;
 
89
GtkWidget *view;
 
90
 
 
91
        /* create list store */
 
92
        store = lst_report_new();
 
93
 
 
94
        //treeview
 
95
        view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
 
96
        g_object_unref(store);
 
97
 
 
98
        //5.7
 
99
        gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_TOPSPEND_POS    , list_topspending_compare_func, GINT_TO_POINTER(LST_TOPSPEND_POS), NULL);
 
100
        gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_TOPSPEND_AMOUNT    , list_topspending_compare_func, GINT_TO_POINTER(LST_TOPSPEND_AMOUNT), NULL);
 
101
        //gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), list_topspending_compare_func, NULL, NULL);
 
102
 
 
103
        return(view);
 
104
}
 
105
 
 
106
 
 
107
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
 
108
 
 
109
 
 
110
void ui_hub_reptotal_update(GtkWidget *widget, gpointer user_data)
 
111
{
 
112
struct hbfile_data *data;
 
113
GtkTreeModel *model;
 
114
gchar *title = NULL;
 
115
gchar strbuffer[G_ASCII_DTOSTR_BUF_SIZE];
 
116
 
 
117
        DB( g_print("\n[hub-total] update\n") );
 
118
 
 
119
        data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
 
120
 
 
121
        //TODO: reuse this ?
 
122
        hb_strfmon(strbuffer, G_ASCII_DTOSTR_BUF_SIZE-1, data->hubtot_total, GLOBALS->kcur, GLOBALS->minor);    
 
123
 
 
124
        switch( PREFS->hub_tot_view )
 
125
        {
 
126
                case HUB_TOT_VIEW_CATEGORY: 
 
127
                        title = g_strdup_printf(_("Top %d Spending / Category"), PREFS->rep_maxspenditems);
 
128
                        break;
 
129
                case HUB_TOT_VIEW_PAYEE:
 
130
                        title = g_strdup_printf(_("Top %d Spending / Payee"), PREFS->rep_maxspenditems);
 
131
                        break;
 
132
                case HUB_TOT_VIEW_ACCOUNT:
 
133
                        title = g_strdup_printf(_("Top %d Spending / Account"), PREFS->rep_maxspenditems);
 
134
                        break;
 
135
                case HUB_TOT_VIEW_BALANCE: 
 
136
                        title = g_strdup_printf(_("Account Balance"));
 
137
                        break;
 
138
        }
 
139
 
 
140
        gtk_chart_set_color_scheme(GTK_CHART(data->RE_hubtot_chart), PREFS->report_color_scheme);
 
141
        gtk_chart_set_smallfont (GTK_CHART(data->RE_hubtot_chart), PREFS->rep_smallfont);
 
142
        gtk_chart_set_currency(GTK_CHART(data->RE_hubtot_chart), GLOBALS->kcur);
 
143
 
 
144
        //set column1 != column2 will dual display
 
145
        model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_hubtot));
 
146
        gtk_chart_set_datas_total(GTK_CHART(data->RE_hubtot_chart), model, LST_TOPSPEND_AMOUNT, LST_TOPSPEND_AMOUNT, title, strbuffer);
 
147
 
 
148
        g_free(title);
 
149
}
 
150
 
 
151
 
 
152
void ui_hub_reptotal_clear(GtkWidget *widget, gpointer user_data)
 
153
{
 
154
struct hbfile_data *data;
 
155
GtkTreeModel *model;
 
156
 
 
157
        DB( g_print("\n[hub-total] clear\n") );
 
158
 
 
159
        data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
 
160
 
 
161
        model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_hubtot));
 
162
        gtk_tree_store_clear (GTK_TREE_STORE(model));
 
163
 
 
164
}
 
165
 
 
166
 
 
167
void ui_hub_reptotal_populate(GtkWidget *widget, gpointer user_data)
 
168
{
 
169
struct hbfile_data *data;
 
170
GtkTreeModel *model;
 
171
GtkTreeIter  iter, parent, *tmpparent;
 
172
DataTable *dt;
 
173
gint range;
 
174
gint tmpsrc;
 
175
guint i, max_items;
 
176
gdouble total, other;
 
177
gboolean tmpaccbal, valid;
 
178
 
 
179
        DB( g_print("\n[hub-total] populate\n") );
 
180
 
 
181
        data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
 
182
 
 
183
        tmpsrc = REPORT_SRC_CATEGORY;
 
184
        //tmptype = REPORT_TYPE_EXPENSE;
 
185
        tmpaccbal = FALSE;
 
186
 
 
187
        switch( PREFS->hub_tot_view )
 
188
        {
 
189
                case HUB_TOT_VIEW_CATEGORY: tmpsrc = REPORT_SRC_CATEGORY; break;
 
190
                case HUB_TOT_VIEW_PAYEE   : tmpsrc = REPORT_SRC_PAYEE; break;
 
191
                case HUB_TOT_VIEW_ACCOUNT : tmpsrc = REPORT_SRC_ACCOUNT; break;
 
192
                case HUB_TOT_VIEW_BALANCE : 
 
193
                        tmpsrc = REPORT_SRC_ACCOUNT; 
 
194
                        tmpaccbal = TRUE;
 
195
                        break;
 
196
        }
 
197
 
 
198
        //type  = hbtk_radio_button_get_active(GTK_CONTAINER(data->RA_type));
 
199
        range = hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data->CY_hubtot_range));
 
200
        PREFS->hub_tot_range = range;
 
201
 
 
202
        DB( g_print(" range=%d\n", range) );
 
203
 
 
204
        //if(range == FLT_RANGE_MISC_CUSTOM)
 
205
        //      return;
 
206
 
 
207
        filter_preset_daterange_set(data->hubtot_filter, range, 0);
 
208
        //#1989211 option to include xfer by default
 
209
        if(PREFS->stat_includexfer == FALSE)
 
210
                filter_preset_type_set(data->hubtot_filter, FLT_TYPE_INTXFER, FLT_EXCLUDE);
 
211
        else
 
212
                filter_preset_type_set(data->hubtot_filter, FLT_TYPE_ALL, FLT_INCLUDE);
 
213
 
 
214
 
 
215
        DB( hb_print_date(data->hubtot_filter->mindate, "min:") );
 
216
        DB( hb_print_date(data->hubtot_filter->maxdate, "max:") );
 
217
 
 
218
        total = 0.0;
 
219
 
 
220
        GQueue *txn_queue = hbfile_transaction_get_partial(data->hubtot_filter->mindate, data->hubtot_filter->maxdate);
 
221
        if(!tmpaccbal)
 
222
        {
 
223
                dt = report_compute(tmpsrc, REPORT_INTVL_NONE, data->hubtot_filter, txn_queue, FALSE, FALSE);
 
224
        }
 
225
        else
 
226
                dt = report_compute(tmpsrc, REPORT_INTVL_NONE, data->hubtot_filter, txn_queue, FALSE, TRUE);
 
227
                //dt = report_compute_balance(tmpsrc, REPORT_INTVL_NONE, data->hubtot_filter, TRUE);
 
228
        g_queue_free (txn_queue);
 
229
 
 
230
        if(dt)
 
231
        {
 
232
                //todo: should use clear func
 
233
                model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_hubtot));
 
234
                gtk_tree_store_clear (GTK_TREE_STORE(model));
 
235
 
 
236
                g_object_ref(model); /* Make sure the model stays with us after the tree view unrefs it */
 
237
                gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_hubtot), NULL); /* Detach model from view */
 
238
 
 
239
                DB( g_print("\n -- populate total listview %d rows --\n", dt->nbrows) );
 
240
 
 
241
                // insert into the treeview
 
242
                for(i=0 ; i<dt->nbrows ; i++)
 
243
                {
 
244
                DataRow *dr;
 
245
                gdouble value;
 
246
                guint32 reskey;
 
247
 
 
248
                        //since 5.7 we use the dt-keylst here to insert cat before subcat
 
249
                        reskey = dt->keylist[i];
 
250
                        dr = report_data_get_row(dt, reskey);
 
251
 
 
252
                        //if( tmptype == REPORT_TYPE_EXPENSE && !dr->expense[0] ) continue;
 
253
                        //if( tmptype == REPORT_TYPE_INCOME && !dr->income[1] ) continue;
 
254
                        if( !dr->rowexp && !dr->rowinc )
 
255
                        {
 
256
                                DB( g_print(" - %d : %s k='%d' %.2f %.2f, skipped no data\n", i, dr->label, reskey, dr->rowexp, dr->rowinc) );
 
257
                                continue;
 
258
                        }
 
259
 
 
260
                        //if( tmpsrc == REPORT_SRC_ACCOUNT && (i == 0) )
 
261
                        //      continue;
 
262
 
 
263
                        //#2031245
 
264
                        if( tmpaccbal == TRUE )
 
265
                                value = dr->rowexp + dr->rowinc;
 
266
                        else
 
267
                                value = dr->rowexp; 
 
268
                        
 
269
                        // manage the toplevel for category
 
270
                        tmpparent = NULL;
 
271
                        if( tmpsrc == REPORT_SRC_CATEGORY )
 
272
                        {
 
273
                        Category *tmpcat = da_cat_get(reskey);
 
274
                                if( tmpcat != NULL)
 
275
                                {
 
276
                                        //if( list_topspending_get_top_level (GTK_TREE_MODEL(model), tmpcat->parent, &parent) == TRUE )
 
277
                                        if( hbtk_tree_store_get_top_level(GTK_TREE_MODEL(model), LST_TOPSPEND_KEY, tmpcat->parent, &parent) )
 
278
                                        {
 
279
                                                tmpparent = &parent;
 
280
                                        }
 
281
                                        
 
282
                                        //compute total
 
283
                                        if( tmpcat->parent == 0 )
 
284
                                        {
 
285
                                                if(value < 0.0 )
 
286
                                                        total += value;
 
287
                                        }
 
288
                                }
 
289
                        }
 
290
                        else
 
291
                        {
 
292
                                if(value < 0.0 || tmpaccbal == TRUE )
 
293
                                        total += value;
 
294
                        }
 
295
        
 
296
                        if( value < 0.0 || tmpaccbal == TRUE )
 
297
                        {
 
298
                                // append test
 
299
                                gtk_tree_store_append (GTK_TREE_STORE(model), &iter, tmpparent);
 
300
                                gtk_tree_store_set (GTK_TREE_STORE(model), &iter,
 
301
                                          LST_TOPSPEND_POS, i,
 
302
                                          LST_TOPSPEND_KEY, reskey,
 
303
                                          LST_TOPSPEND_NAME, dr->label,
 
304
                                          LST_TOPSPEND_AMOUNT, value,
 
305
                                          //LST_TOPSPEND_RATE, (gint)(((ABS(value)*100)/ABS(total)) + 0.5),
 
306
                                          -1);
 
307
 
 
308
                                DB( g_print(" - %d : %s k='%d' v='%f' %f %f, added\n", i, dr->label, reskey, value, dr->rowexp, dr->rowinc) );
 
309
                        }
 
310
                        else
 
311
                        {
 
312
                                DB( g_print(" - %d : %s k='%d' v='%f' %f %f, skipped\n", i, dr->label, reskey, value, dr->rowexp, dr->rowinc) );
 
313
                        }
 
314
 
 
315
                }
 
316
 
 
317
                //sort by expense descending
 
318
                gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), LST_TOPSPEND_AMOUNT, GTK_SORT_DESCENDING);
 
319
 
 
320
                //5.7 order & limitation moved here
 
321
                if( tmpaccbal == FALSE )
 
322
                {
 
323
                        other = 0.0;
 
324
                        i = 0;
 
325
                        max_items = (guint)PREFS->rep_maxspenditems;
 
326
 
 
327
                        {
 
328
                        GtkTreeIter remiter;
 
329
                        gdouble othamt;
 
330
                        gboolean do_remove;
 
331
 
 
332
                                DB( g_print(" aggregate items\n") );
 
333
                                valid = gtk_tree_model_get_iter_first(model, &iter);
 
334
                                while( valid )
 
335
                                {
 
336
                                        gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
 
337
                                                  LST_TOPSPEND_POS, i++,
 
338
                                                  -1);
 
339
 
 
340
                                        do_remove = (i > max_items ) ? TRUE : FALSE;
 
341
 
 
342
                                        remiter = iter;
 
343
                                        valid = gtk_tree_model_iter_next(model, &iter);
 
344
 
 
345
                                        if( do_remove )
 
346
                                        {
 
347
                                                gtk_tree_model_get (GTK_TREE_MODEL(model), &remiter,
 
348
                                                        LST_TOPSPEND_AMOUNT, &othamt,
 
349
                                                        -1);
 
350
                                                        
 
351
                                                if(othamt < 0.0)
 
352
                                                        other += othamt;
 
353
 
 
354
                                                DB( g_print(" other += %.2f\n", othamt) );
 
355
                                                hbtk_tree_store_remove_iter_with_child(model, &remiter);
 
356
                                        }
 
357
                                }
 
358
 
 
359
                                // append 'Others'
 
360
                                if(ABS(other) > 0)
 
361
                                {
 
362
                                        DB( g_print(" - %d : %s k='%d' v='%f'\n", max_items+1, "Other", 0, other) );
 
363
 
 
364
                                        gtk_tree_store_append (GTK_TREE_STORE(model), &iter, NULL);
 
365
                                        gtk_tree_store_set (GTK_TREE_STORE(model), &iter,
 
366
                                                  LST_TOPSPEND_POS, max_items+1,
 
367
                                                  LST_TOPSPEND_KEY, 0,
 
368
                                                  LST_TOPSPEND_NAME, _("Other"),
 
369
                                                  LST_TOPSPEND_AMOUNT, other,
 
370
                                                  //LST_TOPSPEND_RATE, (gint)(((ABS(other)*100)/ABS(total)) + 0.5),
 
371
                                                  -1);
 
372
                                }
 
373
 
 
374
                        }
 
375
 
 
376
                        gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), LST_TOPSPEND_POS, GTK_SORT_ASCENDING);
 
377
                }
 
378
 
 
379
                /* Re-attach model to view */
 
380
                gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_hubtot), model);
 
381
                g_object_unref(model);
 
382
 
 
383
                // update chart and widgets
 
384
                {
 
385
                gchar *daterange;
 
386
 
 
387
                        data->hubtot_total = total;
 
388
                        ui_hub_reptotal_update(widget, data);
 
389
                        
 
390
                        daterange = filter_daterange_text_get(data->hubtot_filter);
 
391
                        gtk_widget_set_tooltip_markup(GTK_WIDGET(data->CY_hubtot_range), daterange);
 
392
                        g_free(daterange);
 
393
                }
 
394
 
 
395
                //TODO: later needs to keep this until dispose LV
 
396
                da_datatable_free (dt);
 
397
 
 
398
        }
 
399
        
 
400
 
 
401
}
 
402
 
 
403
 
 
404
static void
 
405
ui_hub_reptotal_activate_radio (GSimpleAction *action, GVariant *parameter, gpointer user_data)
 
406
{
 
407
GVariant *old_state, *new_state;
 
408
 
 
409
        old_state = g_action_get_state (G_ACTION (action));
 
410
        new_state = g_variant_new_string (g_variant_get_string (parameter, NULL));
 
411
 
 
412
        DB( g_print ("Radio action %s activated, state changes from %s to %s\n",
 
413
           g_action_get_name (G_ACTION (action)),
 
414
           g_variant_get_string (old_state, NULL),
 
415
           g_variant_get_string (new_state, NULL)) );
 
416
 
 
417
        PREFS->hub_tot_view = HUB_TOT_VIEW_NONE;
 
418
 
 
419
        if( !strcmp("cat", g_variant_get_string(new_state, NULL)) )
 
420
                PREFS->hub_tot_view = HUB_TOT_VIEW_CATEGORY;
 
421
        else    
 
422
        if( !strcmp("pay", g_variant_get_string(new_state, NULL)) )
 
423
                PREFS->hub_tot_view = HUB_TOT_VIEW_PAYEE;
 
424
        else
 
425
        if( !strcmp("acc", g_variant_get_string(new_state, NULL)) )
 
426
                PREFS->hub_tot_view = HUB_TOT_VIEW_ACCOUNT;
 
427
        else
 
428
        if( !strcmp("bal", g_variant_get_string(new_state, NULL)) )
 
429
                PREFS->hub_tot_view = HUB_TOT_VIEW_BALANCE;
 
430
 
 
431
        g_simple_action_set_state (action, new_state);
 
432
        g_variant_unref (old_state);
 
433
 
 
434
        ui_hub_reptotal_populate(GLOBALS->mainwindow, NULL);
 
435
}
 
436
 
 
437
 
 
438
static const GActionEntry actions[] = {
 
439
//      name, function(), type, state, 
 
440
        { "view", ui_hub_reptotal_activate_radio ,  "s", "'cat'", NULL, {0,0,0} }
 
441
};
 
442
 
 
443
 
 
444
void ui_hub_reptotal_setup(struct hbfile_data *data)
 
445
{
 
446
GAction *action;
 
447
GVariant *new_state;
 
448
 
 
449
        data->hubtot_filter = da_flt_malloc();
 
450
        filter_reset(data->hubtot_filter);
 
451
        
 
452
        hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data->CY_hubtot_range), PREFS->hub_tot_range);
 
453
 
 
454
        //#1989211 option to include xfer by default
 
455
        if(PREFS->stat_includexfer == FALSE)
 
456
                filter_preset_type_set(data->hubtot_filter, FLT_TYPE_INTXFER, FLT_EXCLUDE);
 
457
 
 
458
        if( !G_IS_SIMPLE_ACTION_GROUP(data->hubtot_action_group) )
 
459
                return;
 
460
 
 
461
        action = g_action_map_lookup_action (G_ACTION_MAP (data->hubtot_action_group), "view");
 
462
        if( action )
 
463
        {
 
464
        const gchar *value = "cat";
 
465
 
 
466
                switch( PREFS->hub_tot_view )
 
467
                {
 
468
                        case HUB_TOT_VIEW_CATEGORY: value = "cat"; break;
 
469
                        case HUB_TOT_VIEW_PAYEE:    value = "pay"; break;
 
470
                        case HUB_TOT_VIEW_ACCOUNT:  value = "acc"; break;
 
471
                        case HUB_TOT_VIEW_BALANCE:  value = "bal"; break;
 
472
                }
 
473
                
 
474
                new_state = g_variant_new_string (value);
 
475
                g_simple_action_set_state (G_SIMPLE_ACTION (action), new_state);
 
476
        }
 
477
}
 
478
 
 
479
 
 
480
void ui_hub_reptotal_dispose(struct hbfile_data *data)
 
481
{
 
482
        gtk_chart_set_datas_none(GTK_CHART(data->RE_hubtot_chart));
 
483
        da_flt_free(data->hubtot_filter);
 
484
        data->hubtot_filter = NULL;
 
485
        
 
486
}
 
487
 
 
488
 
 
489
GtkWidget *ui_hub_reptotal_create(struct hbfile_data *data)
 
490
{
 
491
GtkWidget *hub, *hbox, *bbox, *tbar;
 
492
GtkWidget *label, *widget, *image;
 
493
 
 
494
        DB( g_print("\n[hub-total] create\n") );
 
495
 
 
496
        // /!\ this widget has to be freed
 
497
        widget = (GtkWidget *)create_list_topspending();
 
498
        data->LV_hubtot = widget;
 
499
 
 
500
        hub = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
 
501
        hb_widget_set_margins(GTK_WIDGET(hub), 0, SPACING_SMALL, SPACING_SMALL, SPACING_SMALL);
 
502
        data->GR_hubtot = hub;
 
503
 
 
504
#if SHOW_TREE_VIEW == 1
 
505
        GtkWidget *scrollwin = gtk_scrolled_window_new (NULL, NULL);
 
506
        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
 
507
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
508
        gtk_box_pack_start (GTK_BOX(hub), scrollwin, TRUE, TRUE, 0);
 
509
        gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW(scrollwin), data->LV_hubtot);
 
510
        gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (data->LV_hubtot), GTK_TREE_VIEW_GRID_LINES_BOTH);
 
511
#endif
 
512
 
 
513
 
 
514
        /* chart + listview */
 
515
        hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
 
516
        gtk_box_pack_start (GTK_BOX (hub), hbox, TRUE, TRUE, 0);
 
517
 
 
518
        widget = gtk_chart_new(CHART_TYPE_PIE);
 
519
        data->RE_hubtot_chart = widget;
 
520
        gtk_chart_set_minor_prefs(GTK_CHART(widget), PREFS->euro_value, PREFS->minor_cur.symbol);
 
521
        gtk_chart_set_currency(GTK_CHART(widget), GLOBALS->kcur);
 
522
        gtk_chart_show_legend(GTK_CHART(widget), TRUE, TRUE);
 
523
        gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
 
524
 
 
525
        //list toolbar
 
526
        tbar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_MEDIUM);
 
527
        gtk_style_context_add_class (gtk_widget_get_style_context (tbar), GTK_STYLE_CLASS_INLINE_TOOLBAR);
 
528
        gtk_box_pack_start (GTK_BOX (hub), tbar, FALSE, FALSE, 0);
 
529
 
 
530
        label = make_label_group(_("Total chart"));
 
531
        data->LB_hubtot = label;
 
532
        gtk_box_pack_start (GTK_BOX (tbar), label, FALSE, FALSE, 0);
 
533
 
 
534
        /* total + date range */
 
535
        bbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
 
536
        gtk_box_pack_end (GTK_BOX (tbar), bbox, FALSE, FALSE, 0);
 
537
 
 
538
                widget = gtk_menu_button_new();
 
539
                gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
 
540
 
 
541
                gtk_menu_button_set_direction (GTK_MENU_BUTTON(widget), GTK_ARROW_UP);
 
542
                gtk_widget_set_halign (widget, GTK_ALIGN_END);
 
543
                image = gtk_image_new_from_icon_name (ICONNAME_EMBLEM_SYSTEM, GTK_ICON_SIZE_MENU);
 
544
                g_object_set (widget, "image", image,  NULL);
 
545
 
 
546
        GSimpleActionGroup *group = g_simple_action_group_new ();
 
547
        data->hubtot_action_group = group;
 
548
        g_action_map_add_action_entries (G_ACTION_MAP (group), actions, G_N_ELEMENTS (actions), data);
 
549
        gtk_widget_insert_action_group (widget, "actions", G_ACTION_GROUP(group));
 
550
 
 
551
        //gmenu test (see test folder into gtk)
 
552
GMenu *menu, *section;
 
553
 
 
554
        menu = g_menu_new ();
 
555
        section = g_menu_new ();
 
556
        g_menu_append (section, _("Category") , "actions.view::cat");
 
557
        g_menu_append (section, _("Payee")    , "actions.view::pay");
 
558
        g_menu_append (section, _("Account")  , "actions.view::acc");
 
559
        g_menu_append (section, _("Balance")  , "actions.view::bal");
 
560
        g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
 
561
        g_object_unref (section);
 
562
 
 
563
        gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (widget), G_MENU_MODEL (menu));
 
564
 
 
565
 
 
566
        data->CY_hubtot_range = make_daterange(NULL, DATE_RANGE_CUSTOM_HIDDEN);
 
567
        gtk_box_pack_end (GTK_BOX (tbar), data->CY_hubtot_range, FALSE, FALSE, 0);
 
568
 
 
569
        //hbtk_radio_button_connect (GTK_CONTAINER(data->RA_type), "toggled", G_CALLBACK (ui_hub_reptotal_populate), NULL);
 
570
 
 
571
        g_signal_connect (data->CY_hubtot_range, "changed", G_CALLBACK (ui_hub_reptotal_populate), NULL);
 
572
        
 
573
        return hub;
 
574
}
 
575