1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 Maxime DOYEN
4 * This file is part of HomeBank.
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.
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.
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/>.
23 #include "rep-stats.h"
25 #include "list-operation.h"
26 #include "gtk-chart.h"
27 #include "gtk-dateentry.h"
29 #include "dsp-mainwindow.h"
30 #include "ui-account.h"
32 #include "ui-category.h"
33 #include "ui-filter.h"
34 #include "ui-transaction.h"
36 /****************************************************************************/
38 /****************************************************************************/
47 /* our global datas */
48 extern struct HomeBank
*GLOBALS
;
49 extern struct Preferences
*PREFS
;
53 static void ui_repdist_action_viewlist(GtkAction
*action
, gpointer user_data
);
54 static void ui_repdist_action_viewbar(GtkAction
*action
, gpointer user_data
);
55 static void ui_repdist_action_viewpie(GtkAction
*action
, gpointer user_data
);
56 static void ui_repdist_action_detail(GtkAction
*action
, gpointer user_data
);
57 static void ui_repdist_action_legend(GtkAction
*action
, gpointer user_data
);
58 static void ui_repdist_action_rate(GtkAction
*action
, gpointer user_data
);
59 static void ui_repdist_action_filter(GtkAction
*action
, gpointer user_data
);
60 static void ui_repdist_action_refresh(GtkAction
*action
, gpointer user_data
);
63 static GtkRadioActionEntry radio_entries
[] = {
64 { "List" , ICONNAME_HB_VIEW_LIST
, N_("List") , NULL
, N_("View results as list"), 0 },
65 { "Column" , ICONNAME_HB_VIEW_COLUMN
, N_("Column") , NULL
, N_("View results as column"), 1 },
66 { "Donut" , ICONNAME_HB_VIEW_DONUT
, N_("Donut") , NULL
, N_("View results as donut"), 2 },
68 static guint n_radio_entries
= G_N_ELEMENTS (radio_entries
);
71 static GtkActionEntry entries
[] = {
72 { "Filter" , ICONNAME_HB_FILTER
, N_("Filter") , NULL
, N_("Edit filter"), G_CALLBACK (ui_repdist_action_filter
) },
73 { "Refresh" , ICONNAME_HB_REFRESH
, N_("Refresh"), NULL
, N_("Refresh results"), G_CALLBACK (ui_repdist_action_refresh
) },
75 //{ "Export" , ICONNAME_HB_FILE_EXPORT , N_("Export") , NULL, N_("Export as CSV"), G_CALLBACK (ui_repdist_action_export) },
77 static guint n_entries
= G_N_ELEMENTS (entries
);
80 static GtkToggleActionEntry toggle_entries
[] = {
81 { "Detail", ICONNAME_HB_OPE_SHOW
, /* name, icon-name */
82 N_("Detail"), NULL
, /* label, accelerator */
83 N_("Toggle detail"), /* tooltip */
84 G_CALLBACK (ui_repdist_action_detail
),
85 FALSE
}, /* is_active */
87 { "Legend", ICONNAME_HB_SHOW_LEGEND
, /* name, icon-name */
88 N_("Legend"), NULL
, /* label, accelerator */
89 N_("Toggle legend"), /* tooltip */
90 G_CALLBACK (ui_repdist_action_legend
),
91 TRUE
}, /* is_active */
93 { "Rate", ICONNAME_HB_SHOW_RATE
, /* name, icon-name */
94 N_("Rate"), NULL
, /* label, accelerator */
95 N_("Toggle rate"), /* tooltip */
96 G_CALLBACK (ui_repdist_action_rate
),
97 FALSE
}, /* is_active */
100 static guint n_toggle_entries
= G_N_ELEMENTS (toggle_entries
);
104 static const gchar
*ui_info
=
106 " <toolbar name='ToolBar'>"
107 " <toolitem action='List'/>"
108 " <toolitem action='Column'/>"
109 " <toolitem action='Donut'/>"
111 " <toolitem action='Detail'/>"
112 " <toolitem action='Legend'/>"
113 " <toolitem action='Rate'/>"
115 " <toolitem action='Filter'/>"
116 " <toolitem action='Refresh'/>"
118 //" <toolitem action='Export'/>"
119 // replaced by a menubutton
125 static void ui_repdist_date_change(GtkWidget
*widget
, gpointer user_data
);
126 static void ui_repdist_range_change(GtkWidget
*widget
, gpointer user_data
);
127 static void ui_repdist_detail(GtkWidget
*widget
, gpointer user_data
);
128 static void ui_repdist_update(GtkWidget
*widget
, gpointer user_data
);
129 static void ui_repdist_update_total(GtkWidget
*widget
, gpointer user_data
);
130 static void ui_repdist_compute(GtkWidget
*widget
, gpointer user_data
);
131 static void ui_repdist_sensitive(GtkWidget
*widget
, gpointer user_data
);
132 static void ui_repdist_toggle_detail(GtkWidget
*widget
, gpointer user_data
);
133 static void ui_repdist_toggle_legend(GtkWidget
*widget
, gpointer user_data
);
134 static void ui_repdist_toggle_minor(GtkWidget
*widget
, gpointer user_data
);
135 static void ui_repdist_toggle_rate(GtkWidget
*widget
, gpointer user_data
);
136 static GtkWidget
*ui_list_repdist_create(void);
137 static void ui_repdist_update_daterange(GtkWidget
*widget
, gpointer user_data
);
138 static void ui_repdist_update_date_widget(GtkWidget
*widget
, gpointer user_data
);
140 static GString
*ui_list_repdist_to_string(GtkTreeView
*treeview
, gboolean clipboard
);
141 static gint
ui_list_repdist_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
);
145 HbKvData CYA_REPORT_SRC
[] = {
146 { REPORT_SRC_CATEGORY
, N_("Category") },
147 { REPORT_SRC_SUBCATEGORY
, N_("Subcategory") },
148 { REPORT_SRC_PAYEE
, N_("Payee") },
149 { REPORT_SRC_ACCOUNT
, N_("Account") },
150 { REPORT_SRC_TAG
, N_("Tag") },
151 { REPORT_SRC_MONTH
, N_("Month") },
152 { REPORT_SRC_YEAR
, N_("Year") },
157 HbKvData CYA_REPORT_TYPE
[] = {
158 { REPORT_TYPE_ALL
, N_("Exp. & Inc.") },
159 { REPORT_TYPE_EXPENSE
, N_("Expense") },
160 { REPORT_TYPE_INCOME
, N_("Income") },
161 { REPORT_TYPE_BALANCE
, N_("Balance")} ,
165 extern gchar
*CYA_REPORT_MODE
[];
166 extern HbKvData CYA_REPORT_INTVL
[];
168 extern gchar
*CYA_ABMONTHS
[];
170 /* action functions -------------------- */
172 static void ui_repdist_action_viewlist(GtkAction
*action
, gpointer user_data
)
174 struct ui_repdist_data
*data
= user_data
;
176 gtk_notebook_set_current_page(GTK_NOTEBOOK(data
->GR_result
), 0);
177 ui_repdist_sensitive(data
->window
, NULL
);
180 static void ui_repdist_action_viewbar(GtkAction
*action
, gpointer user_data
)
182 struct ui_repdist_data
*data
= user_data
;
184 gtk_notebook_set_current_page(GTK_NOTEBOOK(data
->GR_result
), 1);
185 gtk_chart_set_type (GTK_CHART(data
->RE_chart
), CHART_TYPE_COL
);
186 ui_repdist_sensitive(data
->window
, NULL
);
190 static void ui_repdist_action_viewpie(GtkAction
*action
, gpointer user_data
)
192 struct ui_repdist_data
*data
= user_data
;
195 gtk_notebook_set_current_page(GTK_NOTEBOOK(data
->GR_result
), 1);
197 gtk_chart_set_type (GTK_CHART(data
->RE_chart
), CHART_TYPE_PIE
);
198 ui_repdist_sensitive(data
->window
, NULL
);
200 tmpview
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_type
));
202 // ensure not exp & inc for piechart
203 if( tmpview
== REPORT_TYPE_ALL
)
205 //g_signal_handler_block(data->CY_type, data->handler_id[HID_REPDIST_VIEW]);
206 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data
->CY_type
), REPORT_TYPE_EXPENSE
);
207 //g_signal_handler_unblock(data->CY_type, data->handler_id[HID_REPDIST_VIEW]);
213 static void ui_repdist_action_mode (GtkRadioAction
*action
, GtkRadioAction
*current
, gpointer user_data
)
217 value
= gtk_radio_action_get_current_value(GTK_RADIO_ACTION(action
));
221 ui_repdist_action_viewlist(GTK_ACTION(action
), user_data
);
224 ui_repdist_action_viewbar(GTK_ACTION(action
), user_data
);
227 ui_repdist_action_viewpie(GTK_ACTION(action
), user_data
);
233 static void ui_repdist_action_detail(GtkAction
*action
, gpointer user_data
)
235 struct ui_repdist_data
*data
= user_data
;
237 ui_repdist_toggle_detail(data
->window
, NULL
);
240 static void ui_repdist_action_legend(GtkAction
*action
, gpointer user_data
)
242 struct ui_repdist_data
*data
= user_data
;
244 ui_repdist_toggle_legend(data
->window
, NULL
);
247 static void ui_repdist_action_rate(GtkAction
*action
, gpointer user_data
)
249 struct ui_repdist_data
*data
= user_data
;
251 ui_repdist_toggle_rate(data
->window
, NULL
);
254 static void ui_repdist_action_filter(GtkAction
*action
, gpointer user_data
)
256 struct ui_repdist_data
*data
= user_data
;
259 //create_deffilter_window(data->filter, TRUE);
261 if(ui_flt_manage_dialog_new(GTK_WINDOW(data
->window
), data
->filter
, TRUE
, FALSE
) != GTK_RESPONSE_REJECT
)
263 ui_repdist_compute(data
->window
, NULL
);
264 ui_repdist_update_date_widget(data
->window
, NULL
);
265 ui_repdist_update_daterange(data
->window
, NULL
);
267 g_signal_handler_block(data
->CY_range
, data
->handler_id
[HID_REPDIST_RANGE
]);
268 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
), FLT_RANGE_OTHER
);
269 g_signal_handler_unblock(data
->CY_range
, data
->handler_id
[HID_REPDIST_RANGE
]);
274 static void ui_repdist_action_refresh(GtkAction
*action
, gpointer user_data
)
276 struct ui_repdist_data
*data
= user_data
;
278 ui_repdist_compute(data
->window
, NULL
);
281 /*static void ui_repdist_action_export(GtkAction *action, gpointer user_data)
283 struct ui_repdist_data *data = user_data;
285 ui_repdist_export_csv(data->window, NULL);
290 /* ======================== */
295 ** ============================================================================
299 static void ui_repdist_date_change(GtkWidget
*widget
, gpointer user_data
)
301 struct ui_repdist_data
*data
;
303 DB( g_print("\n[repdist] date change\n") );
305 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
307 data
->filter
->mindate
= gtk_date_entry_get_date(GTK_DATE_ENTRY(data
->PO_mindate
));
308 data
->filter
->maxdate
= gtk_date_entry_get_date(GTK_DATE_ENTRY(data
->PO_maxdate
));
310 // set min/max date for both widget
311 gtk_date_entry_set_maxdate(GTK_DATE_ENTRY(data
->PO_mindate
), data
->filter
->maxdate
);
312 gtk_date_entry_set_mindate(GTK_DATE_ENTRY(data
->PO_maxdate
), data
->filter
->mindate
);
314 g_signal_handler_block(data
->CY_range
, data
->handler_id
[HID_REPDIST_RANGE
]);
315 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
), FLT_RANGE_OTHER
);
316 g_signal_handler_unblock(data
->CY_range
, data
->handler_id
[HID_REPDIST_RANGE
]);
318 ui_repdist_compute(widget
, NULL
);
319 ui_repdist_update_daterange(widget
, NULL
);
324 static void ui_repdist_range_change(GtkWidget
*widget
, gpointer user_data
)
326 struct ui_repdist_data
*data
;
329 DB( g_print("\n[repdist] range change\n") );
331 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
333 range
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
));
335 if(range
!= FLT_RANGE_OTHER
)
337 filter_preset_daterange_set(data
->filter
, range
, 0);
339 ui_repdist_update_date_widget(data
->window
, NULL
);
341 ui_repdist_compute(data
->window
, NULL
);
342 ui_repdist_update_daterange(data
->window
, NULL
);
346 if(ui_flt_manage_dialog_new(GTK_WINDOW(data
->window
), data
->filter
, TRUE
, FALSE
) != GTK_RESPONSE_REJECT
)
348 ui_repdist_update_date_widget(data
->window
, NULL
);
349 ui_repdist_compute(data
->window
, NULL
);
350 ui_repdist_update_daterange(data
->window
, NULL
);
356 static void ui_repdist_update(GtkWidget
*widget
, gpointer user_data
)
358 struct ui_repdist_data
*data
;
361 gint page
, tmpsrc
, tmptype
, column
;
365 DB( g_print("\n[repdist] update\n") );
367 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
370 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
));
371 byamount
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_byamount
));
372 tmptype
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_type
));
373 //tmpsrc = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_src));
374 tmpsrc
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_src
));
377 DB( g_print(" option: byamount=%d tmptype=%d '%s' tmpsrc=%d '%s'\n\n", byamount
, tmptype
, hbtk_get_label(CYA_REPORT_TYPE
,tmptype
), tmpsrc
, hbtk_get_label(CYA_REPORT_SRC
,tmpsrc
)) );
379 // ensure not exp & inc for piechart
380 page
= gtk_notebook_get_current_page(GTK_NOTEBOOK(data
->GR_result
));
382 if( page
== 2 && tmptype
== REPORT_TYPE_ALL
)
384 g_signal_handler_block(data
->CY_type
, data
->handler_id
[HID_REPDIST_VIEW
]);
385 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data
->CY_type
), 1);
386 g_signal_handler_unblock(data
->CY_type
, data
->handler_id
[HID_REPDIST_VIEW
]);
387 tmptype
= REPORT_TYPE_EXPENSE
;
390 // define view/sort column
391 column
= LST_REPDIST_POS
;
397 case REPORT_TYPE_ALL
: //Inc & Exp
398 case REPORT_TYPE_BALANCE
:
399 column
= LST_REPDIST_BALANCE
;
401 case REPORT_TYPE_EXPENSE
:
402 column
= LST_REPDIST_EXPENSE
;
404 case REPORT_TYPE_INCOME
:
405 column
= LST_REPDIST_INCOME
;
410 DB( g_print(" sort on column %d\n\n", column
) );
412 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model
), column
, GTK_SORT_DESCENDING
);
414 gtk_chart_set_color_scheme(GTK_CHART(data
->RE_chart
), PREFS
->report_color_scheme
);
416 //TRANSLATORS: example 'Expense by Category'
417 title
= g_strdup_printf(_("%s by %s"), hbtk_get_label(CYA_REPORT_TYPE
,tmptype
), hbtk_get_label(CYA_REPORT_SRC
, tmpsrc
) );
419 /* update absolute or not */
420 gboolean abs
= (tmptype
== REPORT_TYPE_EXPENSE
|| tmptype
== REPORT_TYPE_INCOME
) ? TRUE
: FALSE
;
421 gtk_chart_set_absolute(GTK_CHART(data
->RE_chart
), abs
);
423 /* show xval for month/year and no by amount display */
426 if( !byamount
&& (tmpsrc
== REPORT_SRC_MONTH
|| tmpsrc
== REPORT_SRC_YEAR
) )
431 case REPORT_SRC_MONTH:
432 gtk_chart_set_every_xval(GTK_CHART(data->RE_chart), 4);
434 case REPORT_SRC_YEAR:
435 gtk_chart_set_every_xval(GTK_CHART(data->RE_chart), 2);
440 gtk_chart_show_xval(GTK_CHART(data
->RE_chart
), xval
);
443 /* update bar chart */
444 if( tmptype
== REPORT_TYPE_ALL
) //dual exp/inc
446 DB( g_print(" set bar to dual exp %d/inc %d\n\n", LST_REPDIST_EXPENSE
, LST_REPDIST_INCOME
) );
447 gtk_chart_set_dualdatas(GTK_CHART(data
->RE_chart
), model
, LST_REPDIST_EXPENSE
, LST_REPDIST_INCOME
, title
, NULL
);
451 // /!\ hazardous here
452 column
= LST_REPDIST_EXPENSE
+(tmptype
-1)*2;
453 DB( g_print(" set bar to %d\n\n", column
) );
454 gtk_chart_set_datas(GTK_CHART(data
->RE_chart
), model
, column
, title
, NULL
);
463 static void ui_repdist_update_date_widget(GtkWidget
*widget
, gpointer user_data
)
465 struct ui_repdist_data
*data
;
467 DB( g_print("\n[repdist] update date widget\n") );
469 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
471 g_signal_handler_block(data
->PO_mindate
, data
->handler_id
[HID_REPDIST_MINDATE
]);
472 g_signal_handler_block(data
->PO_maxdate
, data
->handler_id
[HID_REPDIST_MAXDATE
]);
474 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_mindate
), data
->filter
->mindate
);
475 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_maxdate
), data
->filter
->maxdate
);
477 g_signal_handler_unblock(data
->PO_mindate
, data
->handler_id
[HID_REPDIST_MINDATE
]);
478 g_signal_handler_unblock(data
->PO_maxdate
, data
->handler_id
[HID_REPDIST_MAXDATE
]);
483 static void ui_repdist_update_daterange(GtkWidget
*widget
, gpointer user_data
)
485 struct ui_repdist_data
*data
;
488 DB( g_print("\n[repdist] update daterange\n") );
490 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
492 daterange
= filter_daterange_text_get(data
->filter
);
493 gtk_label_set_markup(GTK_LABEL(data
->TX_daterange
), daterange
);
497 static void ui_repdist_update_total(GtkWidget
*widget
, gpointer user_data
)
499 struct ui_repdist_data
*data
;
502 DB( g_print("\n[repdist] update total\n") );
504 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
506 //minor = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_minor));
508 hb_label_set_colvalue(GTK_LABEL(data
->TX_total
[0]), data
->total_expense
, GLOBALS
->kcur
, GLOBALS
->minor
);
509 hb_label_set_colvalue(GTK_LABEL(data
->TX_total
[1]), data
->total_income
, GLOBALS
->kcur
, GLOBALS
->minor
);
510 hb_label_set_colvalue(GTK_LABEL(data
->TX_total
[2]), data
->total_expense
+ data
->total_income
, GLOBALS
->kcur
, GLOBALS
->minor
);
516 static void ui_repdist_export_result_clipboard(GtkWidget
*widget
, gpointer user_data
)
518 struct ui_repdist_data
*data
;
519 GtkClipboard
*clipboard
;
522 DB( g_print("\n[repdist] export result clipboard\n") );
525 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
527 node
= ui_list_repdist_to_string(GTK_TREE_VIEW(data
->LV_report
), TRUE
);
529 clipboard
= gtk_clipboard_get_default(gdk_display_get_default());
530 gtk_clipboard_set_text(clipboard
, node
->str
, node
->len
);
532 g_string_free(node
, TRUE
);
536 static void ui_repdist_export_result_csv(GtkWidget
*widget
, gpointer user_data
)
538 struct ui_repdist_data
*data
;
539 gchar
*filename
= NULL
;
545 DB( g_print("\n[repdist] export result csv\n") );
548 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
550 //tmpsrc = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_src));
551 tmpsrc
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_src
));
553 name
= g_strdup_printf("hb-repstat_%s.csv", hbtk_get_label(CYA_REPORT_SRC
,tmpsrc
));
555 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_SAVE
, &filename
, name
) == TRUE
)
557 DB( g_print(" + filename is %s\n", filename
) );
558 io
= g_io_channel_new_file(filename
, "w", NULL
);
561 node
= ui_list_repdist_to_string(GTK_TREE_VIEW(data
->LV_report
), FALSE
);
562 g_io_channel_write_chars(io
, node
->str
, -1, NULL
, NULL
);
563 g_io_channel_unref (io
);
564 g_string_free(node
, TRUE
);
572 static void ui_repdist_export_detail_clipboard(GtkWidget
*widget
, gpointer user_data
)
574 struct ui_repdist_data
*data
;
575 GtkClipboard
*clipboard
;
578 DB( g_print("\n[repdist] export detail clipboard\n") );
581 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
583 node
= list_txn_to_string(GTK_TREE_VIEW(data
->LV_detail
), TRUE
);
585 clipboard
= gtk_clipboard_get_default(gdk_display_get_default());
586 gtk_clipboard_set_text(clipboard
, node
->str
, node
->len
);
588 g_string_free(node
, TRUE
);
592 static void ui_repdist_export_detail_csv(GtkWidget
*widget
, gpointer user_data
)
594 struct ui_repdist_data
*data
;
595 gchar
*filename
= NULL
;
601 DB( g_print("\n[repdist] export detail csv\n") );
604 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
606 //tmpsrc = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_src));
607 tmpsrc
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_src
));
608 name
= g_strdup_printf("hb-repstat-detail_%s.csv", hbtk_get_label(CYA_REPORT_SRC
,tmpsrc
));
610 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_SAVE
, &filename
, name
) == TRUE
)
612 DB( g_print(" + filename is %s\n", filename
) );
614 io
= g_io_channel_new_file(filename
, "w", NULL
);
617 node
= list_txn_to_string(GTK_TREE_VIEW(data
->LV_detail
), FALSE
);
618 g_io_channel_write_chars(io
, node
->str
, -1, NULL
, NULL
);
620 g_io_channel_unref (io
);
621 g_string_free(node
, TRUE
);
631 static void ui_repdist_detail(GtkWidget
*widget
, gpointer user_data
)
633 struct ui_repdist_data
*data
;
634 guint active
= GPOINTER_TO_INT(user_data
);
640 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
642 DB( g_print("\n[repdist] detail\n") );
644 /* clear and detach our model */
645 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_detail
));
646 gtk_list_store_clear (GTK_LIST_STORE(model
));
650 //tmpsrc = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_src));
651 tmpsrc
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_src
));
653 g_object_ref(model
); /* Make sure the model stays with us after the tree view unrefs it */
654 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_detail
), NULL
); /* Detach model from view */
656 /* fill in the model */
657 list
= g_queue_peek_head_link(data
->txn_queue
);
660 Transaction
*ope
= list
->data
;
661 gdouble dtlamt
= ope
->amount
;
663 if(filter_txn_match(data
->filter
, ope
) == 1)
665 gboolean match
= FALSE
;
668 if( tmpsrc
!= REPORT_SRC_TAG
)
670 if( (tmpsrc
== REPORT_SRC_CATEGORY
|| tmpsrc
== REPORT_SRC_SUBCATEGORY
) && ope
->flags
& OF_SPLIT
)
672 guint nbsplit
= da_splits_length(ope
->splits
);
676 for(i
=0;i
<nbsplit
;i
++)
678 split
= da_splits_get(ope
->splits
, i
);
679 pos
= category_report_id(split
->kcat
, (tmpsrc
== REPORT_SRC_SUBCATEGORY
) ? TRUE
: FALSE
);
683 dtlamt
+= split
->amount
;
684 // no more break here as we need to compute split 4 cat
691 pos
= report_items_get_pos(tmpsrc
, data
->filter
->mindate
, ope
);
699 /* the TAG process is particular */
701 if(ope
->tags
!= NULL
)
703 guint32
*tptr
= ope
->tags
;
709 DB( g_print(" -> storing tag %d %.2f\n", pos
, ope
->amount
) );
723 gtk_list_store_insert_with_values (GTK_LIST_STORE(model
), &iter
, -1,
724 MODEL_TXN_POINTER
, ope
,
725 MODEL_TXN_SPLITAMT
, dtlamt
,
730 list
= g_list_next(list
);
733 /* Re-attach model to view */
734 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_detail
), model
);
735 g_object_unref(model
);
737 gtk_tree_view_columns_autosize( GTK_TREE_VIEW(data
->LV_detail
) );
744 static void ui_repdist_compute(GtkWidget
*widget
, gpointer user_data
)
746 struct ui_repdist_data
*data
;
747 gint tmpsrc
, tmptype
;
751 GList
*list
, *tmplist
= NULL
;
752 guint n_result
, sortid
;
754 gdouble
*tmp_income
, *tmp_expense
;
755 gdouble exprate
, incrate
, balrate
;
757 DB( g_print("\n[repdist] compute\n") );
759 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
761 //tmpsrc = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_src));
762 tmpsrc
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_src
));
763 tmptype
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_type
));
766 DB( g_print(" for=%d,type=%d\n", tmpsrc
, tmptype
) );
768 //get our min max date
769 from
= data
->filter
->mindate
;
770 to
= data
->filter
->maxdate
;
771 if(to
< from
) return;
774 g_queue_free (data
->txn_queue
);
775 data
->txn_queue
= hbfile_transaction_get_partial(data
->filter
->mindate
, data
->filter
->maxdate
);
777 DB( g_print(" nb-txn=%d\n", g_queue_get_length (data
->txn_queue
) ) );
779 //todo: remove this later on
780 n_result
= report_items_count(tmpsrc
, data
->filter
->mindate
, data
->filter
->maxdate
);
784 case REPORT_SRC_CATEGORY
:
785 case REPORT_SRC_SUBCATEGORY
:
786 tmplist
= category_glist_sorted(1);
788 case REPORT_SRC_PAYEE
:
789 tmplist
= payee_glist_sorted(1);
791 case REPORT_SRC_ACCOUNT
:
792 tmplist
= account_glist_sorted(1);
795 tmplist
= tag_glist_sorted(1);
799 DB( g_print(" %s :: n_result=%d\n", hbtk_get_label(CYA_REPORT_SRC
,tmpsrc
), n_result
) );
801 /* allocate some memory */
802 tmp_expense
= g_malloc0((n_result
+2) * sizeof(gdouble
));
803 tmp_income
= g_malloc0((n_result
+2) * sizeof(gdouble
));
805 data
->total_expense
= 0.0;
806 data
->total_income
= 0.0;
808 if(tmp_expense
&& tmp_income
)
811 DB( g_print(" - ok memory\n") );
813 /* compute the results */
814 list
= g_queue_peek_head_link(data
->txn_queue
);
817 Transaction
*ope
= list
->data
;
819 DB( g_print("** testing '%s', cat=%d==> %d\n", ope
->memo
, ope
->kcat
, filter_txn_match(data
->filter
, ope
)) );
821 if( (filter_txn_match(data
->filter
, ope
) == 1) )
826 DB( g_print(" - should insert\n") );
828 //trn_amount = ope->amount;
829 trn_amount
= hb_amount_base(ope
->amount
, ope
->kcur
);
831 //#1562372 in case of a split we need to take amount for filter categories only
832 if( ope
->flags
& OF_SPLIT
)
834 guint nbsplit
= da_splits_length(ope
->splits
);
841 for(i
=0;i
<nbsplit
;i
++)
843 split
= da_splits_get(ope
->splits
, i
);
844 catentry
= da_cat_get(split
->kcat
);
845 if(catentry
== NULL
) continue;
846 sinsert
= ( catentry
->flt_select
== TRUE
) ? 1 : 0;
847 if(data
->filter
->option
[FILTER_CATEGORY
] == 2) sinsert
^= 1;
849 DB( g_print(" split '%s' insert=%d\n",catentry
->name
, sinsert
) );
851 if( (data
->filter
->option
[FILTER_CATEGORY
] == 0) || sinsert
)
853 trn_amount
+= hb_amount_base(split
->amount
, ope
->kcur
);
860 if( tmpsrc
!= REPORT_SRC_TAG
)
862 if( (tmpsrc
== REPORT_SRC_CATEGORY
|| tmpsrc
== REPORT_SRC_SUBCATEGORY
) && ope
->flags
& OF_SPLIT
)
864 guint nbsplit
= da_splits_length(ope
->splits
);
869 for(i
=0;i
<nbsplit
;i
++)
871 split
= da_splits_get(ope
->splits
, i
);
872 catentry
= da_cat_get(split
->kcat
);
873 if(catentry
== NULL
) continue;
874 sinsert
= ( catentry
->flt_select
== TRUE
) ? 1 : 0;
875 if(data
->filter
->option
[FILTER_CATEGORY
] == 2) sinsert
^= 1;
877 DB( g_print(" split '%s' insert=%d\n",catentry
->name
, sinsert
) );
879 if( (data
->filter
->option
[FILTER_CATEGORY
] == 0) || sinsert
)
883 case REPORT_SRC_CATEGORY
:
885 pos
= (catentry
->flags
& GF_SUB
) ? catentry
->parent
: catentry
->key
;
888 case REPORT_SRC_SUBCATEGORY
:
893 trn_amount
= hb_amount_base(split
->amount
, ope
->kcur
);
894 //trn_amount = split->amount;
898 tmp_income
[pos
] += trn_amount
;
899 data
->total_income
+= trn_amount
;
903 tmp_expense
[pos
] += trn_amount
;
904 data
->total_expense
+= trn_amount
;
914 pos
= report_items_get_pos(tmpsrc
, from
, ope
);
917 tmp_income
[pos
] += trn_amount
;
918 data
->total_income
+= trn_amount
;
922 tmp_expense
[pos
] += trn_amount
;
923 data
->total_expense
+= trn_amount
;
928 /* the TAG process is particularly */
930 if(ope
->tags
!= NULL
)
932 guint32
*tptr
= ope
->tags
;
938 DB( g_print(" -> storing tag %d %s %.2f\n", pos
, da_tag_get(*tptr
)->name
, trn_amount
) );
942 tmp_income
[pos
] += trn_amount
;
943 data
->total_income
+= trn_amount
;
947 tmp_expense
[pos
] += trn_amount
;
948 data
->total_expense
+= trn_amount
;
955 // fix total according to selection
956 //if(tmpkind==0 && !tmp_expense[pos]) { data->total_income -= ope->amount; }
957 //if(tmpkind==1 && !tmp_income[pos] ) { data->total_expense -= ope->amount; }
962 list
= g_list_next(list
);
965 /* clear and detach our model */
966 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
));
967 gtk_list_store_clear (GTK_LIST_STORE(model
));
968 g_object_ref(model
); /* Make sure the model stays with us after the tree view unrefs it */
969 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_report
), NULL
); /* Detach model from view */
971 /* insert into the treeview */
972 for(i
=0, sortid
=0; i
<n_result
; i
++)
974 gchar
*name
, *fullcatname
;
981 DB( g_print("try to insert item %d - %.2f %.2f\n", i
, tmp_expense
[i
], tmp_income
[i
]) );
984 /* filter empty results */
985 // 1829630 crash _cairo_arc_in_direction (account was missing here)
987 if( !(tmpsrc
== REPORT_SRC_MONTH
|| tmpsrc
== REPORT_SRC_YEAR
) )
989 if( tmptype
== 1 && !tmp_expense
[i
] ) continue;
990 if( tmptype
== 2 && !tmp_income
[i
] ) continue;
991 if( !tmp_expense
[i
] && !tmp_income
[i
] ) continue;
994 /* get the result name */
997 case REPORT_SRC_CATEGORY
:
999 Category
*entry
= da_cat_get(i
);
1002 name
= entry
->key
== 0 ? _("(no category)") : entry
->name
;
1004 sortid
= g_list_index(tmplist
, entry
);
1009 case REPORT_SRC_SUBCATEGORY
:
1011 Category
*entry
= da_cat_get(i
);
1014 if(entry
->flags
& GF_SUB
)
1016 Category
*parent
= da_cat_get(entry
->parent
);
1018 fullcatname
= g_strdup_printf("%s : %s", parent
->name
, entry
->name
);
1022 name
= entry
->key
== 0 ? _("(no category)") : entry
->name
;
1024 sortid
= g_list_index(tmplist
, entry
);
1029 case REPORT_SRC_PAYEE
:
1031 Payee
*entry
= da_pay_get(i
);
1034 name
= entry
->key
== 0 ? _("(no payee)") : entry
->name
;
1035 sortid
= g_list_index(tmplist
, entry
);
1040 case REPORT_SRC_ACCOUNT
:
1042 Account
*entry
= da_acc_get(i
);
1046 sortid
= g_list_index(tmplist
, entry
);
1051 case REPORT_SRC_TAG
:
1053 Tag
*entry
= da_tag_get(i
+1);
1055 sortid
= g_list_index(tmplist
, entry
);
1059 case REPORT_SRC_MONTH
:
1060 date
= g_date_new_julian(from
);
1061 g_date_add_months(date
, i
);
1062 //g_snprintf(buffer, 63, "%d-%02d", g_date_get_year(date), g_date_get_month(date));
1063 g_snprintf(buffer
, 63, "%d-%s", g_date_get_year(date
), _(CYA_ABMONTHS
[g_date_get_month(date
)]));
1068 case REPORT_SRC_YEAR
:
1069 date
= g_date_new_julian(from
);
1070 g_date_add_years(date
, i
);
1071 g_snprintf(buffer
, 63, "%d", g_date_get_year(date
));
1077 DB( g_print(" inserting %2d, '%s', %9.2f %9.2f %9.2f\n", i
, name
, tmp_expense
[i
], tmp_income
[i
], tmp_expense
[i
] + tmp_income
[i
]) );
1084 if( data
->total_expense
)
1085 exprate
= ABS((tmp_expense
[i
] * 100 / data
->total_expense
));
1087 if( data
->total_income
)
1088 incrate
= (tmp_income
[i
] * 100 / data
->total_income
);
1090 data
->total_balance
= ABS(data
->total_expense
) + data
->total_income
;
1091 if( data
->total_balance
)
1092 balrate
= (ABS(tmp_expense
[i
]) + tmp_income
[i
]) * 100 / data
->total_balance
;
1094 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
1095 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
1096 LST_REPDIST_POS
, sortid
++,
1098 LST_REPDIST_NAME
, name
,
1099 LST_REPDIST_EXPENSE
, tmp_expense
[i
],
1100 LST_REPDIST_INCOME
, tmp_income
[i
],
1101 LST_REPDIST_BALANCE
, tmp_expense
[i
] + tmp_income
[i
],
1102 LST_REPDIST_EXPRATE
, exprate
,
1103 LST_REPDIST_INCRATE
, incrate
,
1104 LST_REPDIST_BALRATE
, balrate
,
1107 g_free(fullcatname
);
1110 /* update column 0 title */
1111 GtkTreeViewColumn
*column
= gtk_tree_view_get_column( GTK_TREE_VIEW(data
->LV_report
), 0);
1112 gtk_tree_view_column_set_title(column
, hbtk_get_label(CYA_REPORT_SRC
,tmpsrc
));
1114 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_report
));
1116 /* Re-attach model to view */
1117 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_report
), model
);
1118 g_object_unref(model
);
1121 /* free our memory */
1122 g_free(tmp_expense
);
1125 /* free tmplist (sort cat/pay) */
1126 g_list_free(tmplist
);
1128 ui_repdist_update_total(widget
,NULL
);
1130 ui_repdist_update(widget
, user_data
);
1136 ** update sensitivity
1138 static void ui_repdist_sensitive(GtkWidget
*widget
, gpointer user_data
)
1140 struct ui_repdist_data
*data
;
1142 gboolean visible
, sensitive
;
1145 DB( g_print("\n[repdist] sensitive\n") );
1147 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1149 page
= gtk_notebook_get_current_page(GTK_NOTEBOOK(data
->GR_result
));
1151 visible
= page
== 0 ? TRUE
: FALSE
;
1152 action
= gtk_ui_manager_get_action(data
->ui
, "/ToolBar/Detail");
1153 gtk_action_set_visible (action
, visible
);
1154 //sensitive = gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_report)), NULL, NULL);
1155 //gtk_action_set_sensitive(action, sensitive);
1156 //action = gtk_ui_manager_get_action(data->ui, "/ToolBar/Export");
1157 //gtk_action_set_visible (action, visible);
1158 hb_widget_visible (data
->BT_export
, visible
);
1161 visible
= page
== 0 ? FALSE
: TRUE
;
1162 //todo: don't display for pie chart (get the type form chart)
1164 hb_widget_visible(data
->LB_zoomx
, visible
);
1165 hb_widget_visible(data
->RG_zoomx
, visible
);
1167 visible
= page
== 0 ? FALSE
: TRUE
;
1168 gtk_action_set_visible(gtk_ui_manager_get_action(data
->ui
, "/ToolBar/Legend"), visible
);
1170 visible
= page
== 0 ? TRUE
: FALSE
;
1171 gtk_action_set_visible(gtk_ui_manager_get_action(data
->ui
, "/ToolBar/Rate"), visible
);
1173 sensitive
= gtk_tree_model_iter_n_children(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_detail
)), NULL
) > 0 ? TRUE
: FALSE
;
1174 gtk_widget_set_sensitive(data
->MI_detailtoclip
, sensitive
);
1175 gtk_widget_set_sensitive(data
->MI_detailtocsv
, sensitive
);
1179 static void ui_repdist_detail_onRowActivated (GtkTreeView
*treeview
,
1181 GtkTreeViewColumn
*col
,
1184 struct ui_repdist_data
*data
;
1185 Transaction
*active_txn
;
1188 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview
), GTK_TYPE_WINDOW
)), "inst_data");
1190 DB( g_print ("\n[repdist] A detail row has been double-clicked!\n") );
1192 active_txn
= list_txn_get_active_transaction(GTK_TREE_VIEW(data
->LV_detail
));
1195 Transaction
*old_txn
, *new_txn
;
1197 old_txn
= da_transaction_clone (active_txn
);
1198 new_txn
= active_txn
;
1199 result
= deftransaction_external_edit(GTK_WINDOW(data
->window
), old_txn
, new_txn
);
1201 if(result
== GTK_RESPONSE_ACCEPT
)
1204 GLOBALS
->changes_count
++;
1205 ui_repdist_compute(data
->window
, NULL
);
1208 da_transaction_free (old_txn
);
1213 static void ui_repdist_update_detail(GtkWidget
*widget
, gpointer user_data
)
1215 struct ui_repdist_data
*data
;
1217 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1219 if(GTK_IS_TREE_VIEW(data
->LV_report
))
1223 GtkTreeSelection
*treeselection
;
1224 GtkTreeModel
*model
;
1228 treeselection
= gtk_tree_view_get_selection (GTK_TREE_VIEW(data
->LV_report
));
1230 if (gtk_tree_selection_get_selected(treeselection
, &model
, &iter
))
1232 gtk_tree_model_get(model
, &iter
, LST_REPDIST_KEY
, &key
, -1);
1234 DB( g_print(" - active is %d\n", key
) );
1236 ui_repdist_detail(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), GINT_TO_POINTER(key
));
1241 gtk_widget_show(data
->GR_detail
);
1244 gtk_widget_hide(data
->GR_detail
);
1252 static void ui_repdist_toggle_detail(GtkWidget
*widget
, gpointer user_data
)
1254 struct ui_repdist_data
*data
;
1256 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1260 DB( g_print("\n[repdist] toggledetail to %d\n", data
->detail
) );
1262 ui_repdist_update_detail(widget
, user_data
);
1267 ** change the chart legend visibility
1269 static void ui_repdist_toggle_legend(GtkWidget
*widget
, gpointer user_data
)
1271 struct ui_repdist_data
*data
;
1274 DB( g_print("\n[repdist] toggle legend\n") );
1276 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1280 gtk_chart_show_legend(GTK_CHART(data
->RE_chart
), data
->legend
, FALSE
);
1284 static void ui_repdist_zoomx_callback(GtkWidget
*widget
, gpointer user_data
)
1286 struct ui_repdist_data
*data
;
1289 DB( g_print("\n[repdist] zoomx\n") );
1291 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1293 value
= gtk_range_get_value(GTK_RANGE(data
->RG_zoomx
));
1295 DB( g_print(" + scale is %.2f\n", value
) );
1297 gtk_chart_set_barw(GTK_CHART(data
->RE_chart
), value
);
1303 ** change the chart rate columns visibility
1305 static void ui_repdist_toggle_rate(GtkWidget
*widget
, gpointer user_data
)
1307 struct ui_repdist_data
*data
;
1308 GtkTreeViewColumn
*column
;
1310 DB( g_print("\n[repdist] toggle rate\n") );
1312 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1316 if(GTK_IS_TREE_VIEW(data
->LV_report
))
1319 column
= gtk_tree_view_get_column (GTK_TREE_VIEW(data
->LV_report
), 2);
1320 gtk_tree_view_column_set_visible(column
, data
->rate
);
1322 column
= gtk_tree_view_get_column (GTK_TREE_VIEW(data
->LV_report
), 4);
1323 gtk_tree_view_column_set_visible(column
, data
->rate
);
1325 column
= gtk_tree_view_get_column (GTK_TREE_VIEW(data
->LV_report
), 6);
1326 gtk_tree_view_column_set_visible(column
, data
->rate
);
1331 static void ui_repdist_toggle_minor(GtkWidget
*widget
, gpointer user_data
)
1333 struct ui_repdist_data
*data
;
1335 DB( g_print("\n[repdist] toggle minor\n") );
1337 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1339 GLOBALS
->minor
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_minor
));
1341 ui_repdist_update_total(widget
,NULL
);
1343 //hbfile_update(data->LV_acc, (gpointer)4);
1344 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_report
));
1345 gtk_chart_show_minor(GTK_CHART(data
->RE_chart
), GLOBALS
->minor
);
1353 static void ui_repdist_setup(struct ui_repdist_data
*data
)
1355 DB( g_print("\n[repdist] setup\n") );
1357 data
->txn_queue
= g_queue_new ();
1359 data
->filter
= da_flt_malloc();
1360 filter_reset(data
->filter
);
1363 data
->detail
= PREFS
->stat_showdetail
;
1365 data
->rate
= PREFS
->stat_showrate
^1;
1368 ui_repdist_toggle_rate(data
->window
, NULL
);
1372 /* 3.4 : make int transfer out of stats */
1373 data
->filter
->option
[FILTER_PAYMODE
] = 1;
1374 data
->filter
->paymode
[PAYMODE_INTXFER
] = FALSE
;
1376 filter_preset_daterange_set(data
->filter
, PREFS
->date_range_rep
, 0);
1378 ui_repdist_update_date_widget(data
->window
, NULL
);
1384 static void ui_repdist_selection(GtkTreeSelection
*treeselection
, gpointer user_data
)
1386 GtkTreeModel
*model
;
1390 DB( g_print("\n[repdist] selection\n") );
1392 if (gtk_tree_selection_get_selected(treeselection
, &model
, &iter
))
1394 gtk_tree_model_get(model
, &iter
, LST_REPDIST_KEY
, &key
, -1);
1397 DB( g_print(" - active is %d\n", key
) );
1399 ui_repdist_detail(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), GINT_TO_POINTER(key
));
1400 ui_repdist_sensitive(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), NULL
);
1407 static gboolean
ui_repdist_dispose(GtkWidget
*widget
, GdkEvent
*event
, gpointer user_data
)
1409 struct ui_repdist_data
*data
= user_data
;
1410 struct WinGeometry
*wg
;
1412 DB( g_print("\n[repdist] dispose\n") );
1414 g_queue_free (data
->txn_queue
);
1416 da_flt_free(data
->filter
);
1420 //store position and size
1421 wg
= &PREFS
->sta_wg
;
1422 gtk_window_get_position(GTK_WINDOW(widget
), &wg
->l
, &wg
->t
);
1423 gtk_window_get_size(GTK_WINDOW(widget
), &wg
->w
, &wg
->h
);
1425 DB( g_print(" window: l=%d, t=%d, w=%d, h=%d\n", wg
->l
, wg
->t
, wg
->w
, wg
->h
) );
1429 //enable define windows
1430 GLOBALS
->define_off
--;
1431 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
));
1437 // the window creation
1438 GtkWidget
*ui_repdist_window_new(void)
1440 struct ui_repdist_data
*data
;
1441 struct WinGeometry
*wg
;
1442 GtkWidget
*window
, *mainvbox
, *hbox
, *vbox
, *notebook
, *treeview
, *vpaned
, *sw
;
1443 GtkWidget
*label
, *widget
, *table
, *entry
;
1446 GtkActionGroup
*actions
;
1448 GError
*error
= NULL
;
1450 DB( g_print("\n[repdist] new\n") );
1453 data
= g_malloc0(sizeof(struct ui_repdist_data
));
1454 if(!data
) return NULL
;
1456 //disable define windows
1457 GLOBALS
->define_off
++;
1458 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
));
1460 /* create window, etc */
1461 window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
1462 data
->window
= window
;
1464 //store our window private data
1465 g_object_set_data(G_OBJECT(window
), "inst_data", (gpointer
)data
);
1466 DB( g_print(" - new window=%p, inst_data=%p\n", window
, data
) );
1468 gtk_window_set_title (GTK_WINDOW (window
), _("Statistics Report"));
1469 gtk_window_set_icon_name(GTK_WINDOW (window
), ICONNAME_HB_REP_STATS
);
1473 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
1474 gtk_container_add (GTK_CONTAINER (window
), mainvbox
);
1476 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
1477 gtk_box_pack_start (GTK_BOX (mainvbox
), hbox
, TRUE
, TRUE
, 0);
1480 table
= gtk_grid_new ();
1481 gtk_widget_set_hexpand (GTK_WIDGET(table
), FALSE
);
1482 gtk_box_pack_start (GTK_BOX (hbox
), table
, FALSE
, FALSE
, 0);
1484 gtk_container_set_border_width (GTK_CONTAINER (table
), SPACING_SMALL
);
1485 gtk_grid_set_row_spacing (GTK_GRID (table
), SPACING_SMALL
);
1486 gtk_grid_set_column_spacing (GTK_GRID (table
), SPACING_MEDIUM
);
1489 label
= make_label_group(_("Display"));
1490 gtk_grid_attach (GTK_GRID (table
), label
, 0, row
, 3, 1);
1493 label
= make_label_widget(_("_View by:"));
1494 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1495 //widget = make_cycle(label, CYA_REPORT_SRC);
1496 widget
= hbtk_combo_box_new_with_data(label
, CYA_REPORT_SRC
);
1497 data
->CY_src
= widget
;
1498 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1501 label
= make_label_widget(_("_Type:"));
1502 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1503 //widget = make_cycle(label, CYA_REPORT_TXN_TYPE);
1504 widget
= hbtk_combo_box_new_with_data(label
, CYA_REPORT_TYPE
);
1505 data
->CY_type
= widget
;
1506 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1510 widget
= gtk_check_button_new_with_mnemonic (_("By _amount"));
1511 data
->CM_byamount
= widget
;
1512 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1515 widget
= gtk_check_button_new_with_mnemonic (_("Euro _minor"));
1516 data
->CM_minor
= widget
;
1517 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1521 label
= make_label_widget(_("_Zoom X:"));
1522 data
->LB_zoomx
= label
;
1523 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1524 widget
= make_scale(label
);
1525 data
->RG_zoomx
= widget
;
1526 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1530 widget = gtk_check_button_new_with_mnemonic ("Legend");
1531 data->CM_legend = widget;
1532 gtk_grid_attach (GTK_GRID (table), widget, 1, 2, row, row+1);
1535 widget
= gtk_separator_new(GTK_ORIENTATION_HORIZONTAL
);
1536 gtk_grid_attach (GTK_GRID (table
), widget
, 0, row
, 3, 1);
1539 label
= make_label_group(_("Date filter"));
1540 gtk_grid_attach (GTK_GRID (table
), label
, 0, row
, 3, 1);
1543 label
= make_label_widget(_("_Range:"));
1544 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1545 data
->CY_range
= make_daterange(label
, DATE_RANGE_CUSTOM_DISABLE
);
1546 gtk_grid_attach (GTK_GRID (table
), data
->CY_range
, 2, row
, 1, 1);
1549 label
= make_label_widget(_("_From:"));
1550 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1551 data
->PO_mindate
= gtk_date_entry_new();
1552 gtk_grid_attach (GTK_GRID (table
), data
->PO_mindate
, 2, row
, 1, 1);
1555 label
= make_label_widget(_("_To:"));
1556 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1557 data
->PO_maxdate
= gtk_date_entry_new();
1558 gtk_grid_attach (GTK_GRID (table
), data
->PO_maxdate
, 2, row
, 1, 1);
1560 //part: info + report
1561 vbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
1562 gtk_box_pack_start (GTK_BOX (hbox
), vbox
, TRUE
, TRUE
, 0);
1565 actions
= gtk_action_group_new ("default");
1568 gtk_action_group_set_translation_domain(actions
, GETTEXT_PACKAGE
);
1570 // data to action callbacks is set here (data)
1571 gtk_action_group_add_radio_actions (actions
, radio_entries
, n_radio_entries
, 0, G_CALLBACK(ui_repdist_action_mode
), data
);
1573 gtk_action_group_add_actions (actions
, entries
, n_entries
, data
);
1575 gtk_action_group_add_toggle_actions (actions
,
1576 toggle_entries
, n_toggle_entries
,
1580 /* set which action should have priority in the toolbar */
1581 //action = gtk_action_group_get_action(actions, "List");
1582 //g_object_set(action, "is_important", TRUE, NULL);
1584 //action = gtk_action_group_get_action(actions, "Column");
1585 //g_object_set(action, "is_important", TRUE, NULL);
1587 //action = gtk_action_group_get_action(actions, "Donut");
1588 //g_object_set(action, "is_important", TRUE, NULL);
1590 action
= gtk_action_group_get_action(actions
, "Detail");
1591 //g_object_set(action, "is_important", TRUE, NULL);
1592 g_object_set(action
, "active", PREFS
->stat_showdetail
, NULL
);
1594 action
= gtk_action_group_get_action(actions
, "Rate");
1595 g_object_set(action
, "active", PREFS
->stat_showrate
, NULL
);
1597 //action = gtk_action_group_get_action(actions, "Filter");
1598 //g_object_set(action, "is_important", TRUE, NULL);
1600 //action = gtk_action_group_get_action(actions, "Refresh");
1601 //g_object_set(action, "is_important", TRUE, NULL);
1604 ui
= gtk_ui_manager_new ();
1605 gtk_ui_manager_insert_action_group (ui
, actions
, 0);
1606 gtk_window_add_accel_group (GTK_WINDOW (window
), gtk_ui_manager_get_accel_group (ui
));
1608 if (!gtk_ui_manager_add_ui_from_string (ui
, ui_info
, -1, &error
))
1610 g_message ("building UI failed: %s", error
->message
);
1611 g_error_free (error
);
1615 data
->actions
= actions
;
1618 data
->TB_bar
= gtk_ui_manager_get_widget (ui
, "/ToolBar");
1619 gtk_box_pack_start (GTK_BOX (vbox
), data
->TB_bar
, FALSE
, FALSE
, 0);
1621 //add export menu button
1622 GtkToolItem
*toolitem
;
1623 GtkWidget
*menu
, *menuitem
, *image
;
1625 menu
= gtk_menu_new ();
1626 //gtk_widget_set_halign (menu, GTK_ALIGN_END);
1628 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Result to clipboard"));
1629 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1630 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_repdist_export_result_clipboard
), data
);
1632 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Result to CSV"));
1633 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1634 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_repdist_export_result_csv
), data
);
1636 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Detail to clipboard"));
1637 data
->MI_detailtoclip
= menuitem
;
1638 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1639 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_repdist_export_detail_clipboard
), data
);
1641 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Detail to CSV"));
1642 data
->MI_detailtocsv
= menuitem
;
1643 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1644 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_repdist_export_detail_csv
), data
);
1646 gtk_widget_show_all (menu
);
1648 widget
= gtk_menu_button_new();
1649 data
->BT_export
= widget
;
1650 gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(widget
)), GTK_STYLE_CLASS_FLAT
);
1652 //gtk_menu_button_set_direction (GTK_MENU_BUTTON(widget), GTK_ARROW_DOWN);
1653 //gtk_widget_set_halign (widget, GTK_ALIGN_END);
1654 image
= gtk_image_new_from_icon_name (ICONNAME_HB_FILE_EXPORT
, GTK_ICON_SIZE_LARGE_TOOLBAR
);
1655 g_object_set (widget
, "image", image
, "popup", GTK_MENU(menu
), NULL
);
1657 toolitem
= gtk_tool_item_new();
1658 gtk_container_add (GTK_CONTAINER(toolitem
), widget
);
1659 gtk_toolbar_insert(GTK_TOOLBAR(data
->TB_bar
), GTK_TOOL_ITEM(toolitem
), -1);
1663 hbox
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, SPACING_SMALL
);
1664 gtk_container_set_border_width (GTK_CONTAINER(hbox
), SPACING_SMALL
);
1665 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
1667 widget
= make_label(NULL
, 0.5, 0.5);
1668 gimp_label_set_attributes (GTK_LABEL (widget
), PANGO_ATTR_SCALE
, PANGO_SCALE_SMALL
, -1);
1669 data
->TX_daterange
= widget
;
1670 gtk_box_pack_start (GTK_BOX (hbox
), widget
, TRUE
, TRUE
, 0);
1672 entry
= gtk_label_new(NULL
);
1673 data
->TX_total
[2] = entry
;
1674 gtk_box_pack_end (GTK_BOX (hbox
), entry
, FALSE
, FALSE
, 0);
1675 label
= gtk_label_new(_("Balance:"));
1676 gtk_box_pack_end (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
1678 entry
= gtk_label_new(NULL
);
1679 data
->TX_total
[1] = entry
;
1680 gtk_box_pack_end (GTK_BOX (hbox
), entry
, FALSE
, FALSE
, 0);
1681 label
= gtk_label_new(_("Income:"));
1682 gtk_box_pack_end (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
1685 entry
= gtk_label_new(NULL
);
1686 data
->TX_total
[0] = entry
;
1687 gtk_box_pack_end (GTK_BOX (hbox
), entry
, FALSE
, FALSE
, 0);
1688 label
= gtk_label_new(_("Expense:"));
1689 gtk_box_pack_end (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
1693 notebook
= gtk_notebook_new();
1694 data
->GR_result
= notebook
;
1695 gtk_widget_show(notebook
);
1696 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook
), FALSE
);
1697 gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook
), FALSE
);
1698 gtk_box_pack_start (GTK_BOX (vbox
), notebook
, TRUE
, TRUE
, 0);
1701 vpaned
= gtk_paned_new(GTK_ORIENTATION_VERTICAL
);
1702 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), vpaned
, NULL
);
1705 sw
= gtk_scrolled_window_new (NULL
, NULL
);
1706 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw
), GTK_SHADOW_ETCHED_IN
);
1707 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1708 treeview
= ui_list_repdist_create();
1709 data
->LV_report
= treeview
;
1710 gtk_container_add (GTK_CONTAINER(sw
), treeview
);
1711 gtk_paned_pack1 (GTK_PANED(vpaned
), sw
, TRUE
, TRUE
);
1714 sw
= gtk_scrolled_window_new (NULL
, NULL
);
1715 data
->GR_detail
= sw
;
1716 //gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW (sw), GTK_CORNER_TOP_RIGHT);
1717 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw
), GTK_SHADOW_ETCHED_IN
);
1718 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1719 treeview
= create_list_transaction(LIST_TXN_TYPE_DETAIL
, PREFS
->lst_ope_columns
);
1720 data
->LV_detail
= treeview
;
1721 gtk_container_add (GTK_CONTAINER(sw
), treeview
);
1722 gtk_paned_pack2 (GTK_PANED(vpaned
), sw
, TRUE
, TRUE
);
1725 widget
= gtk_chart_new(CHART_TYPE_COL
);
1726 data
->RE_chart
= widget
;
1727 gtk_chart_set_minor_prefs(GTK_CHART(widget
), PREFS
->euro_value
, PREFS
->minor_cur
.symbol
);
1728 gtk_chart_set_currency(GTK_CHART(widget
), GLOBALS
->kcur
);
1729 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), widget
, NULL
);
1731 //todo: setup should move this
1732 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_minor
), GLOBALS
->minor
);
1733 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_byamount
), PREFS
->stat_byamount
);
1735 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data
->CY_type
), REPORT_TYPE_EXPENSE
);
1737 /* attach our minor to treeview */
1738 g_object_set_data(G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
))), "minor", (gpointer
)data
->CM_minor
);
1739 g_object_set_data(G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_detail
))), "minor", (gpointer
)data
->CM_minor
);
1741 /* signal connect */
1742 g_signal_connect (window
, "delete-event", G_CALLBACK (ui_repdist_dispose
), (gpointer
)data
);
1744 g_signal_connect (data
->CM_minor
, "toggled", G_CALLBACK (ui_repdist_toggle_minor
), NULL
);
1746 data
->handler_id
[HID_REPDIST_MINDATE
] = g_signal_connect (data
->PO_mindate
, "changed", G_CALLBACK (ui_repdist_date_change
), (gpointer
)data
);
1747 data
->handler_id
[HID_REPDIST_MAXDATE
] = g_signal_connect (data
->PO_maxdate
, "changed", G_CALLBACK (ui_repdist_date_change
), (gpointer
)data
);
1749 data
->handler_id
[HID_REPDIST_RANGE
] = g_signal_connect (data
->CY_range
, "changed", G_CALLBACK (ui_repdist_range_change
), NULL
);
1751 g_signal_connect (data
->CY_src
, "changed", G_CALLBACK (ui_repdist_compute
), (gpointer
)data
);
1753 data
->handler_id
[HID_REPDIST_VIEW
] = g_signal_connect (data
->CY_type
, "changed", G_CALLBACK (ui_repdist_compute
), (gpointer
)data
);
1755 g_signal_connect (data
->RG_zoomx
, "value-changed", G_CALLBACK (ui_repdist_zoomx_callback
), NULL
);
1758 g_signal_connect (data
->CM_byamount
, "toggled", G_CALLBACK (ui_repdist_update
), NULL
);
1760 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_report
)), "changed", G_CALLBACK (ui_repdist_selection
), NULL
);
1762 g_signal_connect (GTK_TREE_VIEW(data
->LV_detail
), "row-activated", G_CALLBACK (ui_repdist_detail_onRowActivated
), NULL
);
1764 //setup, init and show window
1765 ui_repdist_setup(data
);
1768 if(PREFS
->toolbar_style
== 0)
1769 gtk_toolbar_unset_style(GTK_TOOLBAR(data
->TB_bar
));
1771 gtk_toolbar_set_style(GTK_TOOLBAR(data
->TB_bar
), PREFS
->toolbar_style
-1);
1774 //setup, init and show window
1775 wg
= &PREFS
->sta_wg
;
1776 gtk_window_move(GTK_WINDOW(window
), wg
->l
, wg
->t
);
1777 gtk_window_resize(GTK_WINDOW(window
), wg
->w
, wg
->h
);
1779 gtk_widget_show_all (window
);
1784 if( PREFS
->euro_active
)
1785 gtk_widget_show(data
->CM_minor
);
1787 gtk_widget_hide(data
->CM_minor
);
1789 //gtk_widget_hide(data->GR_detail);
1793 ui_repdist_sensitive(window
, NULL
);
1794 ui_repdist_update_detail(window
, NULL
);
1796 DB( g_print("range: %d\n", PREFS
->date_range_rep
) );
1798 if( PREFS
->date_range_rep
!= 0)
1799 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
), PREFS
->date_range_rep
);
1801 ui_repdist_compute(window
, NULL
);
1808 ** ============================================================================
1812 static GString
*ui_list_repdist_to_string(GtkTreeView
*treeview
, gboolean clipboard
)
1815 GtkTreeModel
*model
;
1818 const gchar
*format
;
1820 node
= g_string_new(NULL
);
1823 format
= (clipboard
== TRUE
) ? "%s\t%s\t%s\t%s\n" : "%s;%s;%s;%s\n";
1824 g_string_append_printf(node
, format
, _("Result"), _("Expense"), _("Income"), _("Balance"));
1826 model
= gtk_tree_view_get_model(treeview
);
1827 valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model
), &iter
);
1831 gdouble exp
, inc
, bal
;
1833 gtk_tree_model_get (model
, &iter
,
1834 //LST_REPDIST_KEY, i,
1835 LST_REPDIST_NAME
, &name
,
1836 LST_REPDIST_EXPENSE
, &exp
,
1837 LST_REPDIST_INCOME
, &inc
,
1838 LST_REPDIST_BALANCE
, &bal
,
1841 format
= (clipboard
== TRUE
) ? "%s\t%.2f\t%.2f\t%.2f\n" : "%s;%.2f;%.2f;%.2f\n";
1842 g_string_append_printf(node
, format
, name
, exp
, inc
, bal
);
1847 valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &iter
);
1850 //DB( g_print("text is:\n%s", node->str) );
1858 static void ui_list_repdist_rate_cell_data_function (GtkTreeViewColumn
*col
,
1859 GtkCellRenderer
*renderer
,
1860 GtkTreeModel
*model
,
1864 //GtkWidget *widget;
1866 //widget = g_object_get_data(G_OBJECT(model), "minor");
1868 //todo g_assert here and null test
1873 gtk_tree_model_get(model
, iter
, GPOINTER_TO_INT(user_data
), &tmp
, -1);
1877 g_snprintf(buf
, sizeof(buf
), "%.2f %%", tmp
);
1878 g_object_set(renderer
, "text", buf
, NULL
);
1881 g_object_set(renderer
, "text", "", NULL
);
1886 static void ui_list_repdist_amount_cell_data_function (GtkTreeViewColumn
*col
,
1887 GtkCellRenderer
*renderer
,
1888 GtkTreeModel
*model
,
1894 gchar buf
[G_ASCII_DTOSTR_BUF_SIZE
];
1896 gtk_tree_model_get(model
, iter
, GPOINTER_TO_INT(user_data
), &value
, -1);
1900 hb_strfmon(buf
, G_ASCII_DTOSTR_BUF_SIZE
-1, value
, GLOBALS
->kcur
, GLOBALS
->minor
);
1902 color
= get_normal_color_amount(value
);
1904 g_object_set(renderer
,
1905 "foreground", color
,
1910 g_object_set(renderer
, "text", "", NULL
);
1915 static GtkTreeViewColumn
*ui_list_repdist_amount_column(gchar
*name
, gint id
)
1917 GtkTreeViewColumn
*column
;
1918 GtkCellRenderer
*renderer
;
1920 column
= gtk_tree_view_column_new();
1921 gtk_tree_view_column_set_title(column
, name
);
1922 renderer
= gtk_cell_renderer_text_new ();
1923 g_object_set(renderer
, "xalign", 1.0, NULL
);
1924 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1925 gtk_tree_view_column_set_cell_data_func(column
, renderer
, ui_list_repdist_amount_cell_data_function
, GINT_TO_POINTER(id
), NULL
);
1926 gtk_tree_view_column_set_alignment (column
, 0.5);
1927 //gtk_tree_view_column_set_sort_column_id (column, id);
1931 static GtkTreeViewColumn
*ui_list_repdist_rate_column(gint id
)
1933 GtkTreeViewColumn
*column
;
1934 GtkCellRenderer
*renderer
;
1936 column
= gtk_tree_view_column_new();
1937 gtk_tree_view_column_set_title(column
, "%");
1938 renderer
= gtk_cell_renderer_text_new ();
1939 g_object_set(renderer
, "xalign", 1.0, "yalign", 1.0, "scale", 0.8, "scale-set", TRUE
, NULL
);
1941 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1942 //gtk_tree_view_column_add_attribute(column, renderer, "text", id);
1943 gtk_tree_view_column_set_cell_data_func(column
, renderer
, ui_list_repdist_rate_cell_data_function
, GINT_TO_POINTER(id
), NULL
);
1944 gtk_tree_view_column_set_alignment (column
, 0.5);
1945 //gtk_tree_view_column_set_sort_column_id (column, id);
1947 //gtk_tree_view_column_set_visible(column, FALSE);
1953 ** create our statistic list
1955 static GtkWidget
*ui_list_repdist_create(void)
1957 GtkListStore
*store
;
1959 GtkCellRenderer
*renderer
;
1960 GtkTreeViewColumn
*column
;
1962 /* create list store */
1963 store
= gtk_list_store_new(
1965 G_TYPE_INT
, //keep for compatibility with chart
1977 view
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
));
1978 g_object_unref(store
);
1980 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view
), PREFS
->grid_lines
);
1983 column
= gtk_tree_view_column_new();
1984 gtk_tree_view_column_set_title(column
, _("Result"));
1985 renderer
= gtk_cell_renderer_text_new ();
1986 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1987 //gtk_tree_view_column_set_cell_data_func(column, renderer, ope_result_cell_data_function, NULL, NULL);
1988 gtk_tree_view_column_add_attribute(column
, renderer
, "text", LST_REPDIST_NAME
);
1989 //gtk_tree_view_column_set_sort_column_id (column, LST_REPDIST_NAME);
1990 gtk_tree_view_column_set_resizable(column
, TRUE
);
1991 gtk_tree_view_column_set_alignment (column
, 0.5);
1992 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1994 /* column: Expense */
1995 column
= ui_list_repdist_amount_column(_("Expense"), LST_REPDIST_EXPENSE
);
1996 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1997 column
= ui_list_repdist_rate_column(LST_REPDIST_EXPRATE
);
1998 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
2000 /* column: Income */
2001 column
= ui_list_repdist_amount_column(_("Income"), LST_REPDIST_INCOME
);
2002 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
2003 column
= ui_list_repdist_rate_column(LST_REPDIST_INCRATE
);
2004 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
2006 /* column: Balance */
2007 column
= ui_list_repdist_amount_column(_("Balance"), LST_REPDIST_BALANCE
);
2008 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
2009 column
= ui_list_repdist_rate_column(LST_REPDIST_BALRATE
);
2010 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
2012 /* column last: empty */
2013 column
= gtk_tree_view_column_new();
2014 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
2017 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store
), LST_REPDIST_POS
, ui_list_repdist_compare_func
, GINT_TO_POINTER(LST_REPDIST_POS
), NULL
);
2018 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store
), LST_REPDIST_EXPENSE
, ui_list_repdist_compare_func
, GINT_TO_POINTER(LST_REPDIST_EXPENSE
), NULL
);
2019 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store
), LST_REPDIST_INCOME
, ui_list_repdist_compare_func
, GINT_TO_POINTER(LST_REPDIST_INCOME
), NULL
);
2020 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store
), LST_REPDIST_BALANCE
, ui_list_repdist_compare_func
, GINT_TO_POINTER(LST_REPDIST_BALANCE
), NULL
);
2026 static gint
ui_list_repdist_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
)
2028 gint sortcol
= GPOINTER_TO_INT(userdata
);
2033 gtk_tree_model_get(model
, a
,
2034 LST_REPDIST_POS
, &pos1
,
2037 gtk_tree_model_get(model
, b
,
2038 LST_REPDIST_POS
, &pos2
,
2044 case LST_REPDIST_POS
:
2045 retval
= pos2
- pos1
;
2048 retval
= (ABS(val1
) - ABS(val2
)) > 0 ? 1 : -1;
2052 //DB( g_print(" sort %d=%d or %.2f=%.2f :: %d\n", pos1,pos2, val1, val2, ret) );