1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 Maxime DOYEN
4 * This file is part of HomeBank.
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "rep-vehicle.h"
25 #include "list-operation.h"
26 #include "gtk-chart.h"
27 #include "gtk-dateentry.h"
29 #include "dsp-mainwindow.h"
30 #include "ui-category.h"
33 /****************************************************************************/
35 /****************************************************************************/
44 /* our global datas */
45 extern struct HomeBank
*GLOBALS
;
46 extern struct Preferences
*PREFS
;
50 static void repvehicle_action_refresh(GtkAction
*action
, gpointer user_data
);
51 static void repvehicle_action_export(GtkAction
*action
, gpointer user_data
);
53 static void repvehicle_export_csv(GtkWidget
*widget
, gpointer user_data
);
54 static void repvehicle_date_change(GtkWidget
*widget
, gpointer user_data
);
55 static void repvehicle_range_change(GtkWidget
*widget
, gpointer user_data
);
56 static void repvehicle_compute(GtkWidget
*widget
, gpointer user_data
);
57 static void repvehicle_update(GtkWidget
*widget
, gpointer user_data
);
58 static void repvehicle_toggle_minor(GtkWidget
*widget
, gpointer user_data
);
59 static void repvehicle_setup(struct repvehicle_data
*data
);
60 static gboolean
repvehicle_window_dispose(GtkWidget
*widget
, GdkEvent
*event
, gpointer user_data
);
61 static GtkWidget
*create_list_repvehicle(void);
64 static GtkActionEntry entries
[] = {
65 { "Refresh" , ICONNAME_HB_REFRESH
, N_("Refresh"), NULL
, N_("Refresh results"), G_CALLBACK (repvehicle_action_refresh
) },
67 { "Export" , ICONNAME_HB_FILE_EXPORT
, N_("Export") , NULL
, N_("Export as CSV"), G_CALLBACK (repvehicle_action_export
) },
69 static guint n_entries
= G_N_ELEMENTS (entries
);
71 static const gchar
*ui_info
=
73 " <toolbar name='ToolBar'>"
74 " <toolitem action='Refresh'/>"
76 " <toolitem action='Export'/>"
80 static void repvehicle_date_change(GtkWidget
*widget
, gpointer user_data
)
82 struct repvehicle_data
*data
;
84 DB( g_print("\n[vehiclecost] date change\n") );
86 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
88 data
->filter
->mindate
= gtk_date_entry_get_date(GTK_DATE_ENTRY(data
->PO_mindate
));
89 data
->filter
->maxdate
= gtk_date_entry_get_date(GTK_DATE_ENTRY(data
->PO_maxdate
));
91 // set min/max date for both widget
92 gtk_date_entry_set_maxdate(GTK_DATE_ENTRY(data
->PO_mindate
), data
->filter
->maxdate
);
93 gtk_date_entry_set_mindate(GTK_DATE_ENTRY(data
->PO_maxdate
), data
->filter
->mindate
);
95 g_signal_handler_block(data
->CY_range
, data
->handler_id
[HID_REPVEHICLE_RANGE
]);
96 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
), FLT_RANGE_OTHER
);
97 g_signal_handler_unblock(data
->CY_range
, data
->handler_id
[HID_REPVEHICLE_RANGE
]);
100 repvehicle_compute(widget
, NULL
);
105 static void repvehicle_action_refresh(GtkAction
*action
, gpointer user_data
)
107 struct repvehicle_data
*data
= user_data
;
109 repvehicle_compute(data
->window
, NULL
);
112 static void repvehicle_action_export(GtkAction
*action
, gpointer user_data
)
114 struct repvehicle_data
*data
= user_data
;
116 repvehicle_export_csv(data
->window
, NULL
);
121 static void repvehicle_range_change(GtkWidget
*widget
, gpointer user_data
)
123 struct repvehicle_data
*data
;
126 DB( g_print("\n[vehiclecost] range change\n") );
128 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
130 range
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
));
132 if(range
!= FLT_RANGE_OTHER
)
134 filter_preset_daterange_set(data
->filter
, range
, 0);
136 g_signal_handler_block(data
->PO_mindate
, data
->handler_id
[HID_REPVEHICLE_MINDATE
]);
137 g_signal_handler_block(data
->PO_maxdate
, data
->handler_id
[HID_REPVEHICLE_MAXDATE
]);
139 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_mindate
), data
->filter
->mindate
);
140 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_maxdate
), data
->filter
->maxdate
);
142 g_signal_handler_unblock(data
->PO_mindate
, data
->handler_id
[HID_REPVEHICLE_MINDATE
]);
143 g_signal_handler_unblock(data
->PO_maxdate
, data
->handler_id
[HID_REPVEHICLE_MAXDATE
]);
145 repvehicle_compute(widget
, NULL
);
149 static gint
repvehicle_transaction_compare_func(CarCost
*a
, CarCost
*b
)
153 //retval = (gint)(a->ope->date - b->ope->date);
155 retval
= a
->meter
- b
->meter
;
162 static CarCost
*repvehicle_eval_memofield(CarCost
*item
, gchar
*text
)
170 d
= g_strstr_len(text
, len
, "d=");
171 v1
= g_strstr_len(text
, len
, "v=");
172 v2
= g_strstr_len(text
, len
, "v~");
175 item
->meter
= atol(d
+2);
178 item
->fuel
= g_strtod(v1
+2, NULL
);
179 item
->partial
= FALSE
;
183 item
->fuel
= g_strtod(v2
+2, NULL
);
184 item
->partial
= TRUE
;
193 static void repvehicle_export_csv(GtkWidget
*widget
, gpointer user_data
)
195 struct repvehicle_data
*data
;
199 gchar
*filename
= NULL
;
201 gchar
*outstr
, *name
;
203 DB( g_print("\n[repvehicle] export csv\n") );
205 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
207 name
= "hb-vehicle.csv";
209 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_SAVE
, &filename
, name
) == TRUE
)
211 DB( g_print(" + filename is %s\n", filename
) );
213 io
= g_io_channel_new_file(filename
, "w", NULL
);
217 outstr
= g_strdup_printf("%s;%s;%s;%s;%s;%s;%s;%s\n",
224 PREFS
->vehicle_unit_100
,
225 PREFS
->vehicle_unit_distbyvol
227 g_io_channel_write_chars(io
, outstr
, -1, NULL
, NULL
);
230 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
));
231 valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model
), &iter
);
235 gint meter
, dist
, distbyvol
;
236 gdouble fuel
, price
, amount
, centkm
;
240 gtk_tree_model_get (model
, &iter
,
241 LST_CAR_DATE
, &julian
,
242 LST_CAR_METER
, &meter
,
243 LST_CAR_FUEL
, &fuel
,
244 LST_CAR_PRICE
, &price
,
245 LST_CAR_AMOUNT
, &amount
,
246 LST_CAR_DIST
, &dist
,
247 LST_CAR_100KM
, ¢km
,
248 LST_CAR_DISTBYVOL
, &distbyvol
,
249 LST_CAR_PARTIAL
, &partial
,
252 hb_sprint_date(datebuf
, julian
);
254 outstr
= g_strdup_printf("%s;%d;%.2f;%.2f;%.2f;%d;%.2f;%d;%d\n",
255 datebuf
, meter
, fuel
, price
, amount
, dist
, centkm
, distbyvol
, partial
);
256 g_io_channel_write_chars(io
, outstr
, -1, NULL
, NULL
);
258 DB( g_print("%s", outstr
) );
262 valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &iter
);
265 g_io_channel_unref (io
);
273 static void repvehicle_compute(GtkWidget
*widget
, gpointer user_data
)
275 struct repvehicle_data
*data
;
279 DB( g_print("\n[vehiclecost] compute\n") );
281 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
284 da_vehiclecost_destroy(data
->vehicle_list
);
285 data
->vehicle_list
= NULL
;
287 // get the category key
288 catkey
= ui_cat_comboboxentry_get_key(GTK_COMBO_BOX(data
->PO_cat
));
290 /* do nothing if cat is 0 */
294 DB( g_print(" -> active cat is %d\n", catkey
) );
296 g_queue_free (data
->txn_queue
);
297 data
->txn_queue
= hbfile_transaction_get_partial(data
->filter
->mindate
, data
->filter
->maxdate
);
299 // collect transactions
300 // the purpose here is to collect all cat transaction
301 // and precompute item-> meter/fuel/partial
302 list
= g_queue_peek_head_link(data
->txn_queue
);
305 Transaction
*ope
= list
->data
;
309 // eval normal transaction
310 if(!(ope
->flags
& OF_SPLIT
))
312 cat
= da_cat_get(ope
->kcat
);
313 if( cat
&& (cat
->key
== catkey
|| cat
->parent
== catkey
) )
315 item
= da_vehiclecost_malloc();
316 item
->date
= ope
->date
;
317 item
->memo
= ope
->memo
;
318 // get amount in base currency
319 //item->amount = ope->amount;
320 item
->amount
= hb_amount_base(ope
->amount
, ope
->kcur
);
322 item
= repvehicle_eval_memofield(item
, ope
->memo
);
323 data
->vehicle_list
= g_list_append(data
->vehicle_list
, item
);
324 DB( g_print(" -> store acc=%d '%s' %.2f\n", ope
->kacc
, ope
->memo
, ope
->amount
) );
327 // eval split transaction
330 guint i
, nbsplit
= da_splits_length(ope
->splits
);
333 DB( g_print(" -> nb split %d\n", nbsplit
) );
335 for(i
=0;i
<nbsplit
;i
++)
337 split
= da_splits_get(ope
->splits
, i
);
338 cat
= da_cat_get(split
->kcat
);
340 DB( g_print(" -> eval split '%s'\n", split
->memo
) );
342 if( cat
&& (cat
->key
== catkey
|| cat
->parent
== catkey
) )
344 item
= da_vehiclecost_malloc();
345 item
->date
= ope
->date
;
346 item
->memo
= split
->memo
;
347 // get amount in base currency
348 //item->amount = split->amount;
349 item
->amount
= hb_amount_base(split
->amount
, ope
->kcur
);
351 item
= repvehicle_eval_memofield(item
, split
->memo
);
352 data
->vehicle_list
= g_list_append(data
->vehicle_list
, item
);
353 DB( g_print(" -> store split part acc=%d '%s' %.2f\n", ope
->kacc
, split
->memo
, split
->amount
) );
358 list
= g_list_next(list
);
361 // sort by meter #399170
362 data
->vehicle_list
= g_list_sort(data
->vehicle_list
, (GCompareFunc
)repvehicle_transaction_compare_func
);
365 repvehicle_update(widget
, NULL
);
369 static void repvehicle_update(GtkWidget
*widget
, gpointer user_data
)
371 struct repvehicle_data
*data
;
377 int nb_fullrefuel
= 0;
380 DB( g_print("\n[vehiclecost] update\n") );
382 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
384 // clear and detach our model
385 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
));
386 gtk_list_store_clear (GTK_LIST_STORE(model
));
388 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_report
), NULL
);
390 data
->total_misccost
= 0;
391 data
->total_fuelcost
= 0;
392 data
->total_fuel
= 0;
393 data
->total_dist
= 0;
395 gdouble partial_fuel
= 0;
396 guint partial_dist
= 0;
399 list
= g_list_first(data
->vehicle_list
);
402 CarCost
*item
= list
->data
;
408 if( (item
->date
>= data
->filter
->mindate
) && (item
->date
<= data
->filter
->maxdate
) )
410 trn_amount
= item
->amount
;
412 if( item
->meter
== 0 )
414 data
->total_misccost
+= trn_amount
;
420 //previtem = g_list_nth_data(data->vehicle_list, nb_refuel-1);
421 //if(previtem != NULL) previtem->dist = item->meter - previtem->meter;
422 //DB( g_print(" + previous item dist = %d\n", item->meter - previtem->meter) );
423 item
->dist
= item
->meter
- lastmeter
;
425 //DB( g_print(" + last meter = %d\n", lastmeter) );
429 lastmeter
= item
->meter
;
432 DB( g_print("\n eval %02d :: d=%d v=%.2f $%.2f dist=%d\n", nb_refuel
, item
->meter
, item
->fuel
, trn_amount
, item
->dist
) );
433 DB( g_print(" + %s :: pf=%.2f pd=%d\n", item
->partial
? "partial" : "full", partial_fuel
, partial_dist
) );
438 //bugfix #159066 partial/full
439 if(item
->partial
== FALSE
)
441 //#1836380 if we don't have a full already, the computing will be wrong
442 if( nb_fullrefuel
> 0 )
444 // full refuel after partial
445 if(partial_fuel
&& partial_dist
)
447 partial_fuel
+= item
->fuel
;
448 partial_dist
+= item
->dist
;
450 centkm
= partial_dist
!= 0 ? partial_fuel
* 100 / partial_dist
: 0;
451 DB( g_print(" + centkm=%.2f %.2f * 100 / %d (full after partial)\n", centkm
, partial_fuel
, partial_dist
) );
456 centkm
= item
->dist
!= 0 ? item
->fuel
* 100 / item
->dist
: 0;
457 DB( g_print(" + centkm=%.2f :: %.2f * 100 / %d (full after full)\n", centkm
, item
->fuel
, item
->dist
) );
467 partial_fuel
+= item
->fuel
;
468 partial_dist
+= item
->dist
;
470 DB( g_print(" + centkm= not computable\n") );
475 distbyvol
= hb_amount_round((1/centkm
)*100, 0);
478 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
480 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
481 LST_CAR_DATE
, item
->date
,
482 LST_CAR_MEMO
, item
->memo
,
483 LST_CAR_METER
, item
->meter
,
484 LST_CAR_FUEL
, item
->fuel
,
485 LST_CAR_PRICE
, ABS(trn_amount
) / item
->fuel
,
486 LST_CAR_AMOUNT
, trn_amount
,
488 LST_CAR_100KM
, centkm
,
489 LST_CAR_DISTBYVOL
, distbyvol
,
490 LST_CAR_PARTIAL
, item
->partial
,
493 //DB( g_print("\n insert d=%d v=%4.2f $%8.2f %d %5.2f\n", item->meter, item->fuel, trn_amount, dist, centkm) );
497 data
->total_fuelcost
+= trn_amount
;
498 data
->total_fuel
+= item
->fuel
;
499 data
->total_dist
+= item
->dist
;
505 list
= g_list_next(list
);
508 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_report
), model
);
509 g_object_unref(model
);
512 gdouble coef
= data
->total_dist
? 100 / (gdouble
)data
->total_dist
: 0;
514 GLOBALS
->minor
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_minor
));
517 DB( g_print(" coef = 100 / %.2f = %.2f\n", (gdouble
)data
->total_dist
, coef
) );
519 // row 1 is for 100km
521 gtk_label_set_text(GTK_LABEL(data->LA_total[1][1]), "1:1"); //Consumption
522 gtk_label_set_text(GTK_LABEL(data->LA_total[2][1]), "2:1"); //Fuel cost
523 gtk_label_set_text(GTK_LABEL(data->LA_total[3][1]), "3:1"); //Other cost
524 gtk_label_set_text(GTK_LABEL(data->LA_total[4][1]), "4:1"); //Total cost
528 buf
= g_strdup_printf(PREFS
->vehicle_unit_vol
, data
->total_fuel
* coef
);
529 gtk_label_set_text(GTK_LABEL(data
->LA_avera
[CAR_RES_FUEL
]), buf
);
533 //hb_label_set_colvaluecurr(GTK_LABEL(data->LA_avera[CAR_RES_FUELCOST]), data->total_fuelcost * coef, GLOBALS->kcur);
534 hb_label_set_colvalue(GTK_LABEL(data
->LA_avera
[CAR_RES_FUELCOST
]), data
->total_fuelcost
* coef
, GLOBALS
->kcur
, GLOBALS
->minor
);
537 //hb_label_set_colvaluecurr(GTK_LABEL(data->LA_avera[CAR_RES_OTHERCOST]), data->total_misccost * coef, GLOBALS->kcur);
538 hb_label_set_colvalue(GTK_LABEL(data
->LA_avera
[CAR_RES_OTHERCOST
]), data
->total_misccost
* coef
, GLOBALS
->kcur
, GLOBALS
->minor
);
541 //hb_label_set_colvaluecurr(GTK_LABEL(data->LA_avera[CAR_RES_TOTALCOST]), (data->total_fuelcost + data->total_misccost) * coef, GLOBALS->kcur);
542 hb_label_set_colvalue(GTK_LABEL(data
->LA_avera
[CAR_RES_TOTALCOST
]), (data
->total_fuelcost
+ data
->total_misccost
) * coef
, GLOBALS
->kcur
, GLOBALS
->minor
);
545 // row 2 is for total
547 gtk_label_set_text(GTK_LABEL(data->LA_total[1][2]), "1:2"); //Consumption
548 gtk_label_set_text(GTK_LABEL(data->LA_total[2][2]), "2:2"); //Fuel cost
549 gtk_label_set_text(GTK_LABEL(data->LA_total[3][2]), "3:2"); //Other cost
550 gtk_label_set_text(GTK_LABEL(data->LA_total[4][2]), "4:2"); //Total
554 buf
= g_strdup_printf(PREFS
->vehicle_unit_dist
, data
->total_dist
);
555 gtk_label_set_text(GTK_LABEL(data
->LA_total
[CAR_RES_METER
]), buf
);
559 buf
= g_strdup_printf(PREFS
->vehicle_unit_vol
, data
->total_fuel
);
560 gtk_label_set_text(GTK_LABEL(data
->LA_total
[CAR_RES_FUEL
]), buf
);
564 //hb_label_set_colvaluecurr(GTK_LABEL(data->LA_total[CAR_RES_FUELCOST]), data->total_fuelcost, GLOBALS->kcur);
565 hb_label_set_colvalue(GTK_LABEL(data
->LA_total
[CAR_RES_FUELCOST
]), data
->total_fuelcost
, GLOBALS
->kcur
, GLOBALS
->minor
);
568 //hb_label_set_colvaluecurr(GTK_LABEL(data->LA_total[CAR_RES_OTHERCOST]), data->total_misccost, GLOBALS->kcur);
569 hb_label_set_colvalue(GTK_LABEL(data
->LA_total
[CAR_RES_OTHERCOST
]), data
->total_misccost
, GLOBALS
->kcur
, GLOBALS
->minor
);
572 //hb_label_set_colvaluecurr(GTK_LABEL(data->LA_total[CAR_RES_TOTALCOST]), data->total_fuelcost + data->total_misccost, GLOBALS->kcur);
573 hb_label_set_colvalue(GTK_LABEL(data
->LA_total
[CAR_RES_TOTALCOST
]), data
->total_fuelcost
+ data
->total_misccost
, GLOBALS
->kcur
, GLOBALS
->minor
);
578 static void repvehicle_toggle_minor(GtkWidget
*widget
, gpointer user_data
)
580 struct repvehicle_data
*data
;
582 DB( g_print("\n[vehiclecost] toggle\n") );
584 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
586 repvehicle_update(widget
, NULL
);
587 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_report
));
591 statistic_update_total(widget,NULL);
593 //hbfile_update(data->LV_acc, (gpointer)4);
594 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_report));
596 minor = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_minor));
597 gtk_chart_show_minor(GTK_CHART(data->RE_bar), minor);
598 gtk_chart_show_minor(GTK_CHART(data->RE_pie), minor);
606 static void repvehicle_setup(struct repvehicle_data
*data
)
608 DB( g_print("\n[vehiclecost] setup\n") );
610 data
->txn_queue
= g_queue_new ();
611 data
->vehicle_list
= NULL
;
613 data
->filter
= da_flt_malloc();
614 filter_reset(data
->filter
);
616 /* 3.4 : make int transfer out of stats */
617 data
->filter
->option
[FILTER_PAYMODE
] = 1;
618 data
->filter
->paymode
[PAYMODE_INTXFER
] = FALSE
;
620 filter_preset_daterange_set(data
->filter
, PREFS
->date_range_rep
, 0);
622 g_signal_handler_block(data
->PO_mindate
, data
->handler_id
[HID_REPVEHICLE_MINDATE
]);
623 g_signal_handler_block(data
->PO_maxdate
, data
->handler_id
[HID_REPVEHICLE_MAXDATE
]);
625 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_mindate
), data
->filter
->mindate
);
626 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_maxdate
), data
->filter
->maxdate
);
628 g_signal_handler_unblock(data
->PO_mindate
, data
->handler_id
[HID_REPVEHICLE_MINDATE
]);
629 g_signal_handler_unblock(data
->PO_maxdate
, data
->handler_id
[HID_REPVEHICLE_MAXDATE
]);
632 ui_cat_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_cat
), GLOBALS
->h_cat
);
634 g_signal_handler_block(data
->PO_cat
, data
->handler_id
[HID_REPVEHICLE_VEHICLE
]);
635 ui_cat_comboboxentry_set_active(GTK_COMBO_BOX(data
->PO_cat
), GLOBALS
->vehicle_category
);
636 g_signal_handler_unblock(data
->PO_cat
, data
->handler_id
[HID_REPVEHICLE_VEHICLE
]);
646 static gboolean
repvehicle_window_dispose(GtkWidget
*widget
, GdkEvent
*event
, gpointer user_data
)
648 struct repvehicle_data
*data
= user_data
;
649 struct WinGeometry
*wg
;
651 DB( g_print("\n[vehiclecost] dispose\n") );
653 g_queue_free (data
->txn_queue
);
655 da_vehiclecost_destroy(data
->vehicle_list
);
657 da_flt_free(data
->filter
);
661 //store position and size
663 gtk_window_get_position(GTK_WINDOW(widget
), &wg
->l
, &wg
->t
);
664 gtk_window_get_size(GTK_WINDOW(widget
), &wg
->w
, &wg
->h
);
666 DB( g_print(" window: l=%d, t=%d, w=%d, h=%d\n", wg
->l
, wg
->t
, wg
->w
, wg
->h
) );
668 //enable define windows
669 GLOBALS
->define_off
--;
670 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
));
676 // the window creation
677 GtkWidget
*repcost_window_new(void)
679 struct repvehicle_data
*data
;
680 struct WinGeometry
*wg
;
681 GtkWidget
*window
, *mainvbox
, *hbox
, *vbox
, *treeview
;
682 GtkWidget
*label
, *widget
, *table
;
685 GtkActionGroup
*actions
;
687 GError
*error
= NULL
;
689 data
= g_malloc0(sizeof(struct repvehicle_data
));
690 if(!data
) return NULL
;
692 DB( g_print("\n[vehiclecost] new\n") );
694 //disable define windows
695 GLOBALS
->define_off
++;
696 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
));
698 /* create window, etc */
699 window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
700 data
->window
= window
;
702 //store our window private data
703 g_object_set_data(G_OBJECT(window
), "inst_data", (gpointer
)data
);
704 DB( g_print(" - new window=%p, inst_data=%p\n", window
, data
) );
706 gtk_window_set_title (GTK_WINDOW (window
), _("Vehicle cost report"));
708 //set the window icon
709 gtk_window_set_icon_name(GTK_WINDOW (window
), ICONNAME_HB_REP_CAR
);
714 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
715 gtk_container_add (GTK_CONTAINER (window
), mainvbox
);
717 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
718 gtk_box_pack_start (GTK_BOX (mainvbox
), hbox
, TRUE
, TRUE
, 0);
721 table
= gtk_grid_new ();
722 gtk_widget_set_hexpand (GTK_WIDGET(table
), FALSE
);
723 gtk_box_pack_start (GTK_BOX (hbox
), table
, FALSE
, FALSE
, 0);
725 gtk_container_set_border_width (GTK_CONTAINER (table
), SPACING_SMALL
);
726 gtk_grid_set_row_spacing (GTK_GRID (table
), SPACING_SMALL
);
727 gtk_grid_set_column_spacing (GTK_GRID (table
), SPACING_MEDIUM
);
730 label
= make_label_group(_("Display"));
731 gtk_grid_attach (GTK_GRID (table
), label
, 0, row
, 3, 1);
734 label
= make_label_widget(_("Vehi_cle:"));
735 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
737 widget
= ui_cat_comboboxentry_new(label
);
738 data
->PO_cat
= widget
;
739 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
742 widget
= gtk_check_button_new_with_mnemonic (_("Euro _minor"));
743 data
->CM_minor
= widget
;
744 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
747 widget
= gtk_separator_new(GTK_ORIENTATION_HORIZONTAL
);
748 gtk_grid_attach (GTK_GRID (table
), widget
, 0, row
, 3, 1);
751 label
= make_label_group(_("Date filter"));
752 gtk_grid_attach (GTK_GRID (table
), label
, 0, row
, 3, 1);
755 label
= make_label_widget(_("_Range:"));
756 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
757 data
->CY_range
= make_daterange(label
, DATE_RANGE_CUSTOM_DISABLE
);
758 gtk_grid_attach (GTK_GRID (table
), data
->CY_range
, 2, row
, 1, 1);
761 label
= make_label_widget(_("_From:"));
762 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
763 data
->PO_mindate
= gtk_date_entry_new();
764 gtk_grid_attach (GTK_GRID (table
), data
->PO_mindate
, 2, row
, 1, 1);
767 label
= make_label_widget(_("_To:"));
768 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
769 data
->PO_maxdate
= gtk_date_entry_new();
770 gtk_grid_attach (GTK_GRID (table
), data
->PO_maxdate
, 2, row
, 1, 1);
773 //part: info + report
774 vbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
775 gtk_box_pack_start (GTK_BOX (hbox
), vbox
, TRUE
, TRUE
, 0);
778 actions
= gtk_action_group_new ("default");
781 gtk_action_group_set_translation_domain(actions
, GETTEXT_PACKAGE
);
783 // data to action callbacks is set here (data)
784 gtk_action_group_add_actions (actions
, entries
, n_entries
, data
);
786 /* set which action should have priority in the toolbar */
787 //action = gtk_action_group_get_action(actions, "Refresh");
788 //g_object_set(action, "is_important", TRUE, NULL);
791 ui
= gtk_ui_manager_new ();
792 gtk_ui_manager_insert_action_group (ui
, actions
, 0);
793 gtk_window_add_accel_group (GTK_WINDOW (window
), gtk_ui_manager_get_accel_group (ui
));
795 if (!gtk_ui_manager_add_ui_from_string (ui
, ui_info
, -1, &error
))
797 g_message ("building UI failed: %s", error
->message
);
798 g_error_free (error
);
802 data
->actions
= actions
;
805 data
->TB_bar
= gtk_ui_manager_get_widget (ui
, "/ToolBar");
806 gtk_box_pack_start (GTK_BOX (vbox
), data
->TB_bar
, FALSE
, FALSE
, 0);
810 table
= gtk_grid_new ();
811 gtk_widget_set_hexpand (GTK_WIDGET(table
), FALSE
);
812 gtk_box_pack_start (GTK_BOX (vbox
), table
, FALSE
, FALSE
, 0);
814 gtk_container_set_border_width (GTK_CONTAINER (table
), SPACING_SMALL
);
815 gtk_grid_set_row_spacing (GTK_GRID (table
), SPACING_SMALL
);
816 gtk_grid_set_column_spacing (GTK_GRID (table
), SPACING_MEDIUM
);
820 label
= make_label_widget(_("Meter:"));
821 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
824 label
= make_label_widget(_("Consumption:"));
825 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
828 label
= make_label_widget(_("Fuel cost:"));
829 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
832 label
= make_label_widget(_("Other cost:"));
833 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
836 label
= make_label_widget(_("Total cost:"));
837 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
841 label
= make_label_widget(PREFS
->vehicle_unit_100
);
842 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
844 for(col
= 1;col
<MAX_CAR_RES
;col
++)
846 label
= make_label(NULL
, 1.0, 0.5);
847 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
848 data
->LA_avera
[col
] = label
;
853 label
= make_label_widget(_("Total"));
854 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
856 for(col
= 1;col
<MAX_CAR_RES
;col
++)
858 label
= make_label(NULL
, 1.0, 0.5);
859 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
860 data
->LA_total
[col
] = label
;
865 widget
= gtk_scrolled_window_new (NULL
, NULL
);
866 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget
), GTK_SHADOW_ETCHED_IN
);
867 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (widget
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
869 treeview
= create_list_repvehicle();
870 data
->LV_report
= treeview
;
871 gtk_container_add (GTK_CONTAINER(widget
), treeview
);
872 gtk_box_pack_start (GTK_BOX (vbox
), widget
, TRUE
, TRUE
, 0);
875 //todo:should move this
876 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_minor
),GLOBALS
->minor
);
880 /* attach our minor to treeview */
881 g_object_set_data(G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
))), "minor", (gpointer
)data
->CM_minor
);
886 g_signal_connect (window
, "delete-event", G_CALLBACK (repvehicle_window_dispose
), (gpointer
)data
);
888 g_signal_connect (data
->CM_minor
, "toggled", G_CALLBACK (repvehicle_toggle_minor
), NULL
);
890 data
->handler_id
[HID_REPVEHICLE_MINDATE
] = g_signal_connect (data
->PO_mindate
, "changed", G_CALLBACK (repvehicle_date_change
), (gpointer
)data
);
891 data
->handler_id
[HID_REPVEHICLE_MAXDATE
] = g_signal_connect (data
->PO_maxdate
, "changed", G_CALLBACK (repvehicle_date_change
), (gpointer
)data
);
893 data
->handler_id
[HID_REPVEHICLE_RANGE
] = g_signal_connect (data
->CY_range
, "changed", G_CALLBACK (repvehicle_range_change
), NULL
);
895 data
->handler_id
[HID_REPVEHICLE_VEHICLE
] = g_signal_connect (data
->PO_cat
, "changed", G_CALLBACK (repvehicle_compute
), NULL
);
898 //setup, init and show window
899 repvehicle_setup(data
);
903 if(PREFS->toolbar_style == 0)
904 gtk_toolbar_unset_style(GTK_TOOLBAR(data->TB_bar));
906 gtk_toolbar_set_style(GTK_TOOLBAR(data->TB_bar), PREFS->toolbar_style-1);
909 //setup, init and show window
911 gtk_window_move(GTK_WINDOW(window
), wg
->l
, wg
->t
);
912 gtk_window_resize(GTK_WINDOW(window
), wg
->w
, wg
->h
);
914 gtk_widget_show_all (window
);
917 if( PREFS
->euro_active
)
918 gtk_widget_show(data
->CM_minor
);
920 gtk_widget_hide(data
->CM_minor
);
924 if( PREFS
->date_range_rep
)
925 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
), PREFS
->date_range_rep
);
927 repvehicle_compute(window
, NULL
);
933 ** ============================================================================
936 static void repvehicle_date_cell_data_function (GtkTreeViewColumn
*col
, GtkCellRenderer
*renderer
, GtkTreeModel
*model
, GtkTreeIter
*iter
, gpointer user_data
)
942 gtk_tree_model_get(model
, iter
,
943 LST_CAR_DATE
, &julian
,
946 date
= g_date_new_julian (julian
);
947 g_date_strftime (buf
, 256-1, PREFS
->date_format
, date
);
950 g_object_set(renderer
, "text", buf
, NULL
);
953 static void repvehicle_distance_cell_data_function (GtkTreeViewColumn
*col
, GtkCellRenderer
*renderer
, GtkTreeModel
*model
, GtkTreeIter
*iter
, gpointer user_data
)
958 gtk_tree_model_get(model
, iter
, user_data
, &distance
, -1);
962 text
= g_strdup_printf(PREFS
->vehicle_unit_dist
, distance
);
963 g_object_set(renderer
, "text", text
, NULL
);
967 g_object_set(renderer
, "text", "-", NULL
);
970 static void repvehicle_volume_cell_data_function (GtkTreeViewColumn
*col
, GtkCellRenderer
*renderer
, GtkTreeModel
*model
, GtkTreeIter
*iter
, gpointer user_data
)
976 gtk_tree_model_get(model
, iter
, user_data
, &volume
, LST_CAR_PARTIAL
, &partial
, -1);
980 text
= g_strdup_printf(PREFS
->vehicle_unit_vol
, volume
);
981 g_object_set(renderer
,
984 "style", partial
? PANGO_STYLE_ITALIC
: PANGO_STYLE_NORMAL
,
990 g_object_set(renderer
, "text", "-", NULL
);
993 static void repvehicle_amount_cell_data_function (GtkTreeViewColumn
*col
,
994 GtkCellRenderer
*renderer
,
1001 gchar buf
[G_ASCII_DTOSTR_BUF_SIZE
];
1003 gtk_tree_model_get(model
, iter
,
1009 hb_strfmon(buf
, G_ASCII_DTOSTR_BUF_SIZE
-1, value
, GLOBALS
->kcur
, GLOBALS
->minor
);
1011 color
= get_normal_color_amount(value
);
1013 g_object_set(renderer
,
1014 "foreground", color
,
1019 g_object_set(renderer
, "text", "", NULL
);
1023 static GtkTreeViewColumn
*volume_list_repvehicle_column(gchar
*name
, gint id
)
1025 GtkTreeViewColumn
*column
;
1026 GtkCellRenderer
*renderer
;
1028 column
= gtk_tree_view_column_new();
1029 gtk_tree_view_column_set_title(column
, name
);
1030 renderer
= gtk_cell_renderer_text_new ();
1031 g_object_set(renderer
, "xalign", 1.0, NULL
);
1032 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1033 gtk_tree_view_column_set_cell_data_func(column
, renderer
, repvehicle_volume_cell_data_function
, GINT_TO_POINTER(id
), NULL
);
1034 gtk_tree_view_column_set_alignment (column
, 0.5);
1035 //gtk_tree_view_column_set_sort_column_id (column, id);
1039 static GtkTreeViewColumn
*distance_list_repvehicle_column(gchar
*name
, gint id
)
1041 GtkTreeViewColumn
*column
;
1042 GtkCellRenderer
*renderer
;
1044 column
= gtk_tree_view_column_new();
1045 gtk_tree_view_column_set_title(column
, name
);
1046 renderer
= gtk_cell_renderer_text_new ();
1047 g_object_set(renderer
, "xalign", 1.0, NULL
);
1048 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1049 gtk_tree_view_column_set_cell_data_func(column
, renderer
, repvehicle_distance_cell_data_function
, GINT_TO_POINTER(id
), NULL
);
1050 gtk_tree_view_column_set_alignment (column
, 0.5);
1051 //gtk_tree_view_column_set_sort_column_id (column, id);
1055 static GtkTreeViewColumn
*amount_list_repvehicle_column(gchar
*name
, gint id
)
1057 GtkTreeViewColumn
*column
;
1058 GtkCellRenderer
*renderer
;
1060 column
= gtk_tree_view_column_new();
1061 gtk_tree_view_column_set_title(column
, name
);
1062 renderer
= gtk_cell_renderer_text_new ();
1063 g_object_set(renderer
, "xalign", 1.0, NULL
);
1064 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1065 gtk_tree_view_column_set_cell_data_func(column
, renderer
, repvehicle_amount_cell_data_function
, GINT_TO_POINTER(id
), NULL
);
1066 gtk_tree_view_column_set_alignment (column
, 0.5);
1067 //gtk_tree_view_column_set_sort_column_id (column, id);
1073 ** create our statistic list
1075 static GtkWidget
*create_list_repvehicle(void)
1077 GtkListStore
*store
;
1079 GtkCellRenderer
*renderer
;
1080 GtkTreeViewColumn
*column
;
1082 /* create list store */
1083 store
= gtk_list_store_new(
1097 view
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
));
1098 g_object_unref(store
);
1100 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view
), PREFS
->grid_lines
);
1103 column
= gtk_tree_view_column_new();
1104 gtk_tree_view_column_set_title(column
, _("Date"));
1105 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1106 renderer
= gtk_cell_renderer_text_new();
1107 g_object_set(renderer
, "xalign", 1.0, NULL
);
1108 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1109 //gtk_tree_view_column_add_attribute(column, renderer, "text", LST_CAR_DATE);
1110 gtk_tree_view_column_set_alignment (column
, 0.5);
1111 gtk_tree_view_column_set_cell_data_func(column
, renderer
, repvehicle_date_cell_data_function
, NULL
, NULL
);
1127 column = gtk_tree_view_column_new();
1128 gtk_tree_view_column_set_title(column, _("Memo"));
1129 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
1130 renderer = gtk_cell_renderer_text_new();
1131 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1132 gtk_tree_view_column_add_attribute(column, renderer, "text", LST_CAR_MEMO);
1133 //gtk_tree_view_column_set_cell_data_func(column, renderer, repvehicle_text_cell_data_function, NULL, NULL);
1137 column
= distance_list_repvehicle_column(_("Meter"), LST_CAR_METER
);
1138 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1140 /* column: Fuel load */
1141 column
= volume_list_repvehicle_column(_("Fuel"), LST_CAR_FUEL
);
1142 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1144 /* column: Price by unit */
1145 column
= amount_list_repvehicle_column(_("Price"), LST_CAR_PRICE
);
1146 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1148 /* column: Amount */
1149 column
= amount_list_repvehicle_column(_("Amount"), LST_CAR_AMOUNT
);
1150 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1152 /* column: Distance done */
1153 column
= distance_list_repvehicle_column(_("Dist."), LST_CAR_DIST
);
1154 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1156 /* column: consumption for 100Km */
1157 column
= volume_list_repvehicle_column(PREFS
->vehicle_unit_100
, LST_CAR_100KM
);
1158 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1160 /* column: km by liter (distance by volume */
1161 column
= distance_list_repvehicle_column(PREFS
->vehicle_unit_distbyvol
, LST_CAR_DISTBYVOL
);
1162 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1165 /* column last: empty */
1166 column
= gtk_tree_view_column_new();
1167 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);