1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2018 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"
37 /****************************************************************************/
39 /****************************************************************************/
48 /* our global datas */
49 extern struct HomeBank
*GLOBALS
;
50 extern struct Preferences
*PREFS
;
54 static void ui_reptime_action_viewlist(GtkAction
*action
, gpointer user_data
);
55 //static void ui_reptime_action_viewcolumn(GtkAction *action, gpointer user_data);
56 static void ui_reptime_action_viewline(GtkAction
*action
, gpointer user_data
);
57 static void ui_reptime_action_detail(GtkAction
*action
, gpointer user_data
);
58 //static void ui_reptime_action_filter(GtkAction *action, gpointer user_data);
59 static void ui_reptime_action_refresh(GtkAction
*action
, gpointer user_data
);
61 static void ui_reptime_list_set_cur(GtkTreeView
*treeview
, guint32 kcur
);
64 static GtkRadioActionEntry radio_entries
[] = {
65 { "List" , ICONNAME_HB_VIEW_LIST
, N_("List") , NULL
, N_("View results as list") , 0 },
66 { "Line" , ICONNAME_HB_VIEW_LINE
, N_("Line") , NULL
, N_("View results as lines") , 1 },
67 // { "Column" , ICONNAME_HB_VIEW_COLUMN, N_("Column") , NULL, N_("View results as column"), 2 },
69 static guint n_radio_entries
= G_N_ELEMENTS (radio_entries
);
71 static GtkActionEntry entries
[] = {
72 // { "Filter" , ICONNAME_HB_FILTER , N_("Filter") , NULL, N_("Edit the filter"), G_CALLBACK (ui_reptime_action_filter) },
73 { "Refresh" , ICONNAME_REFRESH
, N_("Refresh"), NULL
, N_("Refresh results"), G_CALLBACK (ui_reptime_action_refresh
) },
75 // { "Export" , ICONNAME_HB_FILE_EXPORT, N_("Export") , NULL, N_("Export as CSV"), G_CALLBACK (ui_reptime_action_export) },
77 static guint n_entries
= G_N_ELEMENTS (entries
);
79 static GtkToggleActionEntry toggle_entries
[] = {
80 { "Detail", ICONNAME_HB_OPE_SHOW
, /* name, icon-name */
81 N_("Detail"), NULL
, /* label, accelerator */
82 N_("Toggle detail"), /* tooltip */
83 G_CALLBACK (ui_reptime_action_detail
),
84 FALSE
}, /* is_active */
87 static guint n_toggle_entries
= G_N_ELEMENTS (toggle_entries
);
90 static const gchar
*ui_info
=
92 " <toolbar name='ToolBar'>"
93 " <toolitem action='List'/>"
94 " <toolitem action='Line'/>"
95 //" <toolitem action='Column'/>"
97 " <toolitem action='Detail'/>"
99 //" <toolitem action='Filter'/>"
100 " <toolitem action='Refresh'/>"
102 //" <toolitem action='Export'/>"
103 // replaced by a menubutton
108 static void ui_reptime_date_change(GtkWidget
*widget
, gpointer user_data
);
109 static void ui_reptime_range_change(GtkWidget
*widget
, gpointer user_data
);
110 static void ui_reptime_detail(GtkWidget
*widget
, gpointer user_data
);
111 static void ui_reptime_update(GtkWidget
*widget
, gpointer user_data
);
112 static void ui_reptime_compute(GtkWidget
*widget
, gpointer user_data
);
113 static void ui_reptime_sensitive(GtkWidget
*widget
, gpointer user_data
);
114 static void ui_reptime_toggle_detail(GtkWidget
*widget
, gpointer user_data
);
115 static void ui_reptime_toggle_minor(GtkWidget
*widget
, gpointer user_data
);
116 static void ui_reptime_update_daterange(GtkWidget
*widget
, gpointer user_data
);
117 static GtkWidget
*ui_list_reptime_create(void);
119 static gint
ui_list_reptime_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
);
120 static GString
*ui_list_reptime_to_string(GtkTreeView
*treeview
, gboolean clipboard
);
123 gchar
*CYA_TIMESELECT
[] = { N_("Account"), N_("Category"), N_("Payee"), NULL
};
127 gchar
*CYA_VIEWBY
[] = { N_("Day"), N_("Week"), N_("Month"), N_("Quarter"), N_("Year"), NULL
};
129 //extern gchar *CYA_FLT_SELECT[];
131 gchar
*CYA_ABMONTHS
[] =
148 /* action functions -------------------- */
150 static void ui_reptime_action_viewlist(GtkAction
*action
, gpointer user_data
)
152 struct ui_reptime_data
*data
= user_data
;
154 data
->charttype
= CHART_TYPE_NONE
;
155 gtk_notebook_set_current_page(GTK_NOTEBOOK(data
->GR_result
), 0);
156 ui_reptime_sensitive(data
->window
, NULL
);
159 static void ui_reptime_action_viewline(GtkAction
*action
, gpointer user_data
)
161 struct ui_reptime_data
*data
= user_data
;
163 data
->charttype
= CHART_TYPE_LINE
;
164 gtk_notebook_set_current_page(GTK_NOTEBOOK(data
->GR_result
), 1);
165 ui_reptime_sensitive(data
->window
, NULL
);
166 ui_reptime_update(data
->window
, NULL
);
170 /*static void ui_reptime_action_viewcolumn(GtkAction *action, gpointer user_data)
172 struct ui_reptime_data *data = user_data;
174 data->charttype = CHART_TYPE_COL;
175 gtk_notebook_set_current_page(GTK_NOTEBOOK(data->GR_result), 1);
176 ui_reptime_sensitive(data->window, NULL);
177 ui_reptime_update(data->window, NULL);
182 static void ui_reptime_action_mode (GtkRadioAction
*action
, GtkRadioAction
*current
, gpointer user_data
)
186 value
= gtk_radio_action_get_current_value(GTK_RADIO_ACTION(action
));
190 ui_reptime_action_viewlist(GTK_ACTION(action
), user_data
);
193 ui_reptime_action_viewline(GTK_ACTION(action
), user_data
);
199 static void ui_reptime_action_detail(GtkAction
*action
, gpointer user_data
)
201 struct ui_reptime_data
*data
= user_data
;
203 ui_reptime_toggle_detail(data
->window
, NULL
);
207 static void ui_reptime_action_filter(GtkAction *action, gpointer user_data)
209 struct ui_reptime_data *data = user_data;
212 //create_deffilter_window(data->filter, TRUE);
214 if(create_deffilter_window(data->filter, TRUE) != GTK_RESPONSE_REJECT)
215 ui_reptime_compute(data->window, NULL);
219 static void ui_reptime_action_refresh(GtkAction
*action
, gpointer user_data
)
221 struct ui_reptime_data
*data
= user_data
;
223 ui_reptime_compute(data
->window
, NULL
);
226 /*static void ui_reptime_action_export(GtkAction *action, gpointer user_data)
228 struct ui_reptime_data *data = user_data;
230 ui_reptime_export_csv(data->window, NULL);
235 /* ======================== */
240 ** ============================================================================
247 ** return the month list position correponding to the passed date
249 static gint
DateInMonth(guint32 from
, guint32 opedate
)
251 GDate
*date1
, *date2
;
255 // this return sometimes -1, -2 which is wrong
257 date1
= g_date_new_julian(from
);
258 date2
= g_date_new_julian(opedate
);
260 pos
= ((g_date_get_year(date2
) - g_date_get_year(date1
)) * 12) + g_date_get_month(date2
) - g_date_get_month(date1
);
262 //g_print(" from=%d-%d ope=%d-%d => %d\n", g_date_get_month(date1), g_date_get_year(date1), g_date_get_month(date2), g_date_get_year(date2), pos);
270 static gint
DateInQuarter(guint32 from
, guint32 opedate
)
272 GDate
*date1
, *date2
;
276 // this return sometimes -1, -2 which is wrong
278 date1
= g_date_new_julian(from
);
279 date2
= g_date_new_julian(opedate
);
281 pos
= (((g_date_get_year(date2
) - g_date_get_year(date1
)) * 12) + g_date_get_month(date2
) - g_date_get_month(date1
))/3;
283 DB( g_print(" from=%d-%d ope=%d-%d => %d\n", g_date_get_month(date1
), g_date_get_year(date1
), g_date_get_month(date2
), g_date_get_year(date2
), pos
) );
291 ** return the year list position correponding to the passed date
293 static gint
DateInYear(guint32 from
, guint32 opedate
)
296 gint year_from
, year_ope
, pos
;
298 date
= g_date_new_julian(from
);
299 year_from
= g_date_get_year(date
);
300 g_date_set_julian(date
, opedate
);
301 year_ope
= g_date_get_year(date
);
304 pos
= year_ope
- year_from
;
306 //g_print(" from=%d ope=%d => %d\n", year_from, year_ope, pos);
312 static void ui_reptime_date_change(GtkWidget
*widget
, gpointer user_data
)
314 struct ui_reptime_data
*data
;
316 DB( g_print("\n[reptime] date change\n") );
318 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
320 data
->filter
->mindate
= gtk_date_entry_get_date(GTK_DATE_ENTRY(data
->PO_mindate
));
321 data
->filter
->maxdate
= gtk_date_entry_get_date(GTK_DATE_ENTRY(data
->PO_maxdate
));
323 // set min/max date for both widget
324 gtk_date_entry_set_maxdate(GTK_DATE_ENTRY(data
->PO_mindate
), data
->filter
->maxdate
);
325 gtk_date_entry_set_mindate(GTK_DATE_ENTRY(data
->PO_maxdate
), data
->filter
->mindate
);
327 g_signal_handler_block(data
->CY_range
, data
->handler_id
[HID_REPTIME_RANGE
]);
328 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->CY_range
), FLT_RANGE_OTHER
);
329 g_signal_handler_unblock(data
->CY_range
, data
->handler_id
[HID_REPTIME_RANGE
]);
331 ui_reptime_compute(widget
, NULL
);
332 ui_reptime_update_daterange(widget
, NULL
);
337 static void ui_reptime_update_quickdate(GtkWidget
*widget
, gpointer user_data
)
339 struct ui_reptime_data
*data
;
341 DB( g_print("\n[reptime] update quickdate\n") );
343 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
345 g_signal_handler_block(data
->PO_mindate
, data
->handler_id
[HID_REPTIME_MINDATE
]);
346 g_signal_handler_block(data
->PO_maxdate
, data
->handler_id
[HID_REPTIME_MAXDATE
]);
348 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_mindate
), data
->filter
->mindate
);
349 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_maxdate
), data
->filter
->maxdate
);
351 g_signal_handler_unblock(data
->PO_mindate
, data
->handler_id
[HID_REPTIME_MINDATE
]);
352 g_signal_handler_unblock(data
->PO_maxdate
, data
->handler_id
[HID_REPTIME_MAXDATE
]);
357 static void ui_reptime_range_change(GtkWidget
*widget
, gpointer user_data
)
359 struct ui_reptime_data
*data
;
362 DB( g_print("\n[reptime] range change\n") );
364 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
366 range
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_range
));
368 if(range
!= FLT_RANGE_OTHER
)
370 filter_preset_daterange_set(data
->filter
, range
, data
->accnum
);
372 ui_reptime_update_quickdate(widget
, NULL
);
374 ui_reptime_compute(widget
, NULL
);
375 ui_reptime_update_daterange(widget
, NULL
);
380 static void ui_reptime_update_daterange(GtkWidget
*widget
, gpointer user_data
)
382 struct ui_reptime_data
*data
;
385 DB( g_print("\n[reptime] update daterange\n") );
387 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
389 daterange
= filter_daterange_text_get(data
->filter
);
390 gtk_label_set_markup(GTK_LABEL(data
->TX_daterange
), daterange
);
395 static void ui_reptime_detail(GtkWidget
*widget
, gpointer user_data
)
397 struct ui_reptime_data
*data
;
398 guint active
= GPOINTER_TO_INT(user_data
);
399 guint tmpfor
, tmpslice
;
408 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
410 DB( g_print("\n[reptime] detail\n") );
412 tmpfor
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_for
));
413 tmpslice
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_view
));
414 showall
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_all
));
419 case FOR_REPTIME_ACCOUNT
:
420 selkey
= ui_acc_comboboxentry_get_key(GTK_COMBO_BOX(data
->PO_acc
));
422 case FOR_REPTIME_CATEGORY
:
423 selkey
= ui_cat_comboboxentry_get_key(GTK_COMBO_BOX(data
->PO_cat
));
425 case FOR_REPTIME_PAYEE
:
426 selkey
= ui_pay_comboboxentry_get_key(GTK_COMBO_BOX(data
->PO_pay
));
430 //DB( g_print(" for=%d, view by=%d :: key=%d\n", tmpfor, tmpslice, selkey) );
432 //get our min max date
433 from
= data
->filter
->mindate
;
434 //to = data->filter->maxdate;
436 /* clear and detach our model */
437 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_detail
));
438 gtk_list_store_clear (GTK_LIST_STORE(model
));
442 g_object_ref(model
); /* Make sure the model stays with us after the tree view unrefs it */
443 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_detail
), NULL
); /* Detach model from view */
445 /* fill in the model */
446 list
= g_queue_peek_head_link(data
->txn_queue
);
449 Transaction
*ope
= list
->data
;
451 gboolean include
= FALSE
;
453 //DB( g_print(" get %s\n", ope->ope_Word) );
457 case FOR_REPTIME_ACCOUNT
:
458 if( selkey
== ope
->kacc
)
461 case FOR_REPTIME_CATEGORY
:
465 if( ope
->flags
& OF_SPLIT
)
467 guint nbsplit
= da_splits_count(ope
->splits
);
470 for(i
=0;i
<nbsplit
;i
++)
472 split
= ope
->splits
[i
];
473 catentry
= da_cat_get(split
->kcat
);
474 if(catentry
!= NULL
) //#1340142
476 if( selkey
== catentry
->parent
|| selkey
== catentry
->key
)
484 catentry
= da_cat_get(ope
->kcat
);
485 if(catentry
!= NULL
) //#1340142
487 if( selkey
== catentry
->parent
|| selkey
== catentry
->key
)
494 case FOR_REPTIME_PAYEE
:
495 if( selkey
== ope
->kpay
)
500 if( include
== TRUE
|| showall
== TRUE
)
505 case GROUPBY_REPTIME_DAY
:
506 pos
= ope
->date
- from
;
509 case GROUPBY_REPTIME_WEEK
:
510 pos
= (ope
->date
- from
)/7;
513 case GROUPBY_REPTIME_MONTH
:
514 pos
= DateInMonth(from
, ope
->date
);
517 case GROUPBY_REPTIME_QUARTER
:
518 pos
= DateInQuarter(from
, ope
->date
);
521 case GROUPBY_REPTIME_YEAR
:
522 pos
= DateInYear(from
, ope
->date
);
526 DB( g_print("** pos=%d\n", pos
) );
532 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
533 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
534 LST_DSPOPE_DATAS
, ope
,
541 list
= g_list_next(list
);
544 /* Re-attach model to view */
545 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_detail
), model
);
546 g_object_unref(model
);
548 gtk_tree_view_columns_autosize( GTK_TREE_VIEW(data
->LV_detail
) );
554 static void ui_reptime_update(GtkWidget
*widget
, gpointer user_data
)
556 struct ui_reptime_data
*data
;
563 DB( g_print("\n[reptime] update\n") );
565 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
568 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
));
570 tmpfor
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_for
));
571 //tmpslice = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_view));
573 // ensure not exp & inc for piechart
574 page
= gtk_notebook_get_current_page(GTK_NOTEBOOK(data
->GR_result
));
576 DB( g_print(" page %d\n\n", page
) );
577 //DB( g_print(" tmpslice %d\n\n", tmpslice) );
580 //column = LST_REPTIME_POS;
581 //DB( g_print(" sort on column %d\n\n", column) );
582 //gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), column, GTK_SORT_DESCENDING);
584 gtk_chart_show_legend(GTK_CHART(data
->RE_line
), FALSE
, FALSE
);
585 gtk_chart_show_xval(GTK_CHART(data
->RE_line
), TRUE
);
587 ////TRANSLATORS: example 'Expense by Category'
588 title
= g_strdup_printf(_("%s Over Time"), _(CYA_TIMESELECT
[tmpfor
]) );
589 gtk_chart_set_datas(GTK_CHART(data
->RE_line
), model
, LST_REPTIME_AMOUNT
, title
, NULL
);
594 DB( g_print(" change chart type to %d\n", data
->charttype
) );
595 gtk_chart_set_type (GTK_CHART(data
->RE_line
), data
->charttype
);
596 gtk_chart_set_showmono(GTK_CHART(data
->RE_line
), TRUE
);
602 static void ui_reptime_export_result_clipboard(GtkWidget
*widget
, gpointer user_data
)
604 struct ui_reptime_data
*data
;
605 GtkClipboard
*clipboard
;
608 DB( g_print("\n[reptime] export result clipboard\n") );
611 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
613 node
= ui_list_reptime_to_string(GTK_TREE_VIEW(data
->LV_report
), TRUE
);
615 clipboard
= gtk_clipboard_get_default(gdk_display_get_default());
616 gtk_clipboard_set_text(clipboard
, node
->str
, node
->len
);
618 g_string_free(node
, TRUE
);
622 static void ui_reptime_export_result_csv(GtkWidget
*widget
, gpointer user_data
)
624 struct ui_reptime_data
*data
;
625 gchar
*filename
= NULL
;
631 DB( g_print("\n[reptime] export result csv\n") );
634 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
636 tmpfor
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_for
));
637 name
= g_strdup_printf("hb-reptime_%s.csv", CYA_TIMESELECT
[tmpfor
]);
639 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_SAVE
, &filename
, name
) == TRUE
)
641 DB( g_print(" + filename is %s\n", filename
) );
642 io
= g_io_channel_new_file(filename
, "w", NULL
);
645 node
= ui_list_reptime_to_string(GTK_TREE_VIEW(data
->LV_report
), FALSE
);
646 g_io_channel_write_chars(io
, node
->str
, -1, NULL
, NULL
);
647 g_io_channel_unref (io
);
648 g_string_free(node
, TRUE
);
656 static void ui_reptime_export_detail_clipboard(GtkWidget
*widget
, gpointer user_data
)
658 struct ui_reptime_data
*data
;
659 GtkClipboard
*clipboard
;
662 DB( g_print("\n[reptime] export detail clipboard\n") );
665 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
667 node
= list_txn_to_string(GTK_TREE_VIEW(data
->LV_detail
), TRUE
);
669 clipboard
= gtk_clipboard_get_default(gdk_display_get_default());
670 gtk_clipboard_set_text(clipboard
, node
->str
, node
->len
);
672 g_string_free(node
, TRUE
);
676 static void ui_reptime_export_detail_csv(GtkWidget
*widget
, gpointer user_data
)
678 struct ui_reptime_data
*data
;
679 gchar
*filename
= NULL
;
685 DB( g_print("\n[reptime] export detail csv\n") );
688 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
690 tmpfor
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_for
));
691 name
= g_strdup_printf("hb-reptime-detail_%s.csv", CYA_TIMESELECT
[tmpfor
]);
693 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_SAVE
, &filename
, name
) == TRUE
)
695 DB( g_print(" + filename is %s\n", filename
) );
697 io
= g_io_channel_new_file(filename
, "w", NULL
);
700 node
= list_txn_to_string(GTK_TREE_VIEW(data
->LV_detail
), FALSE
);
701 g_io_channel_write_chars(io
, node
->str
, -1, NULL
, NULL
);
703 g_io_channel_unref (io
);
704 g_string_free(node
, TRUE
);
714 static void ui_reptime_update_for(GtkWidget
*widget
, gpointer user_data
)
716 struct ui_reptime_data
*data
;
720 DB( g_print("\n[reptime] update for\n") );
722 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
724 tmpfor
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_for
));
726 visible
= tmpfor
== 0 ? TRUE
: FALSE
;
727 hb_widget_visible(data
->LB_acc
, visible
);
728 hb_widget_visible(data
->PO_acc
, visible
);
730 visible
= tmpfor
== 1 ? TRUE
: FALSE
;
731 hb_widget_visible(data
->LB_cat
, visible
);
732 hb_widget_visible(data
->PO_cat
, visible
);
734 visible
= tmpfor
== 2 ? TRUE
: FALSE
;
735 hb_widget_visible(data
->LB_pay
, visible
);
736 hb_widget_visible(data
->PO_pay
, visible
);
742 static void ui_reptime_for(GtkWidget
*widget
, gpointer user_data
)
744 struct ui_reptime_data
*data
;
746 DB( g_print("\n[reptime] for\n") );
748 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
750 ui_reptime_update_for(widget
, data
);
752 ui_reptime_compute(widget
, data
);
756 static void ui_reptime_compute(GtkWidget
*widget
, gpointer user_data
)
758 struct ui_reptime_data
*data
;
759 gint tmpfor
, tmpslice
;
764 gdouble cumulation
, average
;
771 GDate
*date1
, *date2
;
775 DB( g_print("\n[reptime] compute\n") );
777 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
779 tmpfor
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_for
));
780 tmpslice
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_view
));
781 cumul
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_cumul
));
782 showall
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_all
));
789 case FOR_REPTIME_ACCOUNT
:
790 selkey
= ui_acc_comboboxentry_get_key(GTK_COMBO_BOX(data
->PO_acc
));
792 data
->accnum
= selkey
;
794 case FOR_REPTIME_CATEGORY
:
795 selkey
= ui_cat_comboboxentry_get_key(GTK_COMBO_BOX(data
->PO_cat
));
797 case FOR_REPTIME_PAYEE
:
798 selkey
= ui_pay_comboboxentry_get_key(GTK_COMBO_BOX(data
->PO_pay
));
802 DB( g_print(" for=%d, view by=%d :: key=%d\n", tmpfor
, tmpslice
, selkey
) );
805 //#1715532 5.0.5: no... but only showall
808 filter_preset_daterange_set(data
->filter
, data
->filter
->range
, data
->accnum
);
809 ui_reptime_update_quickdate(widget
, NULL
);
812 //get our min max date
813 from
= data
->filter
->mindate
;
814 to
= data
->filter
->maxdate
;
815 if(to
< from
) return;
817 g_queue_free (data
->txn_queue
);
818 data
->txn_queue
= hbfile_transaction_get_partial(data
->filter
->mindate
, data
->filter
->maxdate
);
821 /* count number or results */
824 case GROUPBY_REPTIME_DAY
:
825 n_result
= 1 + (to
- from
);
827 case GROUPBY_REPTIME_WEEK
:
828 n_result
= 1 + ((to
- from
) / 7);
830 case GROUPBY_REPTIME_MONTH
:
831 date1
= g_date_new_julian(from
);
832 date2
= g_date_new_julian(to
);
833 n_result
= 1 + ((g_date_get_year(date2
) - g_date_get_year(date1
)) * 12) + g_date_get_month(date2
) - g_date_get_month(date1
);
837 case GROUPBY_REPTIME_QUARTER
:
838 date1
= g_date_new_julian(from
);
839 date2
= g_date_new_julian(to
);
840 n_result
= 1 + (((g_date_get_year(date2
) - g_date_get_year(date1
)) * 12) + g_date_get_month(date2
) - g_date_get_month(date1
))/3;
844 case GROUPBY_REPTIME_YEAR
:
845 date1
= g_date_new_julian(from
);
846 date2
= g_date_new_julian(to
);
847 n_result
= 1 + g_date_get_year(date2
) - g_date_get_year(date1
);
855 DB( g_print(" %s :: n_result=%d\n", CYA_TIMESELECT
[tmpfor
], n_result
) );
857 /* allocate some memory */
859 tmp_amount
= g_malloc0((n_result
+2) * sizeof(gdouble
));
866 kcur
= GLOBALS
->kcur
;
867 if( (tmpfor
== FOR_REPTIME_ACCOUNT
) && (showall
== FALSE
) )
869 Account
*acc
= da_acc_get(selkey
);
877 ui_reptime_list_set_cur(GTK_TREE_VIEW(data
->LV_report
), kcur
);
878 gtk_chart_set_currency(GTK_CHART(data
->RE_line
), kcur
);
880 /* compute the results */
881 list
= g_queue_peek_head_link(data
->txn_queue
);
884 Transaction
*ope
= list
->data
;
885 gboolean include
= FALSE
;
888 DB( g_print("** testing '%s', cat=%d==> %d\n", ope
->memo
, ope
->kcat
, filter_test(data
->filter
, ope
)) );
890 // add usage of payee or category
893 case FOR_REPTIME_ACCOUNT
:
894 if( selkey
== ope
->kacc
)
897 case FOR_REPTIME_CATEGORY
:
901 if( ope
->flags
& OF_SPLIT
)
903 guint nbsplit
= da_splits_count(ope
->splits
);
906 for(i
=0;i
<nbsplit
;i
++)
908 split
= ope
->splits
[i
];
909 catentry
= da_cat_get(split
->kcat
);
910 if(catentry
!= NULL
) //#1340142
912 if( selkey
== catentry
->parent
|| selkey
== catentry
->key
)
919 catentry
= da_cat_get(ope
->kcat
);
920 if(catentry
!= NULL
) //#1340142
922 if( selkey
== catentry
->parent
|| selkey
== catentry
->key
)
929 case FOR_REPTIME_PAYEE
:
930 if( selkey
== ope
->kpay
)
935 if( include
== TRUE
|| showall
== TRUE
)
942 case GROUPBY_REPTIME_DAY
:
943 pos
= ope
->date
- from
;
946 case GROUPBY_REPTIME_WEEK
:
947 pos
= (ope
->date
- from
)/7;
950 case GROUPBY_REPTIME_MONTH
:
951 pos
= DateInMonth(from
, ope
->date
);
954 case GROUPBY_REPTIME_QUARTER
:
955 pos
= DateInQuarter(from
, ope
->date
);
958 case GROUPBY_REPTIME_YEAR
:
959 pos
= DateInYear(from
, ope
->date
);
965 if( (tmpfor
== FOR_REPTIME_CATEGORY
) && (ope
->flags
& OF_SPLIT
) )
967 guint nbsplit
= da_splits_count(ope
->splits
);
971 for(i
=0;i
<nbsplit
;i
++)
973 split
= ope
->splits
[i
];
974 catentry
= da_cat_get(split
->kcat
);
975 if(catentry
!= NULL
) //#1340142
977 //#1678230 miss showall
978 if( showall
== TRUE
|| selkey
== catentry
->parent
|| selkey
== catentry
->key
)
979 trn_amount
+= split
->amount
;
984 trn_amount
= ope
->amount
;
986 trn_amount
= hb_amount_base(trn_amount
, ope
->kcur
);
988 DB( g_print("** pos=%d : add of %.2f\n", pos
, trn_amount
) );
990 tmp_amount
[pos
] += trn_amount
;
994 list
= g_list_next(list
);
997 /* clear and detach our model */
998 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
));
999 gtk_list_store_clear (GTK_LIST_STORE(model
));
1000 g_object_ref(model
); /* Make sure the model stays with us after the tree view unrefs it */
1001 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_report
), NULL
); /* Detach model from view */
1005 /* insert into the treeview */
1006 for(i
=0, id
=0; i
<n_result
; i
++)
1008 gchar
*name
, *fullcatname
;
1017 DB( g_print("try to insert item %d\n", i
) );
1019 /* get the result name */
1022 case GROUPBY_REPTIME_DAY
:
1023 date
= g_date_new_julian (from
+ i
);
1024 g_date_strftime (buffer
, 63, PREFS
->date_format
, date
);
1029 case GROUPBY_REPTIME_WEEK
:
1030 date
= g_date_new_julian(from
);
1031 g_date_add_days(date
, i
*7);
1032 //g_snprintf(buffer, 63, "%d-%02d", g_date_get_year(date), g_date_get_month(date));
1033 g_snprintf(buffer
, 63, "%d-%d", g_date_get_year(date
), g_date_get_monday_week_of_year(date
));
1038 case GROUPBY_REPTIME_MONTH
:
1039 date
= g_date_new_julian(from
);
1040 g_date_add_months(date
, i
);
1041 //g_snprintf(buffer, 63, "%d-%02d", g_date_get_year(date), g_date_get_month(date));
1042 g_snprintf(buffer
, 63, "%d-%s", g_date_get_year(date
), _(CYA_ABMONTHS
[g_date_get_month(date
)]));
1047 case GROUPBY_REPTIME_QUARTER
:
1048 date
= g_date_new_julian(from
);
1049 g_date_add_months(date
, i
*3);
1050 //g_snprintf(buffer, 63, "%d-%02d", g_date_get_year(date), g_date_get_month(date));
1051 g_snprintf(buffer
, 63, "%d-%d", g_date_get_year(date
), ((g_date_get_month(date
)-1)/3)+1);
1056 case GROUPBY_REPTIME_YEAR
:
1057 date
= g_date_new_julian(from
);
1058 g_date_add_years(date
, i
);
1059 g_snprintf(buffer
, 63, "%d", g_date_get_year(date
));
1065 cumulation
+= tmp_amount
[i
];
1066 value
= cumul
== TRUE
? cumulation
: tmp_amount
[i
];
1069 //DB( g_print(" inserting %2d, '%s', %9.2f\n", i, name, value) );
1071 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
1072 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
1073 LST_REPTIME_POS
, id
++,
1075 LST_REPTIME_TITLE
, name
,
1076 LST_REPTIME_AMOUNT
, value
,
1079 g_free(fullcatname
);
1082 /* update column 0 title */
1083 GtkTreeViewColumn
*column
= gtk_tree_view_get_column( GTK_TREE_VIEW(data
->LV_report
), 0);
1084 gtk_tree_view_column_set_title(column
, _(CYA_VIEWBY
[tmpslice
]));
1086 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_report
));
1088 /* Re-attach model to view */
1089 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_report
), model
);
1090 g_object_unref(model
);
1097 average
= cumulation
/ n_result
;
1099 hb_strfmon(buf
, 127, average
, kcur
, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_minor
)) );
1101 ////TRANSLATORS: count of transaction in balancedrawn / count of total transaction under abalancedrawn amount threshold
1102 info
= g_strdup_printf(_("Average: %s"), buf
);
1103 gtk_label_set_text(GTK_LABEL(data
->TX_info
), info
);
1108 /* free our memory */
1111 ui_reptime_update(widget
, user_data
);
1120 ** update sensitivity
1122 static void ui_reptime_sensitive(GtkWidget
*widget
, gpointer user_data
)
1124 struct ui_reptime_data
*data
;
1126 gboolean visible
, sensitive
;
1129 DB( g_print("\n[reptime] sensitive\n") );
1131 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1133 page
= gtk_notebook_get_current_page(GTK_NOTEBOOK(data
->GR_result
));
1135 visible
= page
== 0 ? TRUE
: FALSE
;
1136 action
= gtk_ui_manager_get_action(data
->ui
, "/ToolBar/Detail");
1137 gtk_action_set_visible (action
, visible
);
1138 //action = gtk_ui_manager_get_action(data->ui, "/ToolBar/Export");
1139 //gtk_action_set_visible (action, visible);
1140 //sensitive = gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_report)), NULL, NULL);
1141 //gtk_action_set_sensitive(action, sensitive);
1142 hb_widget_visible (data
->BT_export
, visible
);
1144 visible
= page
== 0 ? FALSE
: TRUE
;
1145 hb_widget_visible(data
->LB_zoomx
, visible
);
1146 hb_widget_visible(data
->RG_zoomx
, visible
);
1148 sensitive
= gtk_tree_model_iter_n_children(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_detail
)), NULL
) > 0 ? TRUE
: FALSE
;
1149 gtk_widget_set_sensitive(data
->MI_detailtoclip
, sensitive
);
1150 gtk_widget_set_sensitive(data
->MI_detailtocsv
, sensitive
);
1155 static void ui_reptime_detail_onRowActivated (GtkTreeView
*treeview
,
1157 GtkTreeViewColumn
*col
,
1160 struct ui_reptime_data
*data
;
1161 Transaction
*active_txn
;
1164 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview
), GTK_TYPE_WINDOW
)), "inst_data");
1166 DB( g_print ("\n[reptime] A detail row has been double-clicked!\n") );
1168 active_txn
= list_txn_get_active_transaction(GTK_TREE_VIEW(data
->LV_detail
));
1171 Transaction
*old_txn
, *new_txn
;
1173 old_txn
= da_transaction_clone (active_txn
);
1174 new_txn
= active_txn
;
1175 result
= deftransaction_external_edit(GTK_WINDOW(data
->window
), old_txn
, new_txn
);
1177 if(result
== GTK_RESPONSE_ACCEPT
)
1180 GLOBALS
->changes_count
++;
1181 ui_reptime_compute(data
->window
, NULL
);
1184 da_transaction_free (old_txn
);
1189 static void ui_reptime_update_detail(GtkWidget
*widget
, gpointer user_data
)
1191 struct ui_reptime_data
*data
;
1193 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1197 GtkTreeSelection
*treeselection
;
1198 GtkTreeModel
*model
;
1202 treeselection
= gtk_tree_view_get_selection (GTK_TREE_VIEW(data
->LV_report
));
1204 if (gtk_tree_selection_get_selected(treeselection
, &model
, &iter
))
1206 gtk_tree_model_get(model
, &iter
, LST_REPTIME_KEY
, &key
, -1);
1208 DB( g_print(" - active is %d\n", key
) );
1210 ui_reptime_detail(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), GINT_TO_POINTER(key
));
1215 gtk_widget_show(data
->GR_detail
);
1218 gtk_widget_hide(data
->GR_detail
);
1224 static void ui_reptime_toggle_detail(GtkWidget
*widget
, gpointer user_data
)
1226 struct ui_reptime_data
*data
;
1228 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1232 DB( g_print("(stats) toggledetail to %d\n", data
->detail
) );
1234 ui_reptime_update_detail(widget
, user_data
);
1238 static void ui_reptime_zoomx_callback(GtkWidget
*widget
, gpointer user_data
)
1240 struct ui_reptime_data
*data
;
1243 DB( g_print("\n[reptime] zoomx\n") );
1245 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1247 value
= gtk_range_get_value(GTK_RANGE(data
->RG_zoomx
));
1249 DB( g_print(" + scale is %.2f\n", value
) );
1251 gtk_chart_set_barw(GTK_CHART(data
->RE_line
), value
);
1257 static void ui_reptime_toggle_minor(GtkWidget
*widget
, gpointer user_data
)
1259 struct ui_reptime_data
*data
;
1261 DB( g_print("\n[reptime] toggle\n") );
1263 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1265 GLOBALS
->minor
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_minor
));
1267 //hbfile_update(data->LV_acc, (gpointer)4);
1268 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_report
));
1270 gtk_chart_show_minor(GTK_CHART(data
->RE_line
), GLOBALS
->minor
);
1275 static void ui_reptime_toggle_showall(GtkWidget
*widget
, gpointer user_data
)
1277 struct ui_reptime_data
*data
;
1280 DB( g_print("\n[reptime] toggle\n") );
1282 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1284 showall
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_all
));
1286 gtk_widget_set_sensitive(GTK_WIDGET(data
->PO_acc
), showall
^1);
1287 gtk_widget_set_sensitive(GTK_WIDGET(data
->PO_cat
), showall
^1);
1288 gtk_widget_set_sensitive(GTK_WIDGET(data
->PO_pay
), showall
^1);
1290 ui_reptime_compute(widget
, data
);
1299 static void ui_reptime_setup(struct ui_reptime_data
*data
, guint32 accnum
)
1301 DB( g_print("\n[reptime] setup\n") );
1303 data
->txn_queue
= g_queue_new ();
1305 data
->filter
= da_filter_malloc();
1306 filter_default_all_set(data
->filter
);
1310 /* 3.4 : make int transfer out of stats */
1311 data
->filter
->option
[FILTER_PAYMODE
] = 1;
1312 data
->filter
->paymode
[PAYMODE_INTXFER
] = FALSE
;
1314 filter_preset_daterange_set(data
->filter
, PREFS
->date_range_rep
, data
->accnum
);
1316 g_signal_handler_block(data
->PO_mindate
, data
->handler_id
[HID_REPTIME_MINDATE
]);
1317 g_signal_handler_block(data
->PO_maxdate
, data
->handler_id
[HID_REPTIME_MAXDATE
]);
1319 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_mindate
), data
->filter
->mindate
);
1320 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_maxdate
), data
->filter
->maxdate
);
1322 g_signal_handler_unblock(data
->PO_mindate
, data
->handler_id
[HID_REPTIME_MINDATE
]);
1323 g_signal_handler_unblock(data
->PO_maxdate
, data
->handler_id
[HID_REPTIME_MAXDATE
]);
1326 DB( g_print(" populate\n") );
1327 ui_acc_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_acc
), GLOBALS
->h_acc
, ACC_LST_INSERT_REPORT
);
1329 ui_acc_comboboxentry_set_active(GTK_COMBO_BOX(data
->PO_acc
), accnum
);
1331 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->PO_acc
), 0);
1333 ui_pay_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_pay
), GLOBALS
->h_pay
);
1334 ui_pay_comboboxentry_set_active(GTK_COMBO_BOX(data
->PO_pay
), 0);
1336 ui_cat_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_cat
), GLOBALS
->h_cat
);
1337 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->PO_cat
), 0);
1339 DB( g_print(" all ok\n") );
1345 static void ui_reptime_selection(GtkTreeSelection
*treeselection
, gpointer user_data
)
1347 GtkTreeModel
*model
;
1351 DB( g_print("\n[reptime] selection\n") );
1353 if (gtk_tree_selection_get_selected(treeselection
, &model
, &iter
))
1355 gtk_tree_model_get(model
, &iter
, LST_REPTIME_KEY
, &key
, -1);
1359 DB( g_print(" - active is %d\n", key
) );
1361 ui_reptime_detail(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), GINT_TO_POINTER(key
));
1362 ui_reptime_sensitive(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), NULL
);
1369 static gboolean
ui_reptime_dispose(GtkWidget
*widget
, GdkEvent
*event
, gpointer user_data
)
1371 struct ui_reptime_data
*data
= user_data
;
1372 struct WinGeometry
*wg
;
1374 DB( g_print("\n[reptime] dispose\n") );
1376 g_queue_free (data
->txn_queue
);
1378 da_filter_free(data
->filter
);
1382 //store position and size
1383 wg
= &PREFS
->tme_wg
;
1384 gtk_window_get_position(GTK_WINDOW(widget
), &wg
->l
, &wg
->t
);
1385 gtk_window_get_size(GTK_WINDOW(widget
), &wg
->w
, &wg
->h
);
1387 DB( g_print(" window: l=%d, t=%d, w=%d, h=%d\n", wg
->l
, wg
->t
, wg
->w
, wg
->h
) );
1391 //enable define windows
1392 GLOBALS
->define_off
--;
1393 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
));
1398 // the window creation
1399 GtkWidget
*ui_reptime_window_new(guint32 accnum
)
1401 struct ui_reptime_data
*data
;
1402 struct WinGeometry
*wg
;
1403 GtkWidget
*window
, *mainvbox
, *hbox
, *vbox
, *notebook
, *treeview
;
1404 GtkWidget
*label
, *widget
, *table
;
1407 GtkActionGroup
*actions
;
1408 //GtkAction *action;
1409 GError
*error
= NULL
;
1411 data
= g_malloc0(sizeof(struct ui_reptime_data
));
1412 if(!data
) return NULL
;
1414 DB( g_print("\n[reptime] new\n") );
1417 //disable define windows
1418 GLOBALS
->define_off
++;
1419 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
));
1421 /* create window, etc */
1422 window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
1423 data
->window
= window
;
1425 //store our window private data
1426 g_object_set_data(G_OBJECT(window
), "inst_data", (gpointer
)data
);
1427 DB( g_print(" - new window=%p, inst_data=%p\n", window
, data
) );
1430 gtk_window_set_title (GTK_WINDOW (window
), _("Trend Time Report"));
1432 //set the window icon
1433 gtk_window_set_icon_name(GTK_WINDOW (window
), ICONNAME_HB_REP_TIME
);
1437 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
1438 gtk_container_add (GTK_CONTAINER (window
), mainvbox
);
1440 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
1441 gtk_box_pack_start (GTK_BOX (mainvbox
), hbox
, TRUE
, TRUE
, 0);
1444 table
= gtk_grid_new ();
1445 gtk_widget_set_hexpand (GTK_WIDGET(table
), FALSE
);
1446 gtk_box_pack_start (GTK_BOX (hbox
), table
, FALSE
, FALSE
, 0);
1448 gtk_container_set_border_width (GTK_CONTAINER (table
), SPACING_SMALL
);
1449 gtk_grid_set_row_spacing (GTK_GRID (table
), SPACING_SMALL
);
1450 gtk_grid_set_column_spacing (GTK_GRID (table
), SPACING_MEDIUM
);
1453 label
= make_label_group(_("Display"));
1454 gtk_grid_attach (GTK_GRID (table
), label
, 0, row
, 3, 1);
1457 label
= make_label_widget(_("_For:"));
1458 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1459 widget
= make_cycle(label
, CYA_TIMESELECT
);
1460 data
->CY_for
= widget
;
1461 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1464 label
= make_label_widget(_("A_ccount:"));
1465 data
->LB_acc
= label
;
1466 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1467 widget
= ui_acc_comboboxentry_new(label
);
1468 data
->PO_acc
= widget
;
1469 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1472 label
= make_label_widget(_("_Category:"));
1473 data
->LB_cat
= label
;
1474 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1475 widget
= ui_cat_comboboxentry_new(label
);
1476 data
->PO_cat
= widget
;
1477 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1480 label
= make_label_widget(_("_Payee:"));
1481 data
->LB_pay
= label
;
1482 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1483 widget
= ui_pay_comboboxentry_new(label
);
1484 data
->PO_pay
= widget
;
1485 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1488 widget
= gtk_check_button_new_with_mnemonic (_("Select _all"));
1489 data
->CM_all
= widget
;
1490 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1493 widget
= gtk_check_button_new_with_mnemonic (_("_Cumulate"));
1494 data
->CM_cumul
= widget
;
1495 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1498 label
= make_label_widget(_("_View by:"));
1499 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1500 widget
= make_cycle(label
, CYA_VIEWBY
);
1501 data
->CY_view
= widget
;
1502 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1505 widget
= gtk_check_button_new_with_mnemonic (_("Euro _minor"));
1506 data
->CM_minor
= widget
;
1507 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1510 label
= make_label_widget(_("_Zoom X:"));
1511 data
->LB_zoomx
= label
;
1512 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1513 widget
= make_scale(label
);
1514 data
->RG_zoomx
= widget
;
1515 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
1519 widget
= gtk_separator_new(GTK_ORIENTATION_HORIZONTAL
);
1520 gtk_grid_attach (GTK_GRID (table
), widget
, 0, row
, 3, 1);
1523 label
= make_label_group(_("Date filter"));
1524 gtk_grid_attach (GTK_GRID (table
), label
, 0, row
, 3, 1);
1527 label
= make_label_widget(_("_Range:"));
1528 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1529 data
->CY_range
= make_daterange(label
, FALSE
);
1530 gtk_grid_attach (GTK_GRID (table
), data
->CY_range
, 2, row
, 1, 1);
1533 label
= make_label_widget(_("_From:"));
1534 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1535 data
->PO_mindate
= gtk_date_entry_new();
1536 gtk_grid_attach (GTK_GRID (table
), data
->PO_mindate
, 2, row
, 1, 1);
1539 label
= make_label_widget(_("_To:"));
1540 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
1541 data
->PO_maxdate
= gtk_date_entry_new();
1542 gtk_grid_attach (GTK_GRID (table
), data
->PO_maxdate
, 2, row
, 1, 1);
1545 //part: info + report
1546 vbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
1547 gtk_box_pack_start (GTK_BOX (hbox
), vbox
, TRUE
, TRUE
, 0);
1550 actions
= gtk_action_group_new ("default");
1553 gtk_action_group_set_translation_domain(actions
, GETTEXT_PACKAGE
);
1555 // data to action callbacks is set here (data)
1556 gtk_action_group_add_radio_actions (actions
, radio_entries
, n_radio_entries
, 0, G_CALLBACK(ui_reptime_action_mode
), data
);
1558 gtk_action_group_add_actions (actions
, entries
, n_entries
, data
);
1560 gtk_action_group_add_toggle_actions (actions
,
1561 toggle_entries
, n_toggle_entries
,
1565 /* set which action should have priority in the toolbar */
1566 //action = gtk_action_group_get_action(actions, "List");
1567 //g_object_set(action, "is_important", TRUE, NULL);
1569 //action = gtk_action_group_get_action(actions, "Line");
1570 //g_object_set(action, "is_important", TRUE, NULL);
1572 /*action = gtk_action_group_get_action(actions, "Column");
1573 g_object_set(action, "is_important", TRUE, NULL);*/
1575 //action = gtk_action_group_get_action(actions, "Detail");
1576 //g_object_set(action, "is_important", TRUE, NULL);
1578 //action = gtk_action_group_get_action(actions, "Refresh");
1579 //g_object_set(action, "is_important", TRUE, NULL);
1582 ui
= gtk_ui_manager_new ();
1583 gtk_ui_manager_insert_action_group (ui
, actions
, 0);
1584 gtk_window_add_accel_group (GTK_WINDOW (window
), gtk_ui_manager_get_accel_group (ui
));
1586 if (!gtk_ui_manager_add_ui_from_string (ui
, ui_info
, -1, &error
))
1588 g_message ("building UI failed: %s", error
->message
);
1589 g_error_free (error
);
1593 data
->actions
= actions
;
1596 data
->TB_bar
= gtk_ui_manager_get_widget (ui
, "/ToolBar");
1597 gtk_box_pack_start (GTK_BOX (vbox
), data
->TB_bar
, FALSE
, FALSE
, 0);
1599 //add export menu button
1600 GtkToolItem
*toolitem
;
1601 GtkWidget
*menu
, *menuitem
, *image
;
1603 menu
= gtk_menu_new ();
1604 //gtk_widget_set_halign (menu, GTK_ALIGN_END);
1606 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Result to clipboard"));
1607 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1608 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_reptime_export_result_clipboard
), data
);
1610 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Result to CSV"));
1611 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1612 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_reptime_export_result_csv
), data
);
1614 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Detail to clipboard"));
1615 data
->MI_detailtoclip
= menuitem
;
1616 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1617 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_reptime_export_detail_clipboard
), data
);
1619 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Detail to CSV"));
1620 data
->MI_detailtocsv
= menuitem
;
1621 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1622 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_reptime_export_detail_csv
), data
);
1624 gtk_widget_show_all (menu
);
1626 widget
= gtk_menu_button_new();
1627 data
->BT_export
= widget
;
1628 gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(widget
)), GTK_STYLE_CLASS_FLAT
);
1630 //gtk_menu_button_set_direction (GTK_MENU_BUTTON(widget), GTK_ARROW_DOWN);
1631 //gtk_widget_set_halign (widget, GTK_ALIGN_END);
1632 image
= gtk_image_new_from_icon_name (ICONNAME_HB_FILE_EXPORT
, GTK_ICON_SIZE_LARGE_TOOLBAR
);
1633 g_object_set (widget
, "image", image
, "popup", GTK_MENU(menu
), NULL
);
1635 toolitem
= gtk_tool_item_new();
1636 gtk_container_add (GTK_CONTAINER(toolitem
), widget
);
1637 gtk_toolbar_insert(GTK_TOOLBAR(data
->TB_bar
), GTK_TOOL_ITEM(toolitem
), -1);
1640 hbox
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, SPACING_SMALL
);
1641 gtk_container_set_border_width (GTK_CONTAINER(hbox
), SPACING_SMALL
);
1642 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
1644 label
= gtk_label_new(NULL
);
1645 data
->TX_info
= label
;
1646 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
1648 widget
= make_label(NULL
, 0.5, 0.5);
1649 gimp_label_set_attributes (GTK_LABEL (widget
), PANGO_ATTR_SCALE
, PANGO_SCALE_SMALL
, -1);
1650 data
->TX_daterange
= widget
;
1651 gtk_box_pack_start (GTK_BOX (hbox
), widget
, TRUE
, TRUE
, 0);
1655 notebook
= gtk_notebook_new();
1656 data
->GR_result
= notebook
;
1657 gtk_widget_show(notebook
);
1658 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook
), FALSE
);
1659 gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook
), FALSE
);
1661 gtk_box_pack_start (GTK_BOX (vbox
), notebook
, TRUE
, TRUE
, 0);
1664 vbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
1665 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), vbox
, NULL
);
1667 widget
= gtk_scrolled_window_new (NULL
, NULL
);
1668 //gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW (widget), GTK_CORNER_TOP_RIGHT);
1669 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget
), GTK_SHADOW_ETCHED_IN
);
1670 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (widget
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1671 treeview
= ui_list_reptime_create();
1672 data
->LV_report
= treeview
;
1673 gtk_container_add (GTK_CONTAINER(widget
), treeview
);
1674 gtk_box_pack_start (GTK_BOX (vbox
), widget
, TRUE
, TRUE
, 0);
1677 widget
= gtk_scrolled_window_new (NULL
, NULL
);
1678 data
->GR_detail
= widget
;
1679 //gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW (widget), GTK_CORNER_TOP_RIGHT);
1680 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget
), GTK_SHADOW_ETCHED_IN
);
1681 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (widget
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1682 treeview
= create_list_transaction(LIST_TXN_TYPE_DETAIL
, PREFS
->lst_ope_columns
);
1683 data
->LV_detail
= treeview
;
1684 gtk_container_add (GTK_CONTAINER(widget
), treeview
);
1686 gtk_box_pack_start (GTK_BOX (vbox
), widget
, TRUE
, TRUE
, 0);
1690 widget
= gtk_chart_new(CHART_TYPE_LINE
);
1691 data
->RE_line
= widget
;
1692 //gtk_chart_set_minor_prefs(GTK_CHART(widget), PREFS->euro_value, PREFS->minor_cur.suffix_symbol);
1693 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), widget
, NULL
);
1695 //todo:should move this
1696 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_minor
), GLOBALS
->minor
);
1698 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->CY_view
), 1);
1700 /* attach our minor to treeview */
1701 g_object_set_data(G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
))), "minor", (gpointer
)data
->CM_minor
);
1702 g_object_set_data(G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_detail
))), "minor", (gpointer
)data
->CM_minor
);
1706 /* signal connect */
1707 g_signal_connect (window
, "delete-event", G_CALLBACK (ui_reptime_dispose
), (gpointer
)data
);
1709 g_signal_connect (data
->CM_cumul
, "toggled", G_CALLBACK (ui_reptime_compute
), NULL
);
1711 g_signal_connect (data
->CM_minor
, "toggled", G_CALLBACK (ui_reptime_toggle_minor
), NULL
);
1713 data
->handler_id
[HID_REPTIME_MINDATE
] = g_signal_connect (data
->PO_mindate
, "changed", G_CALLBACK (ui_reptime_date_change
), (gpointer
)data
);
1714 data
->handler_id
[HID_REPTIME_MAXDATE
] = g_signal_connect (data
->PO_maxdate
, "changed", G_CALLBACK (ui_reptime_date_change
), (gpointer
)data
);
1716 data
->handler_id
[HID_REPTIME_RANGE
] = g_signal_connect (data
->CY_range
, "changed", G_CALLBACK (ui_reptime_range_change
), NULL
);
1718 g_signal_connect (data
->CY_for
, "changed", G_CALLBACK (ui_reptime_for
), (gpointer
)data
);
1719 data
->handler_id
[HID_REPTIME_VIEW
] = g_signal_connect (data
->CY_view
, "changed", G_CALLBACK (ui_reptime_compute
), (gpointer
)data
);
1721 //setup, init and show window
1722 ui_reptime_setup(data
, accnum
);
1724 g_signal_connect (data
->CM_all
, "toggled", G_CALLBACK (ui_reptime_toggle_showall
), NULL
);
1725 g_signal_connect (data
->PO_acc
, "changed", G_CALLBACK (ui_reptime_compute
), NULL
);
1726 g_signal_connect (data
->PO_cat
, "changed", G_CALLBACK (ui_reptime_compute
), NULL
);
1727 g_signal_connect (data
->PO_pay
, "changed", G_CALLBACK (ui_reptime_compute
), NULL
);
1729 g_signal_connect (data
->RG_zoomx
, "value-changed", G_CALLBACK (ui_reptime_zoomx_callback
), NULL
);
1732 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_report
)), "changed", G_CALLBACK (ui_reptime_selection
), NULL
);
1734 g_signal_connect (GTK_TREE_VIEW(data
->LV_detail
), "row-activated", G_CALLBACK (ui_reptime_detail_onRowActivated
), NULL
);
1738 if(PREFS
->toolbar_style
== 0)
1739 gtk_toolbar_unset_style(GTK_TOOLBAR(data
->TB_bar
));
1741 gtk_toolbar_set_style(GTK_TOOLBAR(data
->TB_bar
), PREFS
->toolbar_style
-1);
1743 //setup, init and show window
1744 wg
= &PREFS
->tme_wg
;
1745 gtk_window_move(GTK_WINDOW(window
), wg
->l
, wg
->t
);
1746 gtk_window_resize(GTK_WINDOW(window
), wg
->w
, wg
->h
);
1748 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->CY_view
), GROUPBY_REPTIME_MONTH
);
1750 gtk_widget_show_all (window
);
1753 if( PREFS
->euro_active
)
1754 gtk_widget_show(data
->CM_minor
);
1756 gtk_widget_hide(data
->CM_minor
);
1758 ui_reptime_update_for(window
, data
);
1759 //gtk_widget_hide(data->GR_detail);
1763 ui_reptime_sensitive(window
, NULL
);
1764 ui_reptime_update_detail(window
, NULL
);
1766 DB( g_print("range: %d\n", PREFS
->date_range_rep
) );
1768 if( PREFS
->date_range_rep
!= 0)
1769 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->CY_range
), PREFS
->date_range_rep
);
1771 ui_reptime_compute(window
, NULL
);
1777 ** ============================================================================
1781 static GString
*ui_list_reptime_to_string(GtkTreeView
*treeview
, gboolean clipboard
)
1784 GtkTreeModel
*model
;
1787 const gchar
*format
;
1789 node
= g_string_new(NULL
);
1792 format
= (clipboard
== TRUE
) ? "%s\t%s\n" : "%s;%s\n";
1793 g_string_append_printf(node
, format
, _("Time slice"), _("Amount"));
1795 model
= gtk_tree_view_get_model(treeview
);
1796 valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model
), &iter
);
1802 gtk_tree_model_get (model
, &iter
,
1803 //LST_REPTIME_KEY, i,
1804 LST_REPTIME_TITLE
, &name
,
1805 LST_REPTIME_AMOUNT
, &amount
,
1808 format
= (clipboard
== TRUE
) ? "%s\t%.2f\n" : "%s;%.2f\n";
1809 g_string_append_printf(node
, format
, name
, amount
);
1814 valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &iter
);
1817 //DB( g_print("text is:\n%s", node->str) );
1823 static void ui_reptime_amount_cell_data_function (GtkTreeViewColumn
*col
,
1824 GtkCellRenderer
*renderer
,
1825 GtkTreeModel
*model
,
1831 gchar buf
[G_ASCII_DTOSTR_BUF_SIZE
];
1832 guint32 kcur
= GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(gtk_tree_view_column_get_tree_view(col
)), "kcur_data"));
1834 gtk_tree_model_get(model
, iter
, GPOINTER_TO_INT(user_data
), &value
, -1);
1838 hb_strfmon(buf
, G_ASCII_DTOSTR_BUF_SIZE
-1, value
, kcur
, GLOBALS
->minor
);
1840 color
= get_normal_color_amount(value
);
1842 g_object_set(renderer
,
1843 "foreground", color
,
1848 g_object_set(renderer
, "text", "", NULL
);
1853 static GtkTreeViewColumn
*amount_list_ui_reptime_column(gchar
*name
, gint id
)
1855 GtkTreeViewColumn
*column
;
1856 GtkCellRenderer
*renderer
;
1858 column
= gtk_tree_view_column_new();
1859 gtk_tree_view_column_set_title(column
, name
);
1860 renderer
= gtk_cell_renderer_text_new ();
1861 g_object_set(renderer
, "xalign", 1.0, NULL
);
1862 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1863 gtk_tree_view_column_set_cell_data_func(column
, renderer
, ui_reptime_amount_cell_data_function
, GINT_TO_POINTER(id
), NULL
);
1864 gtk_tree_view_column_set_alignment (column
, 0.5);
1865 //gtk_tree_view_column_set_sort_column_id (column, id);
1870 static void ui_reptime_list_set_cur(GtkTreeView
*treeview
, guint32 kcur
)
1872 g_object_set_data(G_OBJECT(treeview
), "kcur_data", GUINT_TO_POINTER(kcur
));
1878 ** create our statistic list
1880 static GtkWidget
*ui_list_reptime_create(void)
1882 GtkListStore
*store
;
1884 GtkCellRenderer
*renderer
;
1885 GtkTreeViewColumn
*column
;
1887 /* create list store */
1888 store
= gtk_list_store_new(
1897 view
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
));
1898 g_object_unref(store
);
1900 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view
), PREFS
->grid_lines
);
1903 column
= gtk_tree_view_column_new();
1904 gtk_tree_view_column_set_title(column
, _("Time slice"));
1905 renderer
= gtk_cell_renderer_text_new ();
1906 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1907 //gtk_tree_view_column_set_cell_data_func(column, renderer, ope_result_cell_data_function, NULL, NULL);
1908 gtk_tree_view_column_add_attribute(column
, renderer
, "text", LST_REPTIME_TITLE
);
1909 //gtk_tree_view_column_set_sort_column_id (column, LST_REPTIME_NAME);
1910 gtk_tree_view_column_set_resizable(column
, TRUE
);
1911 gtk_tree_view_column_set_alignment (column
, 0.5);
1912 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1914 /* column: Amount */
1915 column
= amount_list_ui_reptime_column(_("Amount"), LST_REPTIME_AMOUNT
);
1916 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1918 /* column last: empty */
1919 column
= gtk_tree_view_column_new();
1920 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1923 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
);
1924 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
);
1929 static gint
ui_list_reptime_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
)
1931 gint sortcol
= GPOINTER_TO_INT(userdata
);
1936 gtk_tree_model_get(model
, a
,
1937 LST_REPTIME_POS
, &pos1
,
1940 gtk_tree_model_get(model
, b
,
1941 LST_REPTIME_POS
, &pos2
,
1945 if(pos1 == -1) return(1);
1946 if(pos2 == -1) return(-1);
1949 if(sortcol
== LST_REPTIME_POS
)
1950 retval
= pos2
- pos1
;
1952 retval
= (ABS(val1
) - ABS(val2
)) > 0 ? 1 : -1;
1954 //DB( g_print(" sort %d=%d or %.2f=%.2f :: %d\n", pos1,pos2, val1, val2, ret) );