]> Dogcows Code - chaz/homebank/blob - src/rep_time.c
import homebank-5.1.7
[chaz/homebank] / src / rep_time.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2018 Maxime DOYEN
3 *
4 * This file is part of HomeBank.
5 *
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 #include "homebank.h"
22
23 #include "rep_time.h"
24
25 #include "list_operation.h"
26 #include "gtk-chart.h"
27 #include "gtk-dateentry.h"
28
29 #include "dsp_mainwindow.h"
30 #include "ui-account.h"
31 #include "ui-payee.h"
32 #include "ui-category.h"
33 #include "ui-filter.h"
34 #include "ui-transaction.h"
35
36
37 /****************************************************************************/
38 /* Debug macros */
39 /****************************************************************************/
40 #define MYDEBUG 0
41
42 #if MYDEBUG
43 #define DB(x) (x);
44 #else
45 #define DB(x);
46 #endif
47
48 /* our global datas */
49 extern struct HomeBank *GLOBALS;
50 extern struct Preferences *PREFS;
51
52
53 /* prototypes */
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);
60
61 static void ui_reptime_list_set_cur(GtkTreeView *treeview, guint32 kcur);
62
63
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 },
68 };
69 static guint n_radio_entries = G_N_ELEMENTS (radio_entries);
70
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) },
74
75 // { "Export" , ICONNAME_HB_FILE_EXPORT, N_("Export") , NULL, N_("Export as CSV"), G_CALLBACK (ui_reptime_action_export) },
76 };
77 static guint n_entries = G_N_ELEMENTS (entries);
78
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 */
85
86 };
87 static guint n_toggle_entries = G_N_ELEMENTS (toggle_entries);
88
89
90 static const gchar *ui_info =
91 "<ui>"
92 " <toolbar name='ToolBar'>"
93 " <toolitem action='List'/>"
94 " <toolitem action='Line'/>"
95 //" <toolitem action='Column'/>"
96 " <separator/>"
97 " <toolitem action='Detail'/>"
98 " <separator/>"
99 //" <toolitem action='Filter'/>"
100 " <toolitem action='Refresh'/>"
101 " <separator/>"
102 //" <toolitem action='Export'/>"
103 // replaced by a menubutton
104 " </toolbar>"
105 "</ui>";
106
107
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);
118
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);
121
122
123 gchar *CYA_TIMESELECT[] = { N_("Account"), N_("Category"), N_("Payee"), NULL };
124
125
126
127 gchar *CYA_VIEWBY[] = { N_("Day"), N_("Week"), N_("Month"), N_("Quarter"), N_("Year"), NULL };
128
129 //extern gchar *CYA_FLT_SELECT[];
130
131 gchar *CYA_ABMONTHS[] =
132 {
133 NULL,
134 N_("Jan"),
135 N_("Feb"),
136 N_("Mar"),
137 N_("Apr"),
138 N_("May"),
139 N_("Jun"),
140 N_("Jul"),
141 N_("Aug"),
142 N_("Sep"),
143 N_("Oct"),
144 N_("Nov"),
145 N_("Dec"),
146 };
147
148 /* action functions -------------------- */
149
150 static void ui_reptime_action_viewlist(GtkAction *action, gpointer user_data)
151 {
152 struct ui_reptime_data *data = user_data;
153
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);
157 }
158
159 static void ui_reptime_action_viewline(GtkAction *action, gpointer user_data)
160 {
161 struct ui_reptime_data *data = user_data;
162
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);
167 }
168
169
170 /*static void ui_reptime_action_viewcolumn(GtkAction *action, gpointer user_data)
171 {
172 struct ui_reptime_data *data = user_data;
173
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);
178
179 }*/
180
181
182 static void ui_reptime_action_mode (GtkRadioAction *action, GtkRadioAction *current, gpointer user_data)
183 {
184 gint value;
185
186 value = gtk_radio_action_get_current_value(GTK_RADIO_ACTION(action));
187 switch( value )
188 {
189 case 0:
190 ui_reptime_action_viewlist(GTK_ACTION(action), user_data);
191 break;
192 case 1:
193 ui_reptime_action_viewline(GTK_ACTION(action), user_data);
194 break;
195 }
196 }
197
198
199 static void ui_reptime_action_detail(GtkAction *action, gpointer user_data)
200 {
201 struct ui_reptime_data *data = user_data;
202
203 ui_reptime_toggle_detail(data->window, NULL);
204 }
205
206 /*
207 static void ui_reptime_action_filter(GtkAction *action, gpointer user_data)
208 {
209 struct ui_reptime_data *data = user_data;
210
211 //debug
212 //create_deffilter_window(data->filter, TRUE);
213
214 if(create_deffilter_window(data->filter, TRUE) != GTK_RESPONSE_REJECT)
215 ui_reptime_compute(data->window, NULL);
216 }
217 */
218
219 static void ui_reptime_action_refresh(GtkAction *action, gpointer user_data)
220 {
221 struct ui_reptime_data *data = user_data;
222
223 ui_reptime_compute(data->window, NULL);
224 }
225
226 /*static void ui_reptime_action_export(GtkAction *action, gpointer user_data)
227 {
228 struct ui_reptime_data *data = user_data;
229
230 ui_reptime_export_csv(data->window, NULL);
231 }*/
232
233
234
235 /* ======================== */
236
237
238
239 /*
240 ** ============================================================================
241 */
242
243
244
245
246 /*
247 ** return the month list position correponding to the passed date
248 */
249 static gint DateInMonth(guint32 from, guint32 opedate)
250 {
251 GDate *date1, *date2;
252 gint pos;
253
254 //debug
255 // this return sometimes -1, -2 which is wrong
256
257 date1 = g_date_new_julian(from);
258 date2 = g_date_new_julian(opedate);
259
260 pos = ((g_date_get_year(date2) - g_date_get_year(date1)) * 12) + g_date_get_month(date2) - g_date_get_month(date1);
261
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);
263
264 g_date_free(date2);
265 g_date_free(date1);
266
267 return(pos);
268 }
269
270 static gint DateInQuarter(guint32 from, guint32 opedate)
271 {
272 GDate *date1, *date2;
273 gint pos;
274
275 //debug
276 // this return sometimes -1, -2 which is wrong
277
278 date1 = g_date_new_julian(from);
279 date2 = g_date_new_julian(opedate);
280
281 pos = (((g_date_get_year(date2) - g_date_get_year(date1)) * 12) + g_date_get_month(date2) - g_date_get_month(date1))/3;
282
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) );
284
285 g_date_free(date2);
286 g_date_free(date1);
287
288 return(pos);
289 }
290 /*
291 ** return the year list position correponding to the passed date
292 */
293 static gint DateInYear(guint32 from, guint32 opedate)
294 {
295 GDate *date;
296 gint year_from, year_ope, pos;
297
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);
302 g_date_free(date);
303
304 pos = year_ope - year_from;
305
306 //g_print(" from=%d ope=%d => %d\n", year_from, year_ope, pos);
307
308 return(pos);
309 }
310
311
312 static void ui_reptime_date_change(GtkWidget *widget, gpointer user_data)
313 {
314 struct ui_reptime_data *data;
315
316 DB( g_print("\n[reptime] date change\n") );
317
318 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
319
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));
322
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);
326
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]);
330
331 ui_reptime_compute(widget, NULL);
332 ui_reptime_update_daterange(widget, NULL);
333
334 }
335
336
337 static void ui_reptime_update_quickdate(GtkWidget *widget, gpointer user_data)
338 {
339 struct ui_reptime_data *data;
340
341 DB( g_print("\n[reptime] update quickdate\n") );
342
343 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
344
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]);
347
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);
350
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]);
353
354 }
355
356
357 static void ui_reptime_range_change(GtkWidget *widget, gpointer user_data)
358 {
359 struct ui_reptime_data *data;
360 gint range;
361
362 DB( g_print("\n[reptime] range change\n") );
363
364 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
365
366 range = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_range));
367
368 if(range != FLT_RANGE_OTHER)
369 {
370 filter_preset_daterange_set(data->filter, range, data->accnum);
371
372 ui_reptime_update_quickdate(widget, NULL);
373
374 ui_reptime_compute(widget, NULL);
375 ui_reptime_update_daterange(widget, NULL);
376 }
377
378 }
379
380 static void ui_reptime_update_daterange(GtkWidget *widget, gpointer user_data)
381 {
382 struct ui_reptime_data *data;
383 gchar *daterange;
384
385 DB( g_print("\n[reptime] update daterange\n") );
386
387 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
388
389 daterange = filter_daterange_text_get(data->filter);
390 gtk_label_set_markup(GTK_LABEL(data->TX_daterange), daterange);
391 g_free(daterange);
392 }
393
394
395 static void ui_reptime_detail(GtkWidget *widget, gpointer user_data)
396 {
397 struct ui_reptime_data *data;
398 guint active = GPOINTER_TO_INT(user_data);
399 guint tmpfor, tmpslice;
400 gboolean showall;
401 guint32 from;
402 guint i;
403 GList *list;
404 GtkTreeModel *model;
405 GtkTreeIter iter;
406 guint32 selkey;
407
408 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
409
410 DB( g_print("\n[reptime] detail\n") );
411
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));
415 selkey = 0;
416
417 switch(tmpfor)
418 {
419 case FOR_REPTIME_ACCOUNT:
420 selkey = ui_acc_comboboxentry_get_key(GTK_COMBO_BOX(data->PO_acc));
421 break;
422 case FOR_REPTIME_CATEGORY:
423 selkey = ui_cat_comboboxentry_get_key(GTK_COMBO_BOX(data->PO_cat));
424 break;
425 case FOR_REPTIME_PAYEE:
426 selkey = ui_pay_comboboxentry_get_key(GTK_COMBO_BOX(data->PO_pay));
427 break;
428 }
429
430 //DB( g_print(" for=%d, view by=%d :: key=%d\n", tmpfor, tmpslice, selkey) );
431
432 //get our min max date
433 from = data->filter->mindate;
434 //to = data->filter->maxdate;
435
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));
439
440 if(data->detail)
441 {
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 */
444
445 /* fill in the model */
446 list = g_queue_peek_head_link(data->txn_queue);
447 while (list != NULL)
448 {
449 Transaction *ope = list->data;
450 guint32 pos = 0;
451 gboolean include = FALSE;
452
453 //DB( g_print(" get %s\n", ope->ope_Word) );
454
455 switch(tmpfor)
456 {
457 case FOR_REPTIME_ACCOUNT:
458 if( selkey == ope->kacc )
459 include = TRUE;
460 break;
461 case FOR_REPTIME_CATEGORY:
462 {
463 Category *catentry;
464
465 if( ope->flags & OF_SPLIT )
466 {
467 guint nbsplit = da_splits_count(ope->splits);
468 Split *split;
469
470 for(i=0;i<nbsplit;i++)
471 {
472 split = ope->splits[i];
473 catentry = da_cat_get(split->kcat);
474 if(catentry != NULL) //#1340142
475 {
476 if( selkey == catentry->parent || selkey == catentry->key )
477 include = TRUE;
478
479 }
480 }
481 }
482 else
483 {
484 catentry = da_cat_get(ope->kcat);
485 if(catentry != NULL) //#1340142
486 {
487 if( selkey == catentry->parent || selkey == catentry->key )
488 include = TRUE;
489
490 }
491 }
492 }
493 break;
494 case FOR_REPTIME_PAYEE:
495 if( selkey == ope->kpay )
496 include = TRUE;
497 break;
498 }
499
500 if( include == TRUE || showall == TRUE )
501 {
502
503 switch(tmpslice)
504 {
505 case GROUPBY_REPTIME_DAY:
506 pos = ope->date - from;
507 break;
508
509 case GROUPBY_REPTIME_WEEK:
510 pos = (ope->date - from)/7;
511 break;
512
513 case GROUPBY_REPTIME_MONTH:
514 pos = DateInMonth(from, ope->date);
515 break;
516
517 case GROUPBY_REPTIME_QUARTER:
518 pos = DateInQuarter(from, ope->date);
519 break;
520
521 case GROUPBY_REPTIME_YEAR:
522 pos = DateInYear(from, ope->date);
523 break;
524 }
525
526 DB( g_print("** pos=%d\n", pos) );
527
528 //insert
529 if( pos == active )
530 {
531
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,
535 -1);
536 }
537
538
539 }
540
541 list = g_list_next(list);
542 }
543
544 /* Re-attach model to view */
545 gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_detail), model);
546 g_object_unref(model);
547
548 gtk_tree_view_columns_autosize( GTK_TREE_VIEW(data->LV_detail) );
549 }
550
551 }
552
553
554 static void ui_reptime_update(GtkWidget *widget, gpointer user_data)
555 {
556 struct ui_reptime_data *data;
557 GtkTreeModel *model;
558 gint page;
559 gint tmpfor;
560 gchar *title;
561 //gboolean xval;
562
563 DB( g_print("\n[reptime] update\n") );
564
565 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
566
567
568 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_report));
569 //byamount = 0;
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));
572
573 // ensure not exp & inc for piechart
574 page = gtk_notebook_get_current_page(GTK_NOTEBOOK(data->GR_result));
575
576 DB( g_print(" page %d\n\n", page) );
577 //DB( g_print(" tmpslice %d\n\n", tmpslice) );
578
579
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);
583
584 gtk_chart_show_legend(GTK_CHART(data->RE_line), FALSE, FALSE);
585 gtk_chart_show_xval(GTK_CHART(data->RE_line), TRUE);
586
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);
590 g_free(title);
591
592 if(page == 1)
593 {
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);
597 }
598
599 }
600
601
602 static void ui_reptime_export_result_clipboard(GtkWidget *widget, gpointer user_data)
603 {
604 struct ui_reptime_data *data;
605 GtkClipboard *clipboard;
606 GString *node;
607
608 DB( g_print("\n[reptime] export result clipboard\n") );
609
610 data = user_data;
611 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
612
613 node = ui_list_reptime_to_string(GTK_TREE_VIEW(data->LV_report), TRUE);
614
615 clipboard = gtk_clipboard_get_default(gdk_display_get_default());
616 gtk_clipboard_set_text(clipboard, node->str, node->len);
617
618 g_string_free(node, TRUE);
619 }
620
621
622 static void ui_reptime_export_result_csv(GtkWidget *widget, gpointer user_data)
623 {
624 struct ui_reptime_data *data;
625 gchar *filename = NULL;
626 GString *node;
627 GIOChannel *io;
628 gchar *name;
629 gint tmpfor;
630
631 DB( g_print("\n[reptime] export result csv\n") );
632
633 data = user_data;
634 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
635
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]);
638
639 if( ui_file_chooser_csv(GTK_WINDOW(data->window), GTK_FILE_CHOOSER_ACTION_SAVE, &filename, name) == TRUE )
640 {
641 DB( g_print(" + filename is %s\n", filename) );
642 io = g_io_channel_new_file(filename, "w", NULL);
643 if(io != NULL)
644 {
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);
649 }
650 g_free( filename );
651 }
652 g_free(name);
653 }
654
655
656 static void ui_reptime_export_detail_clipboard(GtkWidget *widget, gpointer user_data)
657 {
658 struct ui_reptime_data *data;
659 GtkClipboard *clipboard;
660 GString *node;
661
662 DB( g_print("\n[reptime] export detail clipboard\n") );
663
664 data = user_data;
665 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
666
667 node = list_txn_to_string(GTK_TREE_VIEW(data->LV_detail), TRUE);
668
669 clipboard = gtk_clipboard_get_default(gdk_display_get_default());
670 gtk_clipboard_set_text(clipboard, node->str, node->len);
671
672 g_string_free(node, TRUE);
673 }
674
675
676 static void ui_reptime_export_detail_csv(GtkWidget *widget, gpointer user_data)
677 {
678 struct ui_reptime_data *data;
679 gchar *filename = NULL;
680 GString *node;
681 GIOChannel *io;
682 gchar *name;
683 gint tmpfor;
684
685 DB( g_print("\n[reptime] export detail csv\n") );
686
687 data = user_data;
688 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
689
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]);
692
693 if( ui_file_chooser_csv(GTK_WINDOW(data->window), GTK_FILE_CHOOSER_ACTION_SAVE, &filename, name) == TRUE )
694 {
695 DB( g_print(" + filename is %s\n", filename) );
696
697 io = g_io_channel_new_file(filename, "w", NULL);
698 if(io != NULL)
699 {
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);
702
703 g_io_channel_unref (io);
704 g_string_free(node, TRUE);
705 }
706
707 g_free( filename );
708 }
709
710 g_free(name);
711 }
712
713
714 static void ui_reptime_update_for(GtkWidget *widget, gpointer user_data)
715 {
716 struct ui_reptime_data *data;
717 gint tmpfor;
718 gboolean visible;
719
720 DB( g_print("\n[reptime] update for\n") );
721
722 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
723
724 tmpfor = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_for));
725
726 visible = tmpfor == 0 ? TRUE : FALSE;
727 hb_widget_visible(data->LB_acc, visible);
728 hb_widget_visible(data->PO_acc, visible);
729
730 visible = tmpfor == 1 ? TRUE : FALSE;
731 hb_widget_visible(data->LB_cat, visible);
732 hb_widget_visible(data->PO_cat, visible);
733
734 visible = tmpfor == 2 ? TRUE : FALSE;
735 hb_widget_visible(data->LB_pay, visible);
736 hb_widget_visible(data->PO_pay, visible);
737
738 }
739
740
741
742 static void ui_reptime_for(GtkWidget *widget, gpointer user_data)
743 {
744 struct ui_reptime_data *data;
745
746 DB( g_print("\n[reptime] for\n") );
747
748 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
749
750 ui_reptime_update_for(widget, data);
751
752 ui_reptime_compute(widget, data);
753 }
754
755
756 static void ui_reptime_compute(GtkWidget *widget, gpointer user_data)
757 {
758 struct ui_reptime_data *data;
759 gint tmpfor, tmpslice;
760 guint32 from, to;
761 gboolean cumul;
762 gboolean showall;
763
764 gdouble cumulation, average;
765
766 GtkTreeModel *model;
767 GtkTreeIter iter;
768 GList *list;
769 gint id;
770 guint n_result, i;
771 GDate *date1, *date2;
772 gdouble *tmp_amount;
773 guint32 selkey;
774
775 DB( g_print("\n[reptime] compute\n") );
776
777 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
778
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));
783 selkey = 0;
784
785 data->accnum = 0;
786
787 switch(tmpfor)
788 {
789 case FOR_REPTIME_ACCOUNT:
790 selkey = ui_acc_comboboxentry_get_key(GTK_COMBO_BOX(data->PO_acc));
791 if(showall == FALSE)
792 data->accnum = selkey;
793 break;
794 case FOR_REPTIME_CATEGORY:
795 selkey = ui_cat_comboboxentry_get_key(GTK_COMBO_BOX(data->PO_cat));
796 break;
797 case FOR_REPTIME_PAYEE:
798 selkey = ui_pay_comboboxentry_get_key(GTK_COMBO_BOX(data->PO_pay));
799 break;
800 }
801
802 DB( g_print(" for=%d, view by=%d :: key=%d\n", tmpfor, tmpslice, selkey) );
803
804 //to remove > 5.0.2
805 //#1715532 5.0.5: no... but only showall
806 if(showall == TRUE)
807 {
808 filter_preset_daterange_set(data->filter, data->filter->range, data->accnum);
809 ui_reptime_update_quickdate(widget, NULL);
810 }
811
812 //get our min max date
813 from = data->filter->mindate;
814 to = data->filter->maxdate;
815 if(to < from) return;
816
817 g_queue_free (data->txn_queue);
818 data->txn_queue = hbfile_transaction_get_partial(data->filter->mindate, data->filter->maxdate);
819
820
821 /* count number or results */
822 switch(tmpslice)
823 {
824 case GROUPBY_REPTIME_DAY:
825 n_result = 1 + (to - from);
826 break;
827 case GROUPBY_REPTIME_WEEK:
828 n_result = 1 + ((to - from) / 7);
829 break;
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);
834 g_date_free(date2);
835 g_date_free(date1);
836 break;
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;
841 g_date_free(date2);
842 g_date_free(date1);
843 break;
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);
848 g_date_free(date2);
849 g_date_free(date1);
850 break;
851 default:
852 n_result = 0;
853 }
854
855 DB( g_print(" %s :: n_result=%d\n", CYA_TIMESELECT[tmpfor], n_result) );
856
857 /* allocate some memory */
858
859 tmp_amount = g_malloc0((n_result+2) * sizeof(gdouble));
860
861 if(tmp_amount)
862 {
863 guint32 kcur;
864
865 /* set currency */
866 kcur = GLOBALS->kcur;
867 if( (tmpfor == FOR_REPTIME_ACCOUNT) && (showall == FALSE) )
868 {
869 Account *acc = da_acc_get(selkey);
870
871 if( acc != NULL )
872 {
873 kcur = acc->kcur;
874 }
875 }
876
877 ui_reptime_list_set_cur(GTK_TREE_VIEW(data->LV_report), kcur);
878 gtk_chart_set_currency(GTK_CHART(data->RE_line), kcur);
879
880 /* compute the results */
881 list = g_queue_peek_head_link(data->txn_queue);
882 while (list != NULL)
883 {
884 Transaction *ope = list->data;
885 gboolean include = FALSE;
886
887 //debug
888 DB( g_print("** testing '%s', cat=%d==> %d\n", ope->memo, ope->kcat, filter_test(data->filter, ope)) );
889
890 // add usage of payee or category
891 switch(tmpfor)
892 {
893 case FOR_REPTIME_ACCOUNT:
894 if( selkey == ope->kacc )
895 include = TRUE;
896 break;
897 case FOR_REPTIME_CATEGORY:
898 {
899 Category *catentry;
900
901 if( ope->flags & OF_SPLIT )
902 {
903 guint nbsplit = da_splits_count(ope->splits);
904 Split *split;
905
906 for(i=0;i<nbsplit;i++)
907 {
908 split = ope->splits[i];
909 catentry = da_cat_get(split->kcat);
910 if(catentry != NULL) //#1340142
911 {
912 if( selkey == catentry->parent || selkey == catentry->key )
913 include = TRUE;
914 }
915 }
916 }
917 else
918 {
919 catentry = da_cat_get(ope->kcat);
920 if(catentry != NULL) //#1340142
921 {
922 if( selkey == catentry->parent || selkey == catentry->key )
923 include = TRUE;
924 }
925 }
926
927 }
928 break;
929 case FOR_REPTIME_PAYEE:
930 if( selkey == ope->kpay )
931 include = TRUE;
932 break;
933 }
934
935 if( include == TRUE || showall == TRUE)
936 {
937 guint32 pos = 0;
938 gdouble trn_amount;
939
940 switch(tmpslice)
941 {
942 case GROUPBY_REPTIME_DAY:
943 pos = ope->date - from;
944 break;
945
946 case GROUPBY_REPTIME_WEEK:
947 pos = (ope->date - from)/7;
948 break;
949
950 case GROUPBY_REPTIME_MONTH:
951 pos = DateInMonth(from, ope->date);
952 break;
953
954 case GROUPBY_REPTIME_QUARTER:
955 pos = DateInQuarter(from, ope->date);
956 break;
957
958 case GROUPBY_REPTIME_YEAR:
959 pos = DateInYear(from, ope->date);
960 break;
961 }
962
963 trn_amount = 0.0;
964
965 if( (tmpfor == FOR_REPTIME_CATEGORY) && (ope->flags & OF_SPLIT) )
966 {
967 guint nbsplit = da_splits_count(ope->splits);
968 Split *split;
969 Category *catentry;
970
971 for(i=0;i<nbsplit;i++)
972 {
973 split = ope->splits[i];
974 catentry = da_cat_get(split->kcat);
975 if(catentry != NULL) //#1340142
976 {
977 //#1678230 miss showall
978 if( showall == TRUE || selkey == catentry->parent || selkey == catentry->key )
979 trn_amount += split->amount;
980 }
981 }
982 }
983 else
984 trn_amount = ope->amount;
985
986 trn_amount = hb_amount_base(trn_amount, ope->kcur);
987
988 DB( g_print("** pos=%d : add of %.2f\n", pos, trn_amount) );
989
990 tmp_amount[pos] += trn_amount;
991
992 }
993
994 list = g_list_next(list);
995 }
996
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 */
1002
1003 cumulation = 0.0;
1004
1005 /* insert into the treeview */
1006 for(i=0, id=0; i<n_result; i++)
1007 {
1008 gchar *name, *fullcatname;
1009 gdouble value;
1010 gchar buffer[64];
1011 GDate *date;
1012
1013 name = NULL;
1014 fullcatname = NULL;
1015
1016
1017 DB( g_print("try to insert item %d\n", i) );
1018
1019 /* get the result name */
1020 switch(tmpslice)
1021 {
1022 case GROUPBY_REPTIME_DAY:
1023 date = g_date_new_julian (from + i);
1024 g_date_strftime (buffer, 63, PREFS->date_format, date);
1025 g_date_free(date);
1026 name = buffer;
1027 break;
1028
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));
1034 g_date_free(date);
1035 name = buffer;
1036 break;
1037
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)]));
1043 g_date_free(date);
1044 name = buffer;
1045 break;
1046
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);
1052 g_date_free(date);
1053 name = buffer;
1054 break;
1055
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));
1060 g_date_free(date);
1061 name = buffer;
1062 break;
1063 }
1064
1065 cumulation += tmp_amount[i];
1066 value = cumul == TRUE ? cumulation : tmp_amount[i];
1067
1068
1069 //DB( g_print(" inserting %2d, '%s', %9.2f\n", i, name, value) );
1070
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++,
1074 LST_REPTIME_KEY, i,
1075 LST_REPTIME_TITLE, name,
1076 LST_REPTIME_AMOUNT, value,
1077 -1);
1078
1079 g_free(fullcatname);
1080 }
1081
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]));
1085
1086 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_report));
1087
1088 /* Re-attach model to view */
1089 gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_report), model);
1090 g_object_unref(model);
1091
1092 //update average
1093 {
1094 gchar *info;
1095 gchar buf[128];
1096
1097 average = cumulation / n_result;
1098
1099 hb_strfmon(buf, 127, average, kcur, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_minor)) );
1100
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);
1104 g_free(info);
1105 }
1106 }
1107
1108 /* free our memory */
1109 g_free(tmp_amount);
1110
1111 ui_reptime_update(widget, user_data);
1112
1113 }
1114
1115
1116
1117
1118
1119 /*
1120 ** update sensitivity
1121 */
1122 static void ui_reptime_sensitive(GtkWidget *widget, gpointer user_data)
1123 {
1124 struct ui_reptime_data *data;
1125 GtkAction *action;
1126 gboolean visible, sensitive;
1127 gint page;
1128
1129 DB( g_print("\n[reptime] sensitive\n") );
1130
1131 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1132
1133 page = gtk_notebook_get_current_page(GTK_NOTEBOOK(data->GR_result));
1134
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);
1143
1144 visible = page == 0 ? FALSE : TRUE;
1145 hb_widget_visible(data->LB_zoomx, visible);
1146 hb_widget_visible(data->RG_zoomx, visible);
1147
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);
1151
1152 }
1153
1154
1155 static void ui_reptime_detail_onRowActivated (GtkTreeView *treeview,
1156 GtkTreePath *path,
1157 GtkTreeViewColumn *col,
1158 gpointer userdata)
1159 {
1160 struct ui_reptime_data *data;
1161 Transaction *active_txn;
1162 gboolean result;
1163
1164 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview), GTK_TYPE_WINDOW)), "inst_data");
1165
1166 DB( g_print ("\n[reptime] A detail row has been double-clicked!\n") );
1167
1168 active_txn = list_txn_get_active_transaction(GTK_TREE_VIEW(data->LV_detail));
1169 if(active_txn)
1170 {
1171 Transaction *old_txn, *new_txn;
1172
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);
1176
1177 if(result == GTK_RESPONSE_ACCEPT)
1178 {
1179 //#1640885
1180 GLOBALS->changes_count++;
1181 ui_reptime_compute(data->window, NULL);
1182 }
1183
1184 da_transaction_free (old_txn);
1185 }
1186 }
1187
1188
1189 static void ui_reptime_update_detail(GtkWidget *widget, gpointer user_data)
1190 {
1191 struct ui_reptime_data *data;
1192
1193 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1194
1195 if(data->detail)
1196 {
1197 GtkTreeSelection *treeselection;
1198 GtkTreeModel *model;
1199 GtkTreeIter iter;
1200 guint key;
1201
1202 treeselection = gtk_tree_view_get_selection (GTK_TREE_VIEW(data->LV_report));
1203
1204 if (gtk_tree_selection_get_selected(treeselection, &model, &iter))
1205 {
1206 gtk_tree_model_get(model, &iter, LST_REPTIME_KEY, &key, -1);
1207
1208 DB( g_print(" - active is %d\n", key) );
1209
1210 ui_reptime_detail(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), GINT_TO_POINTER(key));
1211 }
1212
1213
1214
1215 gtk_widget_show(data->GR_detail);
1216 }
1217 else
1218 gtk_widget_hide(data->GR_detail);
1219 }
1220
1221
1222
1223
1224 static void ui_reptime_toggle_detail(GtkWidget *widget, gpointer user_data)
1225 {
1226 struct ui_reptime_data *data;
1227
1228 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1229
1230 data->detail ^= 1;
1231
1232 DB( g_print("(stats) toggledetail to %d\n", data->detail) );
1233
1234 ui_reptime_update_detail(widget, user_data);
1235
1236 }
1237
1238 static void ui_reptime_zoomx_callback(GtkWidget *widget, gpointer user_data)
1239 {
1240 struct ui_reptime_data *data;
1241 gdouble value;
1242
1243 DB( g_print("\n[reptime] zoomx\n") );
1244
1245 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1246
1247 value = gtk_range_get_value(GTK_RANGE(data->RG_zoomx));
1248
1249 DB( g_print(" + scale is %.2f\n", value) );
1250
1251 gtk_chart_set_barw(GTK_CHART(data->RE_line), value);
1252
1253 }
1254
1255
1256
1257 static void ui_reptime_toggle_minor(GtkWidget *widget, gpointer user_data)
1258 {
1259 struct ui_reptime_data *data;
1260
1261 DB( g_print("\n[reptime] toggle\n") );
1262
1263 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1264
1265 GLOBALS->minor = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_minor));
1266
1267 //hbfile_update(data->LV_acc, (gpointer)4);
1268 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_report));
1269
1270 gtk_chart_show_minor(GTK_CHART(data->RE_line), GLOBALS->minor);
1271
1272 }
1273
1274
1275 static void ui_reptime_toggle_showall(GtkWidget *widget, gpointer user_data)
1276 {
1277 struct ui_reptime_data *data;
1278 gboolean showall;
1279
1280 DB( g_print("\n[reptime] toggle\n") );
1281
1282 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1283
1284 showall = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_all));
1285
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);
1289
1290 ui_reptime_compute(widget, data);
1291
1292 }
1293
1294
1295
1296 /*
1297 **
1298 */
1299 static void ui_reptime_setup(struct ui_reptime_data *data, guint32 accnum)
1300 {
1301 DB( g_print("\n[reptime] setup\n") );
1302
1303 data->txn_queue = g_queue_new ();
1304
1305 data->filter = da_filter_malloc();
1306 filter_default_all_set(data->filter);
1307
1308 data->detail = 0;
1309
1310 /* 3.4 : make int transfer out of stats */
1311 data->filter->option[FILTER_PAYMODE] = 1;
1312 data->filter->paymode[PAYMODE_INTXFER] = FALSE;
1313
1314 filter_preset_daterange_set(data->filter, PREFS->date_range_rep, data->accnum);
1315
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]);
1318
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);
1321
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]);
1324
1325
1326 DB( g_print(" populate\n") );
1327 ui_acc_comboboxentry_populate(GTK_COMBO_BOX(data->PO_acc), GLOBALS->h_acc, ACC_LST_INSERT_REPORT);
1328 if( accnum )
1329 ui_acc_comboboxentry_set_active(GTK_COMBO_BOX(data->PO_acc), accnum);
1330 else
1331 gtk_combo_box_set_active(GTK_COMBO_BOX(data->PO_acc), 0);
1332
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);
1335
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);
1338
1339 DB( g_print(" all ok\n") );
1340
1341 }
1342
1343
1344
1345 static void ui_reptime_selection(GtkTreeSelection *treeselection, gpointer user_data)
1346 {
1347 GtkTreeModel *model;
1348 GtkTreeIter iter;
1349 guint key = -1;
1350
1351 DB( g_print("\n[reptime] selection\n") );
1352
1353 if (gtk_tree_selection_get_selected(treeselection, &model, &iter))
1354 {
1355 gtk_tree_model_get(model, &iter, LST_REPTIME_KEY, &key, -1);
1356
1357 }
1358
1359 DB( g_print(" - active is %d\n", key) );
1360
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);
1363 }
1364
1365
1366 /*
1367 **
1368 */
1369 static gboolean ui_reptime_dispose(GtkWidget *widget, GdkEvent *event, gpointer user_data)
1370 {
1371 struct ui_reptime_data *data = user_data;
1372 struct WinGeometry *wg;
1373
1374 DB( g_print("\n[reptime] dispose\n") );
1375
1376 g_queue_free (data->txn_queue);
1377
1378 da_filter_free(data->filter);
1379
1380 g_free(data);
1381
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);
1386
1387 DB( g_print(" window: l=%d, t=%d, w=%d, h=%d\n", wg->l, wg->t, wg->w, wg->h) );
1388
1389
1390
1391 //enable define windows
1392 GLOBALS->define_off--;
1393 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
1394
1395 return FALSE;
1396 }
1397
1398 // the window creation
1399 GtkWidget *ui_reptime_window_new(guint32 accnum)
1400 {
1401 struct ui_reptime_data *data;
1402 struct WinGeometry *wg;
1403 GtkWidget *window, *mainvbox, *hbox, *vbox, *notebook, *treeview;
1404 GtkWidget *label, *widget, *table;
1405 gint row;
1406 GtkUIManager *ui;
1407 GtkActionGroup *actions;
1408 //GtkAction *action;
1409 GError *error = NULL;
1410
1411 data = g_malloc0(sizeof(struct ui_reptime_data));
1412 if(!data) return NULL;
1413
1414 DB( g_print("\n[reptime] new\n") );
1415
1416
1417 //disable define windows
1418 GLOBALS->define_off++;
1419 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
1420
1421 /* create window, etc */
1422 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1423 data->window = window;
1424
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) );
1428
1429
1430 gtk_window_set_title (GTK_WINDOW (window), _("Trend Time Report"));
1431
1432 //set the window icon
1433 gtk_window_set_icon_name(GTK_WINDOW (window), ICONNAME_HB_REP_TIME);
1434
1435
1436 //window contents
1437 mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1438 gtk_container_add (GTK_CONTAINER (window), mainvbox);
1439
1440 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
1441 gtk_box_pack_start (GTK_BOX (mainvbox), hbox, TRUE, TRUE, 0);
1442
1443 //control part
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);
1447
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);
1451
1452 row = 0;
1453 label = make_label_group(_("Display"));
1454 gtk_grid_attach (GTK_GRID (table), label, 0, row, 3, 1);
1455
1456 row++;
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);
1462
1463 row++;
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);
1470
1471 row++;
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);
1478
1479 row++;
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);
1486
1487 row++;
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);
1491
1492 row++;
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);
1496
1497 row++;
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);
1503
1504 row++;
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);
1508
1509 row++;
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);
1516
1517
1518 row++;
1519 widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
1520 gtk_grid_attach (GTK_GRID (table), widget, 0, row, 3, 1);
1521
1522 row++;
1523 label = make_label_group(_("Date filter"));
1524 gtk_grid_attach (GTK_GRID (table), label, 0, row, 3, 1);
1525
1526 row++;
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);
1531
1532 row++;
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);
1537
1538 row++;
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);
1543
1544
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);
1548
1549 //ui manager
1550 actions = gtk_action_group_new ("default");
1551
1552 //as we use gettext
1553 gtk_action_group_set_translation_domain(actions, GETTEXT_PACKAGE);
1554
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);
1557
1558 gtk_action_group_add_actions (actions, entries, n_entries, data);
1559
1560 gtk_action_group_add_toggle_actions (actions,
1561 toggle_entries, n_toggle_entries,
1562 data);
1563
1564
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);
1568
1569 //action = gtk_action_group_get_action(actions, "Line");
1570 //g_object_set(action, "is_important", TRUE, NULL);
1571
1572 /*action = gtk_action_group_get_action(actions, "Column");
1573 g_object_set(action, "is_important", TRUE, NULL);*/
1574
1575 //action = gtk_action_group_get_action(actions, "Detail");
1576 //g_object_set(action, "is_important", TRUE, NULL);
1577
1578 //action = gtk_action_group_get_action(actions, "Refresh");
1579 //g_object_set(action, "is_important", TRUE, NULL);
1580
1581
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));
1585
1586 if (!gtk_ui_manager_add_ui_from_string (ui, ui_info, -1, &error))
1587 {
1588 g_message ("building UI failed: %s", error->message);
1589 g_error_free (error);
1590 }
1591
1592 data->ui = ui;
1593 data->actions = actions;
1594
1595 //toolbar
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);
1598
1599 //add export menu button
1600 GtkToolItem *toolitem;
1601 GtkWidget *menu, *menuitem, *image;
1602
1603 menu = gtk_menu_new ();
1604 //gtk_widget_set_halign (menu, GTK_ALIGN_END);
1605
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);
1609
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);
1613
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);
1618
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);
1623
1624 gtk_widget_show_all (menu);
1625
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);
1629
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);
1634
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);
1638
1639 //infos
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);
1643
1644 label = gtk_label_new(NULL);
1645 data->TX_info = label;
1646 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
1647
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);
1652
1653
1654
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);
1660
1661 gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
1662
1663 //page: list
1664 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1665 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, NULL);
1666
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);
1675
1676 //detail
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);
1685
1686 gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0);
1687
1688
1689 //page: lines
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);
1694
1695 //todo:should move this
1696 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->CM_minor), GLOBALS->minor);
1697
1698 gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_view), 1);
1699
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);
1703
1704
1705
1706 /* signal connect */
1707 g_signal_connect (window, "delete-event", G_CALLBACK (ui_reptime_dispose), (gpointer)data);
1708
1709 g_signal_connect (data->CM_cumul, "toggled", G_CALLBACK (ui_reptime_compute), NULL);
1710
1711 g_signal_connect (data->CM_minor, "toggled", G_CALLBACK (ui_reptime_toggle_minor), NULL);
1712
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);
1715
1716 data->handler_id[HID_REPTIME_RANGE] = g_signal_connect (data->CY_range, "changed", G_CALLBACK (ui_reptime_range_change), NULL);
1717
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);
1720
1721 //setup, init and show window
1722 ui_reptime_setup(data, accnum);
1723
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);
1728
1729 g_signal_connect (data->RG_zoomx, "value-changed", G_CALLBACK (ui_reptime_zoomx_callback), NULL);
1730
1731
1732 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_report)), "changed", G_CALLBACK (ui_reptime_selection), NULL);
1733
1734 g_signal_connect (GTK_TREE_VIEW(data->LV_detail), "row-activated", G_CALLBACK (ui_reptime_detail_onRowActivated), NULL);
1735
1736
1737 /* toolbar */
1738 if(PREFS->toolbar_style == 0)
1739 gtk_toolbar_unset_style(GTK_TOOLBAR(data->TB_bar));
1740 else
1741 gtk_toolbar_set_style(GTK_TOOLBAR(data->TB_bar), PREFS->toolbar_style-1);
1742
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);
1747
1748 gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_view), GROUPBY_REPTIME_MONTH);
1749
1750 gtk_widget_show_all (window);
1751
1752 //minor ?
1753 if( PREFS->euro_active )
1754 gtk_widget_show(data->CM_minor);
1755 else
1756 gtk_widget_hide(data->CM_minor);
1757
1758 ui_reptime_update_for(window, data);
1759 //gtk_widget_hide(data->GR_detail);
1760
1761
1762
1763 ui_reptime_sensitive(window, NULL);
1764 ui_reptime_update_detail(window, NULL);
1765
1766 DB( g_print("range: %d\n", PREFS->date_range_rep) );
1767
1768 if( PREFS->date_range_rep != 0)
1769 gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_range), PREFS->date_range_rep);
1770 else
1771 ui_reptime_compute(window, NULL);
1772
1773 return window;
1774 }
1775
1776 /*
1777 ** ============================================================================
1778 */
1779
1780
1781 static GString *ui_list_reptime_to_string(GtkTreeView *treeview, gboolean clipboard)
1782 {
1783 GString *node;
1784 GtkTreeModel *model;
1785 GtkTreeIter iter;
1786 gboolean valid;
1787 const gchar *format;
1788
1789 node = g_string_new(NULL);
1790
1791 // header
1792 format = (clipboard == TRUE) ? "%s\t%s\n" : "%s;%s\n";
1793 g_string_append_printf(node, format, _("Time slice"), _("Amount"));
1794
1795 model = gtk_tree_view_get_model(treeview);
1796 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
1797 while (valid)
1798 {
1799 gchar *name;
1800 gdouble amount;
1801
1802 gtk_tree_model_get (model, &iter,
1803 //LST_REPTIME_KEY, i,
1804 LST_REPTIME_TITLE , &name,
1805 LST_REPTIME_AMOUNT , &amount,
1806 -1);
1807
1808 format = (clipboard == TRUE) ? "%s\t%.2f\n" : "%s;%.2f\n";
1809 g_string_append_printf(node, format, name, amount);
1810
1811 //leak
1812 g_free(name);
1813
1814 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
1815 }
1816
1817 //DB( g_print("text is:\n%s", node->str) );
1818
1819 return node;
1820 }
1821
1822
1823 static void ui_reptime_amount_cell_data_function (GtkTreeViewColumn *col,
1824 GtkCellRenderer *renderer,
1825 GtkTreeModel *model,
1826 GtkTreeIter *iter,
1827 gpointer user_data)
1828 {
1829 gdouble value;
1830 gchar *color;
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"));
1833
1834 gtk_tree_model_get(model, iter, GPOINTER_TO_INT(user_data), &value, -1);
1835
1836 if( value )
1837 {
1838 hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, value, kcur, GLOBALS->minor);
1839
1840 color = get_normal_color_amount(value);
1841
1842 g_object_set(renderer,
1843 "foreground", color,
1844 "text", buf,
1845 NULL); }
1846 else
1847 {
1848 g_object_set(renderer, "text", "", NULL);
1849 }
1850 }
1851
1852
1853 static GtkTreeViewColumn *amount_list_ui_reptime_column(gchar *name, gint id)
1854 {
1855 GtkTreeViewColumn *column;
1856 GtkCellRenderer *renderer;
1857
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);
1866 return column;
1867 }
1868
1869
1870 static void ui_reptime_list_set_cur(GtkTreeView *treeview, guint32 kcur)
1871 {
1872 g_object_set_data(G_OBJECT(treeview), "kcur_data", GUINT_TO_POINTER(kcur));
1873 }
1874
1875
1876
1877 /*
1878 ** create our statistic list
1879 */
1880 static GtkWidget *ui_list_reptime_create(void)
1881 {
1882 GtkListStore *store;
1883 GtkWidget *view;
1884 GtkCellRenderer *renderer;
1885 GtkTreeViewColumn *column;
1886
1887 /* create list store */
1888 store = gtk_list_store_new(
1889 NUM_LST_REPTIME,
1890 G_TYPE_INT,
1891 G_TYPE_INT,
1892 G_TYPE_STRING,
1893 G_TYPE_DOUBLE
1894 );
1895
1896 //treeview
1897 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1898 g_object_unref(store);
1899
1900 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), PREFS->grid_lines);
1901
1902 /* column: Name */
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);
1913
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);
1917
1918 /* column last: empty */
1919 column = gtk_tree_view_column_new();
1920 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
1921
1922 /* sort */
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);
1925
1926 return(view);
1927 }
1928
1929 static gint ui_list_reptime_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
1930 {
1931 gint sortcol = GPOINTER_TO_INT(userdata);
1932 gint retval = 0;
1933 gint pos1, pos2;
1934 gdouble val1, val2;
1935
1936 gtk_tree_model_get(model, a,
1937 LST_REPTIME_POS, &pos1,
1938 sortcol, &val1,
1939 -1);
1940 gtk_tree_model_get(model, b,
1941 LST_REPTIME_POS, &pos2,
1942 sortcol, &val2,
1943 -1);
1944 /*
1945 if(pos1 == -1) return(1);
1946 if(pos2 == -1) return(-1);
1947 */
1948
1949 if(sortcol == LST_REPTIME_POS)
1950 retval = pos2 - pos1;
1951 else
1952 retval = (ABS(val1) - ABS(val2)) > 0 ? 1 : -1;
1953
1954 //DB( g_print(" sort %d=%d or %.2f=%.2f :: %d\n", pos1,pos2, val1, val2, ret) );
1955
1956 return retval;
1957 }
1958
This page took 0.127531 seconds and 4 git commands to generate.