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/>.
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"
38 /****************************************************************************/
40 /****************************************************************************/
49 /* our global datas */
50 extern struct HomeBank
*GLOBALS
;
51 extern struct Preferences
*PREFS
;
55 static void ui_reptime_action_viewlist(GtkAction
*action
, gpointer user_data
);
56 static void ui_reptime_action_viewcolumn(GtkAction
*action
, gpointer user_data
);
57 static void ui_reptime_action_viewline(GtkAction
*action
, gpointer user_data
);
58 static void ui_reptime_action_detail(GtkAction
*action
, gpointer user_data
);
59 //static void ui_reptime_action_filter(GtkAction *action, gpointer user_data);
60 static void ui_reptime_action_refresh(GtkAction
*action
, gpointer user_data
);
62 static void ui_reptime_list_set_cur(GtkTreeView
*treeview
, guint32 kcur
);
65 static GtkRadioActionEntry radio_entries
[] = {
66 { "List" , ICONNAME_HB_VIEW_LIST
, N_("List") , NULL
, N_("View results as list") , 0 },
67 { "Line" , ICONNAME_HB_VIEW_LINE
, N_("Line") , NULL
, N_("View results as lines") , 1 },
68 { "Column" , ICONNAME_HB_VIEW_COLUMN
, N_("Column") , NULL
, N_("View results as column"), 2 },
70 static guint n_radio_entries
= G_N_ELEMENTS (radio_entries
);
72 static GtkActionEntry entries
[] = {
73 // { "Filter" , ICONNAME_HB_FILTER , N_("Filter") , NULL, N_("Edit the filter"), G_CALLBACK (ui_reptime_action_filter) },
74 { "Refresh" , ICONNAME_HB_REFRESH
, N_("Refresh"), NULL
, N_("Refresh results"), G_CALLBACK (ui_reptime_action_refresh
) },
76 // { "Export" , ICONNAME_HB_FILE_EXPORT, N_("Export") , NULL, N_("Export as CSV"), G_CALLBACK (ui_reptime_action_export) },
78 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_reptime_action_detail
),
85 FALSE
}, /* is_active */
88 static guint n_toggle_entries
= G_N_ELEMENTS (toggle_entries
);
91 static const gchar
*ui_info
=
93 " <toolbar name='ToolBar'>"
94 " <toolitem action='List'/>"
95 " <toolitem action='Line'/>"
96 " <toolitem action='Column'/>"
98 " <toolitem action='Detail'/>"
100 //" <toolitem action='Filter'/>"
101 " <toolitem action='Refresh'/>"
103 //" <toolitem action='Export'/>"
104 // replaced by a menubutton
109 static void ui_reptime_date_change(GtkWidget
*widget
, gpointer user_data
);
110 static void ui_reptime_range_change(GtkWidget
*widget
, gpointer user_data
);
111 static void ui_reptime_detail(GtkWidget
*widget
, gpointer user_data
);
112 static void ui_reptime_update(GtkWidget
*widget
, gpointer user_data
);
113 static void ui_reptime_compute(GtkWidget
*widget
, gpointer user_data
);
114 static void ui_reptime_sensitive(GtkWidget
*widget
, gpointer user_data
);
115 static void ui_reptime_toggle_detail(GtkWidget
*widget
, gpointer user_data
);
116 static void ui_reptime_toggle_minor(GtkWidget
*widget
, gpointer user_data
);
117 static void ui_reptime_update_daterange(GtkWidget
*widget
, gpointer user_data
);
118 static GtkWidget
*ui_list_reptime_create(void);
120 static gint
ui_list_reptime_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
);
121 static GString
*ui_list_reptime_to_string(GtkTreeView
*treeview
, gboolean clipboard
);
124 HbKvData CYA_REPORT_SRC_TREND
[] = {
125 { REPORT_SRC_ACCOUNT
, N_("Account") },
126 { REPORT_SRC_CATEGORY
, N_("Category") },
127 { REPORT_SRC_PAYEE
, N_("Payee") },
128 { REPORT_SRC_TAG
, N_("Tag") },
133 HbKvData CYA_REPORT_INTVL
[] = {
134 { REPORT_INTVL_DAY
, N_("Day") },
135 { REPORT_INTVL_WEEK
, N_("Week") },
136 { REPORT_INTVL_MONTH
, N_("Month") },
137 { REPORT_INTVL_QUARTER
, N_("Quarter") },
138 { REPORT_INTVL_HALFYEAR
,N_("Half Year") },
139 { REPORT_INTVL_YEAR
, N_("Year") },
144 extern gchar
*RA_REPORT_TIME_MODE
[];
145 extern gchar
*CYA_ABMONTHS
[];
149 /* action functions -------------------- */
152 static void ui_reptime_action_viewlist(GtkAction
*action
, gpointer user_data
)
154 struct ui_reptime_data
*data
= user_data
;
156 data
->charttype
= CHART_TYPE_NONE
;
157 gtk_notebook_set_current_page(GTK_NOTEBOOK(data
->GR_result
), 0);
158 ui_reptime_sensitive(data
->window
, NULL
);
161 static void ui_reptime_action_viewline(GtkAction
*action
, gpointer user_data
)
163 struct ui_reptime_data
*data
= user_data
;
165 data
->charttype
= CHART_TYPE_LINE
;
166 gtk_notebook_set_current_page(GTK_NOTEBOOK(data
->GR_result
), 1);
167 ui_reptime_sensitive(data
->window
, NULL
);
168 ui_reptime_update(data
->window
, NULL
);
172 static void ui_reptime_action_viewcolumn(GtkAction
*action
, gpointer user_data
)
174 struct ui_reptime_data
*data
= user_data
;
176 data
->charttype
= CHART_TYPE_COL
;
177 gtk_notebook_set_current_page(GTK_NOTEBOOK(data
->GR_result
), 1);
178 ui_reptime_sensitive(data
->window
, NULL
);
179 ui_reptime_update(data
->window
, NULL
);
184 static void ui_reptime_action_mode (GtkRadioAction
*action
, GtkRadioAction
*current
, gpointer user_data
)
188 value
= gtk_radio_action_get_current_value(GTK_RADIO_ACTION(action
));
192 ui_reptime_action_viewlist(GTK_ACTION(action
), user_data
);
195 ui_reptime_action_viewline(GTK_ACTION(action
), user_data
);
198 ui_reptime_action_viewcolumn (GTK_ACTION(action
), user_data
);
204 static void ui_reptime_action_detail(GtkAction
*action
, gpointer user_data
)
206 struct ui_reptime_data
*data
= user_data
;
208 ui_reptime_toggle_detail(data
->window
, NULL
);
212 static void ui_reptime_action_filter(GtkAction *action, gpointer user_data)
214 struct ui_reptime_data *data = user_data;
217 //create_deffilter_window(data->filter, TRUE);
219 if(create_deffilter_window(data->filter, TRUE) != GTK_RESPONSE_REJECT)
220 ui_reptime_compute(data->window, NULL);
224 static void ui_reptime_action_refresh(GtkAction
*action
, gpointer user_data
)
226 struct ui_reptime_data
*data
= user_data
;
228 ui_reptime_compute(data
->window
, NULL
);
231 /*static void ui_reptime_action_export(GtkAction *action, gpointer user_data)
233 struct ui_reptime_data *data = user_data;
235 ui_reptime_export_csv(data->window, NULL);
240 /* ======================== */
245 ** ============================================================================
249 ** return the year list position correponding to the passed date
252 static void ui_reptime_date_change(GtkWidget
*widget
, gpointer user_data
)
254 struct ui_reptime_data
*data
;
256 DB( g_print("\n[reptime] date change\n") );
258 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
260 data
->filter
->mindate
= gtk_date_entry_get_date(GTK_DATE_ENTRY(data
->PO_mindate
));
261 data
->filter
->maxdate
= gtk_date_entry_get_date(GTK_DATE_ENTRY(data
->PO_maxdate
));
263 // set min/max date for both widget
264 gtk_date_entry_set_maxdate(GTK_DATE_ENTRY(data
->PO_mindate
), data
->filter
->maxdate
);
265 gtk_date_entry_set_mindate(GTK_DATE_ENTRY(data
->PO_maxdate
), data
->filter
->mindate
);
267 g_signal_handler_block(data
->CY_range
, data
->handler_id
[HID_REPTIME_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_REPTIME_RANGE
]);
271 ui_reptime_compute(widget
, NULL
);
272 ui_reptime_update_daterange(widget
, NULL
);
277 static void ui_reptime_update_quickdate(GtkWidget
*widget
, gpointer user_data
)
279 struct ui_reptime_data
*data
;
281 DB( g_print("\n[reptime] update quickdate\n") );
283 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
285 g_signal_handler_block(data
->PO_mindate
, data
->handler_id
[HID_REPTIME_MINDATE
]);
286 g_signal_handler_block(data
->PO_maxdate
, data
->handler_id
[HID_REPTIME_MAXDATE
]);
288 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_mindate
), data
->filter
->mindate
);
289 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_maxdate
), data
->filter
->maxdate
);
291 g_signal_handler_unblock(data
->PO_mindate
, data
->handler_id
[HID_REPTIME_MINDATE
]);
292 g_signal_handler_unblock(data
->PO_maxdate
, data
->handler_id
[HID_REPTIME_MAXDATE
]);
297 static void ui_reptime_range_change(GtkWidget
*widget
, gpointer user_data
)
299 struct ui_reptime_data
*data
;
302 DB( g_print("\n[reptime] range change\n") );
304 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
306 range
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
));
308 if(range
!= FLT_RANGE_OTHER
)
310 filter_preset_daterange_set(data
->filter
, range
, data
->accnum
);
312 ui_reptime_update_quickdate(widget
, NULL
);
314 ui_reptime_compute(widget
, NULL
);
315 ui_reptime_update_daterange(widget
, NULL
);
320 static void ui_reptime_update_daterange(GtkWidget
*widget
, gpointer user_data
)
322 struct ui_reptime_data
*data
;
325 DB( g_print("\n[reptime] update daterange\n") );
327 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
329 daterange
= filter_daterange_text_get(data
->filter
);
330 gtk_label_set_markup(GTK_LABEL(data
->TX_daterange
), daterange
);
337 static void ui_reptime_update(GtkWidget
*widget
, gpointer user_data
)
339 struct ui_reptime_data
*data
;
345 DB( g_print("\n[reptime] update\n") );
347 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
350 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
));
352 tmpsrc
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_src
));
353 //tmpintvl = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_intvl));
355 // ensure not exp & inc for piechart
356 page
= gtk_notebook_get_current_page(GTK_NOTEBOOK(data
->GR_result
));
358 DB( g_print(" page %d\n\n", page
) );
359 //DB( g_print(" tmpintvl %d\n\n", tmpintvl) );
361 //column = LST_REPTIME_POS;
362 //DB( g_print(" sort on column %d\n\n", column) );
363 //gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), column, GTK_SORT_DESCENDING);
365 gtk_chart_show_legend(GTK_CHART(data
->RE_line
), FALSE
, FALSE
);
366 gtk_chart_show_xval(GTK_CHART(data
->RE_line
), TRUE
);
368 //visible = (tmpmode == REPORT_RESULT_TOTAL) ? TRUE : FALSE;
369 //gtk_chart_show_average(GTK_CHART(data->RE_line), data->average, visible);
371 //TRANSLATORS: example 'Category Over Time'
372 title
= g_strdup_printf(_("%s Over Time"), hbtk_get_label(CYA_REPORT_SRC_TREND
, tmpsrc
) );
373 gtk_chart_set_datas(GTK_CHART(data
->RE_line
), model
, LST_REPTIME_AMOUNT
, title
, NULL
);
378 DB( g_print(" change chart type to %d\n", data
->charttype
) );
379 gtk_chart_set_type (GTK_CHART(data
->RE_line
), data
->charttype
);
380 gtk_chart_set_showmono(GTK_CHART(data
->RE_line
), TRUE
);
386 static void ui_reptime_export_result_clipboard(GtkWidget
*widget
, gpointer user_data
)
388 struct ui_reptime_data
*data
;
389 GtkClipboard
*clipboard
;
392 DB( g_print("\n[reptime] export result clipboard\n") );
395 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
397 node
= ui_list_reptime_to_string(GTK_TREE_VIEW(data
->LV_report
), TRUE
);
399 clipboard
= gtk_clipboard_get_default(gdk_display_get_default());
400 gtk_clipboard_set_text(clipboard
, node
->str
, node
->len
);
402 g_string_free(node
, TRUE
);
406 static void ui_reptime_export_result_csv(GtkWidget
*widget
, gpointer user_data
)
408 struct ui_reptime_data
*data
;
409 gchar
*filename
= NULL
;
415 DB( g_print("\n[reptime] export result csv\n") );
418 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
420 tmpsrc
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_src
));
421 name
= g_strdup_printf("hb-reptime_%s.csv", hbtk_get_label(CYA_REPORT_SRC_TREND
, tmpsrc
) );
423 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_SAVE
, &filename
, name
) == TRUE
)
425 DB( g_print(" + filename is %s\n", filename
) );
426 io
= g_io_channel_new_file(filename
, "w", NULL
);
429 node
= ui_list_reptime_to_string(GTK_TREE_VIEW(data
->LV_report
), FALSE
);
430 g_io_channel_write_chars(io
, node
->str
, -1, NULL
, NULL
);
431 g_io_channel_unref (io
);
432 g_string_free(node
, TRUE
);
440 static void ui_reptime_export_detail_clipboard(GtkWidget
*widget
, gpointer user_data
)
442 struct ui_reptime_data
*data
;
443 GtkClipboard
*clipboard
;
446 DB( g_print("\n[reptime] export detail clipboard\n") );
449 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
451 node
= list_txn_to_string(GTK_TREE_VIEW(data
->LV_detail
), TRUE
);
453 clipboard
= gtk_clipboard_get_default(gdk_display_get_default());
454 gtk_clipboard_set_text(clipboard
, node
->str
, node
->len
);
456 g_string_free(node
, TRUE
);
460 static void ui_reptime_export_detail_csv(GtkWidget
*widget
, gpointer user_data
)
462 struct ui_reptime_data
*data
;
463 gchar
*filename
= NULL
;
469 DB( g_print("\n[reptime] export detail csv\n") );
472 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
474 tmpsrc
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_src
));
475 name
= g_strdup_printf("hb-reptime-detail_%s.csv", hbtk_get_label(CYA_REPORT_SRC_TREND
, tmpsrc
) );
477 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_SAVE
, &filename
, name
) == TRUE
)
479 DB( g_print(" + filename is %s\n", filename
) );
481 io
= g_io_channel_new_file(filename
, "w", NULL
);
484 node
= list_txn_to_string(GTK_TREE_VIEW(data
->LV_detail
), FALSE
);
485 g_io_channel_write_chars(io
, node
->str
, -1, NULL
, NULL
);
487 g_io_channel_unref (io
);
488 g_string_free(node
, TRUE
);
498 static void ui_reptime_update_for(GtkWidget
*widget
, gpointer user_data
)
500 struct ui_reptime_data
*data
;
504 DB( g_print("\n[reptime] update for\n") );
506 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
508 tmpsrc
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_src
));
510 visible
= tmpsrc
== REPORT_SRC_ACCOUNT
? TRUE
: FALSE
;
511 hb_widget_visible(data
->LB_acc
, visible
);
512 hb_widget_visible(data
->PO_acc
, visible
);
514 visible
= tmpsrc
== REPORT_SRC_CATEGORY
? TRUE
: FALSE
;
515 hb_widget_visible(data
->LB_cat
, visible
);
516 hb_widget_visible(data
->PO_cat
, visible
);
518 visible
= tmpsrc
== REPORT_SRC_PAYEE
? TRUE
: FALSE
;
519 hb_widget_visible(data
->LB_pay
, visible
);
520 hb_widget_visible(data
->PO_pay
, visible
);
522 visible
= tmpsrc
== REPORT_SRC_TAG
? TRUE
: FALSE
;
523 hb_widget_visible(data
->LB_tag
, visible
);
524 hb_widget_visible(data
->PO_tag
, visible
);
530 static void ui_reptime_for(GtkWidget
*widget
, gpointer user_data
)
532 struct ui_reptime_data
*data
;
534 DB( g_print("\n[reptime] for\n") );
536 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
538 ui_reptime_update_for(widget
, data
);
540 ui_reptime_compute(widget
, data
);
544 //TODO: this is temporary, as at end we will enable filter
545 static void ui_reptime_compute_set_filter(Filter
*flt
, gint tmpsrc
, guint32 selkey
)
547 //inactive all filters
548 flt
->option
[FILTER_CATEGORY
] = 0;
549 flt
->option
[FILTER_PAYEE
] = 0;
550 flt
->option
[FILTER_ACCOUNT
] = 0;
551 flt
->option
[FILTER_TEXT
] = 0;
555 case REPORT_SRC_ACCOUNT
:
556 flt
->option
[FILTER_ACCOUNT
] = 1;
557 filter_status_acc_clear_except(flt
, selkey
);
559 case REPORT_SRC_CATEGORY
:
560 flt
->option
[FILTER_CATEGORY
] = 1;
561 filter_status_cat_clear_except(flt
, selkey
);
563 case REPORT_SRC_PAYEE
:
564 flt
->option
[FILTER_PAYEE
] = 1;
565 filter_status_pay_clear_except(flt
, selkey
);
568 flt
->option
[FILTER_TEXT
] = 1;
569 filter_set_tag_by_id(flt
, selkey
);
577 static void ui_reptime_detail(GtkWidget
*widget
, gpointer user_data
)
579 struct ui_reptime_data
*data
;
580 guint active
= GPOINTER_TO_INT(user_data
);
587 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
589 DB( g_print("\n[reptime] detail\n") );
591 //tmpsrc = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_src));
592 tmpintvl
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_intvl
));
594 //ui_reptime_compute_set_filter was already called here
596 //get our min max date
597 from
= data
->filter
->mindate
;
598 //to = data->filter->maxdate;
600 /* clear and detach our model */
601 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_detail
));
602 gtk_list_store_clear (GTK_LIST_STORE(model
));
606 g_object_ref(model
); /* Make sure the model stays with us after the tree view unrefs it */
607 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_detail
), NULL
); /* Detach model from view */
609 /* fill in the model */
610 list
= g_queue_peek_head_link(data
->txn_queue
);
613 Transaction
*ope
= list
->data
;
616 if(filter_txn_match(data
->filter
, ope
) == 1)
618 pos
= report_interval_get_pos(tmpintvl
, from
, ope
);
621 gdouble dtlamt
= report_txn_amount_get(data
->filter
, ope
);
623 gtk_list_store_insert_with_values (GTK_LIST_STORE(model
), &iter
, -1,
624 MODEL_TXN_POINTER
, ope
,
625 MODEL_TXN_SPLITAMT
, dtlamt
,
630 list
= g_list_next(list
);
633 /* Re-attach model to view */
634 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_detail
), model
);
635 g_object_unref(model
);
637 gtk_tree_view_columns_autosize( GTK_TREE_VIEW(data
->LV_detail
) );
643 static void ui_reptime_compute(GtkWidget
*widget
, gpointer user_data
)
645 struct ui_reptime_data
*data
;
646 gint tmpsrc
, tmpintvl
, range
, showempty
;
651 gdouble cumulation
, average
;
661 DB( g_print("\n[reptime] compute\n") );
663 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
665 tmpsrc
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_src
));
666 tmpintvl
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_intvl
));
667 cumul
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_cumul
));
668 showall
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_all
));
669 range
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
));
670 showempty
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_showempty
));
677 case REPORT_SRC_ACCOUNT
:
678 selkey
= ui_acc_comboboxentry_get_key(GTK_COMBO_BOX(data
->PO_acc
));
680 data
->accnum
= selkey
;
682 case REPORT_SRC_CATEGORY
:
683 selkey
= ui_cat_comboboxentry_get_key(GTK_COMBO_BOX(data
->PO_cat
));
685 case REPORT_SRC_PAYEE
:
686 selkey
= ui_pay_comboboxentry_get_key(GTK_COMBO_BOX(data
->PO_pay
));
689 selkey
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->PO_tag
));
693 if( showall
== TRUE
)
695 data
->filter
->option
[FILTER_CATEGORY
] = 0;
696 data
->filter
->option
[FILTER_PAYEE
] = 0;
697 data
->filter
->option
[FILTER_ACCOUNT
] = 0;
698 data
->filter
->option
[FILTER_TEXT
] = 0;
701 ui_reptime_compute_set_filter(data
->filter
, tmpsrc
, selkey
);
704 DB( g_print(" source=%d-%s, intvl=%d-%s:: key=%d\n", tmpsrc
, hbtk_get_label(CYA_REPORT_SRC_TREND
, tmpsrc
), tmpintvl
, hbtk_get_label(CYA_REPORT_INTVL
, tmpintvl
), selkey
) );
707 //#1715532 5.0.5: no... but only showall
708 if( (showall
== TRUE
) && (range
== FLT_RANGE_ALLDATE
) )
710 filter_preset_daterange_set(data
->filter
, data
->filter
->range
, data
->accnum
);
711 ui_reptime_update_quickdate(widget
, NULL
);
714 //get our min max date
715 from
= data
->filter
->mindate
;
716 to
= data
->filter
->maxdate
;
717 if(to
< from
) return;
719 g_queue_free (data
->txn_queue
);
720 data
->txn_queue
= hbfile_transaction_get_partial(data
->filter
->mindate
, data
->filter
->maxdate
);
722 n_result
= report_interval_count(tmpintvl
, from
, to
);
724 DB( g_print(" %s :: n_result=%d\n", hbtk_get_label(CYA_REPORT_SRC_TREND
, tmpsrc
), n_result
) );
726 /* allocate some memory */
727 tmp_amount
= g_malloc0((n_result
+2) * sizeof(gdouble
));
731 list
= g_queue_peek_head_link(data
->txn_queue
);
734 Transaction
*ope
= list
->data
;
736 //DB( g_print("\n** testing '%s', cat=%d==> %d\n", ope->memo, ope->kcat, filter_txn_match(data->filter, ope)) );
738 if( (filter_txn_match(data
->filter
, ope
) == 1) )
743 trn_amount
= report_txn_amount_get(data
->filter
, ope
);
745 //#1829603 Multi currencies problem in Trend Time Report
746 if( ! ( tmpsrc
== REPORT_SRC_ACCOUNT
&& showall
== FALSE
) )
747 trn_amount
= hb_amount_base(trn_amount
, ope
->kcur
);
749 pos
= report_interval_get_pos(tmpintvl
, from
, ope
);
750 if( pos
<= n_result
)
752 DB( g_print("** pos=%d : add of %.2f\n", pos
, trn_amount
) );
753 tmp_amount
[pos
] += trn_amount
;
757 DB( g_print("** pos=%d : invalid offset\n", pos
) );
760 list
= g_list_next(list
);
763 /* clear and detach our model */
764 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
));
765 gtk_list_store_clear (GTK_LIST_STORE(model
));
766 g_object_ref(model
); /* Make sure the model stays with us after the tree view unrefs it */
767 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_report
), NULL
); /* Detach model from view */
771 /* insert into the treeview */
772 for(i
=0, id
=0; i
<n_result
; i
++)
777 if( !showempty
&& tmp_amount
[i
] == 0 )
780 report_interval_snprint_name(intvlname
, sizeof(intvlname
)-1, tmpintvl
, from
, i
);
782 DB( g_print("try to insert item %d\n", i
) );
784 cumulation
+= tmp_amount
[i
];
785 value
= (cumul
== TRUE
) ? cumulation
: tmp_amount
[i
];
787 DB( g_print(" inserting %2d, '%s', %9.2f\n", i
, intvlname
, value
) );
789 gtk_list_store_insert_with_values (GTK_LIST_STORE(model
), &iter
, -1,
790 LST_REPTIME_POS
, id
++,
792 LST_REPTIME_TITLE
, intvlname
,
793 LST_REPTIME_AMOUNT
, value
,
798 // set chart and listview currency
799 guint32 kcur
= GLOBALS
->kcur
;
800 if( (showall
== FALSE
) && (tmpsrc
== REPORT_SRC_ACCOUNT
) )
802 Account
*acc
= da_acc_get(selkey
);
806 gtk_chart_set_overdrawn(GTK_CHART(data
->RE_line
), acc
->minimum
);
809 ui_reptime_list_set_cur(GTK_TREE_VIEW(data
->LV_report
), kcur
);
810 gtk_chart_set_currency(GTK_CHART(data
->RE_line
), kcur
);
813 /* update column 0 title */
814 GtkTreeViewColumn
*column
= gtk_tree_view_get_column( GTK_TREE_VIEW(data
->LV_report
), 0);
816 gtk_tree_view_column_set_title(column
, hbtk_get_label(CYA_REPORT_INTVL
, tmpintvl
) );
818 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_report
));
820 /* Re-attach model to view */
821 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_report
), model
);
822 g_object_unref(model
);
825 gtk_label_set_text(GTK_LABEL(data
->TX_info
), "");
832 average
= cumulation
/ n_result
;
833 data
->average
= average
;
835 hb_strfmon(buf
, 127, average
, kcur
, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_minor
)) );
837 info
= g_strdup_printf(_("Average: %s"), buf
);
838 gtk_label_set_text(GTK_LABEL(data
->TX_info
), info
);
843 /* free our memory */
846 ui_reptime_update(widget
, user_data
);
850 static void ui_reptime_sensitive(GtkWidget
*widget
, gpointer user_data
)
852 struct ui_reptime_data
*data
;
854 gboolean visible
, sensitive
;
857 DB( g_print("\n[reptime] sensitive\n") );
859 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
861 page
= gtk_notebook_get_current_page(GTK_NOTEBOOK(data
->GR_result
));
863 visible
= page
== 0 ? TRUE
: FALSE
;
864 action
= gtk_ui_manager_get_action(data
->ui
, "/ToolBar/Detail");
865 gtk_action_set_visible (action
, visible
);
866 //action = gtk_ui_manager_get_action(data->ui, "/ToolBar/Export");
867 //gtk_action_set_visible (action, visible);
868 //sensitive = gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_report)), NULL, NULL);
869 //gtk_action_set_sensitive(action, sensitive);
870 hb_widget_visible (data
->BT_export
, visible
);
872 visible
= page
== 0 ? FALSE
: TRUE
;
873 hb_widget_visible(data
->LB_zoomx
, visible
);
874 hb_widget_visible(data
->RG_zoomx
, visible
);
876 sensitive
= gtk_tree_model_iter_n_children(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_detail
)), NULL
) > 0 ? TRUE
: FALSE
;
877 gtk_widget_set_sensitive(data
->MI_detailtoclip
, sensitive
);
878 gtk_widget_set_sensitive(data
->MI_detailtocsv
, sensitive
);
883 static void ui_reptime_detail_onRowActivated (GtkTreeView
*treeview
,
885 GtkTreeViewColumn
*col
,
888 struct ui_reptime_data
*data
;
889 Transaction
*active_txn
;
892 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview
), GTK_TYPE_WINDOW
)), "inst_data");
894 DB( g_print ("\n[reptime] A detail row has been double-clicked!\n") );
896 active_txn
= list_txn_get_active_transaction(GTK_TREE_VIEW(data
->LV_detail
));
899 Transaction
*old_txn
, *new_txn
;
901 old_txn
= da_transaction_clone (active_txn
);
902 new_txn
= active_txn
;
903 result
= deftransaction_external_edit(GTK_WINDOW(data
->window
), old_txn
, new_txn
);
905 if(result
== GTK_RESPONSE_ACCEPT
)
908 GLOBALS
->changes_count
++;
909 ui_reptime_compute(data
->window
, NULL
);
912 da_transaction_free (old_txn
);
917 static void ui_reptime_update_detail(GtkWidget
*widget
, gpointer user_data
)
919 struct ui_reptime_data
*data
;
921 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
925 GtkTreeSelection
*treeselection
;
930 treeselection
= gtk_tree_view_get_selection (GTK_TREE_VIEW(data
->LV_report
));
932 if (gtk_tree_selection_get_selected(treeselection
, &model
, &iter
))
934 gtk_tree_model_get(model
, &iter
, LST_REPTIME_KEY
, &key
, -1);
936 DB( g_print(" - active is %d\n", key
) );
938 ui_reptime_detail(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), GINT_TO_POINTER(key
));
943 gtk_widget_show(data
->GR_detail
);
946 gtk_widget_hide(data
->GR_detail
);
952 static void ui_reptime_toggle_detail(GtkWidget
*widget
, gpointer user_data
)
954 struct ui_reptime_data
*data
;
956 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
960 DB( g_print("(stats) toggledetail to %d\n", data
->detail
) );
962 ui_reptime_update_detail(widget
, user_data
);
966 static void ui_reptime_zoomx_callback(GtkWidget
*widget
, gpointer user_data
)
968 struct ui_reptime_data
*data
;
971 DB( g_print("\n[reptime] zoomx\n") );
973 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
975 value
= gtk_range_get_value(GTK_RANGE(data
->RG_zoomx
));
977 DB( g_print(" + scale is %.2f\n", value
) );
979 gtk_chart_set_barw(GTK_CHART(data
->RE_line
), value
);
985 static void ui_reptime_toggle_minor(GtkWidget
*widget
, gpointer user_data
)
987 struct ui_reptime_data
*data
;
989 DB( g_print("\n[reptime] toggle\n") );
991 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
993 GLOBALS
->minor
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_minor
));
995 //hbfile_update(data->LV_acc, (gpointer)4);
996 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_report
));
998 gtk_chart_show_minor(GTK_CHART(data
->RE_line
), GLOBALS
->minor
);
1003 static void ui_reptime_toggle_showall(GtkWidget
*widget
, gpointer user_data
)
1005 struct ui_reptime_data
*data
;
1008 DB( g_print("\n[reptime] toggle\n") );
1010 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1012 showall
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_all
));
1014 gtk_widget_set_sensitive(GTK_WIDGET(data
->PO_acc
), showall
^1);
1015 gtk_widget_set_sensitive(GTK_WIDGET(data
->PO_cat
), showall
^1);
1016 gtk_widget_set_sensitive(GTK_WIDGET(data
->PO_pay
), showall
^1);
1017 gtk_widget_set_sensitive(GTK_WIDGET(data
->PO_tag
), showall
^1);
1019 ui_reptime_compute(widget
, data
);
1028 static void ui_reptime_setup(struct ui_reptime_data
*data
, guint32 accnum
)
1030 DB( g_print("\n[reptime] setup\n") );
1032 data
->txn_queue
= g_queue_new ();
1034 data
->filter
= da_flt_malloc();
1035 filter_reset(data
->filter
);
1039 /* 3.4 : make int transfer out of stats */
1040 //todo: for compatibility with < 5.3, keep this unset, but normally it should be set
1041 //data->filter->option[FILTER_PAYMODE] = 1;
1042 //data->filter->paymode[PAYMODE_INTXFER] = FALSE;
1044 filter_preset_daterange_set(data
->filter
, PREFS
->date_range_rep
, data
->accnum
);
1046 g_signal_handler_block(data
->PO_mindate
, data
->handler_id
[HID_REPTIME_MINDATE
]);
1047 g_signal_handler_block(data
->PO_maxdate
, data
->handler_id
[HID_REPTIME_MAXDATE
]);
1049 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_mindate
), data
->filter
->mindate
);
1050 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_maxdate
), data
->filter
->maxdate
);
1052 g_signal_handler_unblock(data
->PO_mindate
, data
->handler_id
[HID_REPTIME_MINDATE
]);
1053 g_signal_handler_unblock(data
->PO_maxdate
, data
->handler_id
[HID_REPTIME_MAXDATE
]);
1056 DB( g_print(" populate\n") );
1057 ui_acc_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_acc
), GLOBALS
->h_acc
, ACC_LST_INSERT_REPORT
);
1059 ui_acc_comboboxentry_set_active(GTK_COMBO_BOX(data
->PO_acc
), accnum
);
1061 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->PO_acc
), 0);
1063 ui_pay_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_pay
), GLOBALS
->h_pay
);
1064 ui_pay_comboboxentry_set_active(GTK_COMBO_BOX(data
->PO_pay
), 0);
1066 ui_cat_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_cat
), GLOBALS
->h_cat
);
1067 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->PO_cat
), 0);
1069 ui_tag_combobox_populate(GTK_COMBO_BOX_TEXT(data
->PO_tag
));
1071 DB( g_print(" all ok\n") );
1077 static void ui_reptime_selection(GtkTreeSelection
*treeselection
, gpointer user_data
)
1079 GtkTreeModel
*model
;
1083 DB( g_print("\n[reptime] selection\n") );
1085 if (gtk_tree_selection_get_selected(treeselection
, &model
, &iter
))
1087 gtk_tree_model_get(model
, &iter
, LST_REPTIME_KEY
, &key
, -1);
1091 DB( g_print(" - active is %d\n", key
) );
1093 ui_reptime_detail(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), GINT_TO_POINTER(key
));
1094 ui_reptime_sensitive(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), NULL
);
1101 static gboolean
ui_reptime_dispose(GtkWidget
*widget
, GdkEvent
*event
, gpointer user_data
)
1103 struct ui_reptime_data
*data
= user_data
;
1104 struct WinGeometry
*wg
;
1106 DB( g_print("\n[reptime] dispose\n") );
1108 g_queue_free (data
->txn_queue
);
1110 da_flt_free(data
->filter
);
1114 //store position and size
1115 wg
= &PREFS
->tme_wg
;
1116 gtk_window_get_position(GTK_WINDOW(widget
), &wg
->l
, &wg
->t
);
1117 gtk_window_get_size(GTK_WINDOW(widget
), &wg
->w
, &wg
->h
);
1119 DB( g_print(" window: l=%d, t=%d, w=%d, h=%d\n", wg
->l
, wg
->t
, wg
->w
, wg
->h
) );
1123 //enable define windows
1124 GLOBALS
->define_off
--;
1125 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
));
1130 // the window creation
1131 GtkWidget
*ui_reptime_window_new(guint32 accnum
)
1133 struct ui_reptime_data
*data
;
1134 struct WinGeometry
*wg
;
1135 GtkWidget
*window
, *mainvbox
, *hbox
, *vbox
, *notebook
, *treeview
;
1136 GtkWidget
*label
, *widget
, *table
;
1139 GtkActionGroup
*actions
;
1140 //GtkAction *action;
1141 GError
*error
= NULL
;
1143 data
= g_malloc0(sizeof(struct ui_reptime_data
));
1144 if(!data
) return NULL
;
1146 DB( g_print("\n[reptime] new\n") );
1149 //disable define windows
1150 GLOBALS
->define_off
++;
1151 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
));
1153 /* create window, etc */
1154 window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
1155 data
->window
= window
;
1157 //store our window private data
1158 g_object_set_data(G_OBJECT(window
), "inst_data", (gpointer
)data
);
1159 DB( g_print(" - new window=%p, inst_data=%p\n", window
, data
) );
1162 gtk_window_set_title (GTK_WINDOW (window
), _("Trend Time Report"));
1164 //set the window icon
1165 gtk_window_set_icon_name(GTK_WINDOW (window
), ICONNAME_HB_REP_TIME
);
1169 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
1170 gtk_container_add (GTK_CONTAINER (window
), mainvbox
);
1172 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
1173 gtk_box_pack_start (GTK_BOX (mainvbox
), hbox
, TRUE
, TRUE
, 0);
1176 table
= gtk_grid_new ();
1177 gtk_widget_set_hexpand (GTK_WIDGET(table
), FALSE
);
1178 gtk_box_pack_start (GTK_BOX (hbox
), table
, FALSE
, FALSE
, 0);
1180 gtk_container_set_border_width (GTK_CONTAINER (table
), SPACING_SMALL
);
1181 gtk_grid_set_row_spacing (GTK_GRID (table
), SPACING_SMALL
);
1182 gtk_grid_set_column_spacing (GTK_GRID (table
), SPACING_MEDIUM
);
1185 label
= make_label_group(_("Display"));
1186 gtk_grid_attach (GTK_GRID (table
), label
, 0, row
, 3, 1);
1189 label
= make_label_widget(_("_View by:"));
1190 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1191 //widget = make_cycle(label, CYA_TIMESELECT);
1192 widget
= hbtk_combo_box_new_with_data(label
, CYA_REPORT_SRC_TREND
);
1193 data
->CY_src
= widget
;
1194 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1197 label
= make_label_widget(_("A_ccount:"));
1198 data
->LB_acc
= label
;
1199 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1200 widget
= ui_acc_comboboxentry_new(label
);
1201 data
->PO_acc
= widget
;
1202 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1205 label
= make_label_widget(_("_Category:"));
1206 data
->LB_cat
= label
;
1207 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1208 widget
= ui_cat_comboboxentry_new(label
);
1209 data
->PO_cat
= widget
;
1210 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1213 label
= make_label_widget(_("_Payee:"));
1214 data
->LB_pay
= label
;
1215 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1216 widget
= ui_pay_comboboxentry_new(label
);
1217 data
->PO_pay
= widget
;
1218 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1221 label
= make_label_widget(_("_Tag:"));
1222 data
->LB_tag
= label
;
1223 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1224 widget
= ui_tag_combobox_new(label
);
1225 data
->PO_tag
= widget
;
1226 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1229 widget
= gtk_check_button_new_with_mnemonic (_("Select _all"));
1230 data
->CM_all
= widget
;
1231 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1234 widget
= gtk_check_button_new_with_mnemonic (_("_Cumulate"));
1235 data
->CM_cumul
= widget
;
1236 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1239 label
= make_label_widget(_("Inter_val:"));
1240 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1241 //widget = make_cycle(label, CYA_REPORT_INTVL);
1242 widget
= hbtk_combo_box_new_with_data(label
, CYA_REPORT_INTVL
);
1243 data
->CY_intvl
= widget
;
1244 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1247 widget
= gtk_check_button_new_with_mnemonic (_("Show empty line"));
1248 data
->CM_showempty
= widget
;
1249 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1253 widget
= gtk_check_button_new_with_mnemonic (_("Euro _minor"));
1254 data
->CM_minor
= widget
;
1255 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1258 label
= make_label_widget(_("_Zoom X:"));
1259 data
->LB_zoomx
= label
;
1260 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1261 widget
= make_scale(label
);
1262 data
->RG_zoomx
= widget
;
1263 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1266 widget
= gtk_separator_new(GTK_ORIENTATION_HORIZONTAL
);
1267 gtk_grid_attach (GTK_GRID (table
), widget
, 0, row
, 3, 1);
1270 label
= make_label_group(_("Date filter"));
1271 gtk_grid_attach (GTK_GRID (table
), label
, 0, row
, 3, 1);
1274 label
= make_label_widget(_("_Range:"));
1275 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1276 data
->CY_range
= make_daterange(label
, DATE_RANGE_CUSTOM_DISABLE
);
1277 gtk_grid_attach (GTK_GRID (table
), data
->CY_range
, 2, row
, 1, 1);
1280 label
= make_label_widget(_("_From:"));
1281 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1282 data
->PO_mindate
= gtk_date_entry_new();
1283 gtk_grid_attach (GTK_GRID (table
), data
->PO_mindate
, 2, row
, 1, 1);
1286 label
= make_label_widget(_("_To:"));
1287 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1288 data
->PO_maxdate
= gtk_date_entry_new();
1289 gtk_grid_attach (GTK_GRID (table
), data
->PO_maxdate
, 2, row
, 1, 1);
1292 //part: info + report
1293 vbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
1294 gtk_box_pack_start (GTK_BOX (hbox
), vbox
, TRUE
, TRUE
, 0);
1297 actions
= gtk_action_group_new ("default");
1300 gtk_action_group_set_translation_domain(actions
, GETTEXT_PACKAGE
);
1302 // data to action callbacks is set here (data)
1303 gtk_action_group_add_radio_actions (actions
, radio_entries
, n_radio_entries
, 0, G_CALLBACK(ui_reptime_action_mode
), data
);
1305 gtk_action_group_add_actions (actions
, entries
, n_entries
, data
);
1307 gtk_action_group_add_toggle_actions (actions
,
1308 toggle_entries
, n_toggle_entries
,
1312 /* set which action should have priority in the toolbar */
1313 //action = gtk_action_group_get_action(actions, "List");
1314 //g_object_set(action, "is_important", TRUE, NULL);
1316 //action = gtk_action_group_get_action(actions, "Line");
1317 //g_object_set(action, "is_important", TRUE, NULL);
1319 /*action = gtk_action_group_get_action(actions, "Column");
1320 g_object_set(action, "is_important", TRUE, NULL);*/
1322 //action = gtk_action_group_get_action(actions, "Detail");
1323 //g_object_set(action, "is_important", TRUE, NULL);
1325 //action = gtk_action_group_get_action(actions, "Refresh");
1326 //g_object_set(action, "is_important", TRUE, NULL);
1329 ui
= gtk_ui_manager_new ();
1330 gtk_ui_manager_insert_action_group (ui
, actions
, 0);
1331 gtk_window_add_accel_group (GTK_WINDOW (window
), gtk_ui_manager_get_accel_group (ui
));
1333 if (!gtk_ui_manager_add_ui_from_string (ui
, ui_info
, -1, &error
))
1335 g_message ("building UI failed: %s", error
->message
);
1336 g_error_free (error
);
1340 data
->actions
= actions
;
1343 data
->TB_bar
= gtk_ui_manager_get_widget (ui
, "/ToolBar");
1344 gtk_box_pack_start (GTK_BOX (vbox
), data
->TB_bar
, FALSE
, FALSE
, 0);
1346 //add export menu button
1347 GtkToolItem
*toolitem
;
1348 GtkWidget
*menu
, *menuitem
, *image
;
1350 menu
= gtk_menu_new ();
1351 //gtk_widget_set_halign (menu, GTK_ALIGN_END);
1353 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Result to clipboard"));
1354 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1355 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_reptime_export_result_clipboard
), data
);
1357 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Result to CSV"));
1358 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1359 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_reptime_export_result_csv
), data
);
1361 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Detail to clipboard"));
1362 data
->MI_detailtoclip
= menuitem
;
1363 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1364 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_reptime_export_detail_clipboard
), data
);
1366 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Detail to CSV"));
1367 data
->MI_detailtocsv
= menuitem
;
1368 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1369 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_reptime_export_detail_csv
), data
);
1371 gtk_widget_show_all (menu
);
1373 widget
= gtk_menu_button_new();
1374 data
->BT_export
= widget
;
1375 gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(widget
)), GTK_STYLE_CLASS_FLAT
);
1377 //gtk_menu_button_set_direction (GTK_MENU_BUTTON(widget), GTK_ARROW_DOWN);
1378 //gtk_widget_set_halign (widget, GTK_ALIGN_END);
1379 image
= gtk_image_new_from_icon_name (ICONNAME_HB_FILE_EXPORT
, GTK_ICON_SIZE_LARGE_TOOLBAR
);
1380 g_object_set (widget
, "image", image
, "popup", GTK_MENU(menu
), NULL
);
1382 toolitem
= gtk_tool_item_new();
1383 gtk_container_add (GTK_CONTAINER(toolitem
), widget
);
1384 gtk_toolbar_insert(GTK_TOOLBAR(data
->TB_bar
), GTK_TOOL_ITEM(toolitem
), -1);
1387 hbox
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, SPACING_SMALL
);
1388 gtk_container_set_border_width (GTK_CONTAINER(hbox
), SPACING_SMALL
);
1389 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
1391 label
= gtk_label_new(NULL
);
1392 data
->TX_info
= label
;
1393 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
1395 widget
= make_label(NULL
, 0.5, 0.5);
1396 gimp_label_set_attributes (GTK_LABEL (widget
), PANGO_ATTR_SCALE
, PANGO_SCALE_SMALL
, -1);
1397 data
->TX_daterange
= widget
;
1398 gtk_box_pack_start (GTK_BOX (hbox
), widget
, TRUE
, TRUE
, 0);
1402 notebook
= gtk_notebook_new();
1403 data
->GR_result
= notebook
;
1404 gtk_widget_show(notebook
);
1405 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook
), FALSE
);
1406 gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook
), FALSE
);
1408 gtk_box_pack_start (GTK_BOX (vbox
), notebook
, TRUE
, TRUE
, 0);
1411 vbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
1412 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), vbox
, NULL
);
1414 widget
= gtk_scrolled_window_new (NULL
, NULL
);
1415 //gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW (widget), GTK_CORNER_TOP_RIGHT);
1416 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget
), GTK_SHADOW_ETCHED_IN
);
1417 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (widget
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1418 treeview
= ui_list_reptime_create();
1419 data
->LV_report
= treeview
;
1420 gtk_container_add (GTK_CONTAINER(widget
), treeview
);
1421 gtk_box_pack_start (GTK_BOX (vbox
), widget
, TRUE
, TRUE
, 0);
1424 widget
= gtk_scrolled_window_new (NULL
, NULL
);
1425 data
->GR_detail
= widget
;
1426 //gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW (widget), GTK_CORNER_TOP_RIGHT);
1427 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget
), GTK_SHADOW_ETCHED_IN
);
1428 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (widget
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1429 treeview
= create_list_transaction(LIST_TXN_TYPE_DETAIL
, PREFS
->lst_ope_columns
);
1430 data
->LV_detail
= treeview
;
1431 gtk_container_add (GTK_CONTAINER(widget
), treeview
);
1433 gtk_box_pack_start (GTK_BOX (vbox
), widget
, TRUE
, TRUE
, 0);
1437 widget
= gtk_chart_new(CHART_TYPE_LINE
);
1438 data
->RE_line
= widget
;
1439 //gtk_chart_set_minor_prefs(GTK_CHART(widget), PREFS->euro_value, PREFS->minor_cur.suffix_symbol);
1440 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), widget
, NULL
);
1442 //todo:should move this
1443 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_minor
), GLOBALS
->minor
);
1445 //duplicate, see below
1446 //gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_intvl), 1);
1448 /* attach our minor to treeview */
1449 g_object_set_data(G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
))), "minor", (gpointer
)data
->CM_minor
);
1450 g_object_set_data(G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_detail
))), "minor", (gpointer
)data
->CM_minor
);
1454 /* signal connect */
1455 g_signal_connect (window
, "delete-event", G_CALLBACK (ui_reptime_dispose
), (gpointer
)data
);
1457 g_signal_connect (data
->CM_cumul
, "toggled", G_CALLBACK (ui_reptime_compute
), NULL
);
1459 g_signal_connect (data
->CM_minor
, "toggled", G_CALLBACK (ui_reptime_toggle_minor
), NULL
);
1461 data
->handler_id
[HID_REPTIME_MINDATE
] = g_signal_connect (data
->PO_mindate
, "changed", G_CALLBACK (ui_reptime_date_change
), (gpointer
)data
);
1462 data
->handler_id
[HID_REPTIME_MAXDATE
] = g_signal_connect (data
->PO_maxdate
, "changed", G_CALLBACK (ui_reptime_date_change
), (gpointer
)data
);
1464 data
->handler_id
[HID_REPTIME_RANGE
] = g_signal_connect (data
->CY_range
, "changed", G_CALLBACK (ui_reptime_range_change
), NULL
);
1466 g_signal_connect (data
->CY_src
, "changed", G_CALLBACK (ui_reptime_for
), (gpointer
)data
);
1467 data
->handler_id
[HID_REPTIME_VIEW
] = g_signal_connect (data
->CY_intvl
, "changed", G_CALLBACK (ui_reptime_compute
), (gpointer
)data
);
1469 g_signal_connect (data
->CM_showempty
, "toggled", G_CALLBACK (ui_reptime_compute
), NULL
);
1471 //setup, init and show window
1472 ui_reptime_setup(data
, accnum
);
1474 g_signal_connect (data
->CM_all
, "toggled", G_CALLBACK (ui_reptime_toggle_showall
), NULL
);
1475 g_signal_connect (data
->PO_acc
, "changed", G_CALLBACK (ui_reptime_compute
), NULL
);
1476 g_signal_connect (data
->PO_cat
, "changed", G_CALLBACK (ui_reptime_compute
), NULL
);
1477 g_signal_connect (data
->PO_pay
, "changed", G_CALLBACK (ui_reptime_compute
), NULL
);
1478 g_signal_connect (data
->PO_tag
, "changed", G_CALLBACK (ui_reptime_compute
), NULL
);
1480 g_signal_connect (data
->RG_zoomx
, "value-changed", G_CALLBACK (ui_reptime_zoomx_callback
), NULL
);
1483 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_report
)), "changed", G_CALLBACK (ui_reptime_selection
), NULL
);
1485 g_signal_connect (GTK_TREE_VIEW(data
->LV_detail
), "row-activated", G_CALLBACK (ui_reptime_detail_onRowActivated
), NULL
);
1489 if(PREFS
->toolbar_style
== 0)
1490 gtk_toolbar_unset_style(GTK_TOOLBAR(data
->TB_bar
));
1492 gtk_toolbar_set_style(GTK_TOOLBAR(data
->TB_bar
), PREFS
->toolbar_style
-1);
1494 //setup, init and show window
1495 wg
= &PREFS
->tme_wg
;
1496 gtk_window_move(GTK_WINDOW(window
), wg
->l
, wg
->t
);
1497 gtk_window_resize(GTK_WINDOW(window
), wg
->w
, wg
->h
);
1500 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data
->CY_intvl
), REPORT_INTVL_MONTH
);
1502 gtk_widget_show_all (window
);
1505 if( PREFS
->euro_active
)
1506 gtk_widget_show(data
->CM_minor
);
1508 gtk_widget_hide(data
->CM_minor
);
1510 ui_reptime_update_for(window
, data
);
1511 //gtk_widget_hide(data->GR_detail);
1515 ui_reptime_sensitive(window
, NULL
);
1516 ui_reptime_update_detail(window
, NULL
);
1518 DB( g_print("range: %d\n", PREFS
->date_range_rep
) );
1520 if( PREFS
->date_range_rep
!= 0)
1521 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
), PREFS
->date_range_rep
);
1523 ui_reptime_compute(window
, NULL
);
1530 ** ============================================================================
1534 static GString
*ui_list_reptime_to_string(GtkTreeView
*treeview
, gboolean clipboard
)
1537 GtkTreeModel
*model
;
1540 const gchar
*format
;
1542 node
= g_string_new(NULL
);
1545 format
= (clipboard
== TRUE
) ? "%s\t%s\n" : "%s;%s\n";
1546 g_string_append_printf(node
, format
, _("Time slice"), _("Amount"));
1548 model
= gtk_tree_view_get_model(treeview
);
1549 valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model
), &iter
);
1555 gtk_tree_model_get (model
, &iter
,
1556 //LST_REPTIME_KEY, i,
1557 LST_REPTIME_TITLE
, &name
,
1558 LST_REPTIME_AMOUNT
, &amount
,
1561 format
= (clipboard
== TRUE
) ? "%s\t%.2f\n" : "%s;%.2f\n";
1562 g_string_append_printf(node
, format
, name
, amount
);
1567 valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &iter
);
1570 //DB( g_print("text is:\n%s", node->str) );
1576 static void ui_reptime_amount_cell_data_function (GtkTreeViewColumn
*col
,
1577 GtkCellRenderer
*renderer
,
1578 GtkTreeModel
*model
,
1584 gchar buf
[G_ASCII_DTOSTR_BUF_SIZE
];
1585 guint32 kcur
= GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(gtk_tree_view_column_get_tree_view(col
)), "kcur_data"));
1587 gtk_tree_model_get(model
, iter
, GPOINTER_TO_INT(user_data
), &value
, -1);
1591 hb_strfmon(buf
, G_ASCII_DTOSTR_BUF_SIZE
-1, value
, kcur
, GLOBALS
->minor
);
1593 color
= get_normal_color_amount(value
);
1595 g_object_set(renderer
,
1596 "foreground", color
,
1601 g_object_set(renderer
, "text", "", NULL
);
1606 static GtkTreeViewColumn
*amount_list_ui_reptime_column(gchar
*name
, gint id
)
1608 GtkTreeViewColumn
*column
;
1609 GtkCellRenderer
*renderer
;
1611 column
= gtk_tree_view_column_new();
1612 gtk_tree_view_column_set_title(column
, name
);
1613 renderer
= gtk_cell_renderer_text_new ();
1614 g_object_set(renderer
, "xalign", 1.0, NULL
);
1615 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1616 gtk_tree_view_column_set_cell_data_func(column
, renderer
, ui_reptime_amount_cell_data_function
, GINT_TO_POINTER(id
), NULL
);
1617 gtk_tree_view_column_set_alignment (column
, 0.5);
1618 //gtk_tree_view_column_set_sort_column_id (column, id);
1623 static void ui_reptime_list_set_cur(GtkTreeView
*treeview
, guint32 kcur
)
1625 g_object_set_data(G_OBJECT(treeview
), "kcur_data", GUINT_TO_POINTER(kcur
));
1630 ** create our statistic list
1632 static GtkWidget
*ui_list_reptime_create(void)
1634 GtkListStore
*store
;
1636 GtkCellRenderer
*renderer
;
1637 GtkTreeViewColumn
*column
;
1639 /* create list store */
1640 store
= gtk_list_store_new(
1649 view
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
));
1650 g_object_unref(store
);
1652 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view
), PREFS
->grid_lines
);
1655 column
= gtk_tree_view_column_new();
1656 gtk_tree_view_column_set_title(column
, _("Time slice"));
1657 renderer
= gtk_cell_renderer_text_new ();
1658 g_object_set(renderer
, "xalign", 1.0, NULL
);
1659 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1660 //gtk_tree_view_column_set_cell_data_func(column, renderer, ope_result_cell_data_function, NULL, NULL);
1661 gtk_tree_view_column_add_attribute(column
, renderer
, "text", LST_REPTIME_TITLE
);
1662 //gtk_tree_view_column_set_sort_column_id (column, LST_REPTIME_NAME);
1663 gtk_tree_view_column_set_resizable(column
, TRUE
);
1664 gtk_tree_view_column_set_alignment (column
, 0.5);
1665 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1667 /* column: Amount */
1668 column
= amount_list_ui_reptime_column(_("Amount"), LST_REPTIME_AMOUNT
);
1669 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1671 /* column last: empty */
1672 column
= gtk_tree_view_column_new();
1673 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1676 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store
), LST_REPTIME_POS
, ui_list_reptime_compare_func
, GINT_TO_POINTER(LST_REPTIME_POS
), NULL
);
1677 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store
), LST_REPTIME_AMOUNT
, ui_list_reptime_compare_func
, GINT_TO_POINTER(LST_REPTIME_AMOUNT
), NULL
);
1682 static gint
ui_list_reptime_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
)
1684 gint sortcol
= GPOINTER_TO_INT(userdata
);
1689 gtk_tree_model_get(model
, a
,
1690 LST_REPTIME_POS
, &pos1
,
1693 gtk_tree_model_get(model
, b
,
1694 LST_REPTIME_POS
, &pos2
,
1698 if(pos1 == -1) return(1);
1699 if(pos2 == -1) return(-1);
1702 if(sortcol
== LST_REPTIME_POS
)
1703 retval
= pos2
- pos1
;
1705 retval
= (ABS(val1
) - ABS(val2
)) > 0 ? 1 : -1;
1707 //DB( g_print(" sort %d=%d or %.2f=%.2f :: %d\n", pos1,pos2, val1, val2, ret) );