1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2016 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_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("(repvehicle) 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 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->CY_range
), 11);
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("(repvehicle) range change\n") );
128 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
130 range
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_range
));
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("(repvehicle) 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 some datas
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
->wording
= ope
->wording
;
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
->wording
);
323 data
->vehicle_list
= g_list_append(data
->vehicle_list
, item
);
324 DB( g_print(" -> store acc=%d '%s' %.2f\n", ope
->kacc
, ope
->wording
, ope
->amount
) );
327 // eval split transaction
330 guint i
, nbsplit
= da_splits_count(ope
->splits
);
333 DB( g_print(" -> nb split %d\n", nbsplit
) );
335 for(i
=0;i
<nbsplit
;i
++)
337 split
= 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
->wording
= 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
;
379 DB( g_print("(repvehicle) update\n") );
381 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
383 // clear and detach our model
384 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
));
385 gtk_list_store_clear (GTK_LIST_STORE(model
));
387 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_report
), NULL
);
389 data
->total_misccost
= 0;
390 data
->total_fuelcost
= 0;
391 data
->total_fuel
= 0;
392 data
->total_dist
= 0;
394 gdouble partial_fuel
= 0;
395 guint partial_dist
= 0;
398 list
= g_list_first(data
->vehicle_list
);
401 CarCost
*item
= list
->data
;
407 if( (item
->date
>= data
->filter
->mindate
) && (item
->date
<= data
->filter
->maxdate
) )
409 trn_amount
= item
->amount
;
411 if( item
->meter
== 0 )
413 data
->total_misccost
+= trn_amount
;
419 //previtem = g_list_nth_data(data->vehicle_list, nb_refuel-1);
420 //if(previtem != NULL) previtem->dist = item->meter - previtem->meter;
421 //DB( g_print(" + previous item dist = %d\n", item->meter - previtem->meter) );
422 item
->dist
= item
->meter
- lastmeter
;
424 //DB( g_print(" + last meter = %d\n", lastmeter) );
428 lastmeter
= item
->meter
;
431 DB( g_print(" eval : d=%d v=%4.2f $%8.2f dist=%d\n", item
->meter
, item
->fuel
, trn_amount
, item
->dist
) );
434 if(item
->partial
== FALSE
)
436 // full refuel after partial
437 if(partial_fuel
&& partial_dist
)
439 DB( g_print(" + full refuel after partial\n") );
440 partial_fuel
+= item
->fuel
;
441 partial_dist
+= item
->dist
;
443 centkm
= partial_dist
!= 0 ? partial_fuel
* 100 / partial_dist
: 0;
447 DB( g_print(" + real full refuel\n") );
449 centkm
= item
->dist
!= 0 ? item
->fuel
* 100 / item
->dist
: 0;
457 DB( g_print(" + partial refuel\n") );
458 partial_fuel
+= item
->fuel
;
459 partial_dist
+= item
->dist
;
466 distbyvol
= hb_amount_round((1/centkm
)*100, 0);
468 DB( g_print(" + pf=%.2f pd=%d :: dbv=%d\n", partial_fuel
, partial_dist
, distbyvol
) );
472 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
474 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
475 LST_CAR_DATE
, item
->date
,
476 LST_CAR_WORDING
, item
->wording
,
477 LST_CAR_METER
, item
->meter
,
478 LST_CAR_FUEL
, item
->fuel
,
479 LST_CAR_PRICE
, ABS(trn_amount
) / item
->fuel
,
480 LST_CAR_AMOUNT
, trn_amount
,
482 LST_CAR_100KM
, centkm
,
483 LST_CAR_DISTBYVOL
, distbyvol
,
484 LST_CAR_PARTIAL
, item
->partial
,
487 DB( g_print(" + insert d=%d v=%4.2f $%8.2f %d %5.2f\n", item
->meter
, item
->fuel
, trn_amount
, dist
, centkm
) );
491 data
->total_fuelcost
+= trn_amount
;
492 data
->total_fuel
+= item
->fuel
;
493 data
->total_dist
+= item
->dist
;
499 list
= g_list_next(list
);
502 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_report
), model
);
503 g_object_unref(model
);
506 gdouble coef
= data
->total_dist
? 100 / (gdouble
)data
->total_dist
: 0;
508 GLOBALS
->minor
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_minor
));
511 DB( g_print(" coef = 100 / %.2f = %.2f\n", (gdouble
)data
->total_dist
, coef
) );
513 // row 1 is for 100km
515 gtk_label_set_text(GTK_LABEL(data->LA_total[1][1]), "1:1"); //Consumption
516 gtk_label_set_text(GTK_LABEL(data->LA_total[2][1]), "2:1"); //Fuel cost
517 gtk_label_set_text(GTK_LABEL(data->LA_total[3][1]), "3:1"); //Other cost
518 gtk_label_set_text(GTK_LABEL(data->LA_total[4][1]), "4:1"); //Total cost
522 buf
= g_strdup_printf(PREFS
->vehicle_unit_vol
, data
->total_fuel
* coef
);
523 gtk_label_set_text(GTK_LABEL(data
->LA_avera
[CAR_RES_FUEL
]), buf
);
527 //hb_label_set_colvaluecurr(GTK_LABEL(data->LA_avera[CAR_RES_FUELCOST]), data->total_fuelcost * coef, GLOBALS->kcur);
528 hb_label_set_colvalue(GTK_LABEL(data
->LA_avera
[CAR_RES_FUELCOST
]), data
->total_fuelcost
* coef
, GLOBALS
->kcur
, GLOBALS
->minor
);
531 //hb_label_set_colvaluecurr(GTK_LABEL(data->LA_avera[CAR_RES_OTHERCOST]), data->total_misccost * coef, GLOBALS->kcur);
532 hb_label_set_colvalue(GTK_LABEL(data
->LA_avera
[CAR_RES_OTHERCOST
]), data
->total_misccost
* coef
, GLOBALS
->kcur
, GLOBALS
->minor
);
535 //hb_label_set_colvaluecurr(GTK_LABEL(data->LA_avera[CAR_RES_TOTALCOST]), (data->total_fuelcost + data->total_misccost) * coef, GLOBALS->kcur);
536 hb_label_set_colvalue(GTK_LABEL(data
->LA_avera
[CAR_RES_TOTALCOST
]), (data
->total_fuelcost
+ data
->total_misccost
) * coef
, GLOBALS
->kcur
, GLOBALS
->minor
);
539 // row 2 is for total
541 gtk_label_set_text(GTK_LABEL(data->LA_total[1][2]), "1:2"); //Consumption
542 gtk_label_set_text(GTK_LABEL(data->LA_total[2][2]), "2:2"); //Fuel cost
543 gtk_label_set_text(GTK_LABEL(data->LA_total[3][2]), "3:2"); //Other cost
544 gtk_label_set_text(GTK_LABEL(data->LA_total[4][2]), "4:2"); //Total
548 buf
= g_strdup_printf(PREFS
->vehicle_unit_dist
, data
->total_dist
);
549 gtk_label_set_text(GTK_LABEL(data
->LA_total
[CAR_RES_METER
]), buf
);
553 buf
= g_strdup_printf(PREFS
->vehicle_unit_vol
, data
->total_fuel
);
554 gtk_label_set_text(GTK_LABEL(data
->LA_total
[CAR_RES_FUEL
]), buf
);
558 //hb_label_set_colvaluecurr(GTK_LABEL(data->LA_total[CAR_RES_FUELCOST]), data->total_fuelcost, GLOBALS->kcur);
559 hb_label_set_colvalue(GTK_LABEL(data
->LA_total
[CAR_RES_FUELCOST
]), data
->total_fuelcost
, GLOBALS
->kcur
, GLOBALS
->minor
);
562 //hb_label_set_colvaluecurr(GTK_LABEL(data->LA_total[CAR_RES_OTHERCOST]), data->total_misccost, GLOBALS->kcur);
563 hb_label_set_colvalue(GTK_LABEL(data
->LA_total
[CAR_RES_OTHERCOST
]), data
->total_misccost
, GLOBALS
->kcur
, GLOBALS
->minor
);
566 //hb_label_set_colvaluecurr(GTK_LABEL(data->LA_total[CAR_RES_TOTALCOST]), data->total_fuelcost + data->total_misccost, GLOBALS->kcur);
567 hb_label_set_colvalue(GTK_LABEL(data
->LA_total
[CAR_RES_TOTALCOST
]), data
->total_fuelcost
+ data
->total_misccost
, GLOBALS
->kcur
, GLOBALS
->minor
);
572 static void repvehicle_toggle_minor(GtkWidget
*widget
, gpointer user_data
)
574 struct repvehicle_data
*data
;
576 DB( g_print("(repvehicle) toggle\n") );
578 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
580 repvehicle_update(widget
, NULL
);
581 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_report
));
585 statistic_update_total(widget,NULL);
587 //hbfile_update(data->LV_acc, (gpointer)4);
588 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_report));
590 minor = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_minor));
591 gtk_chart_show_minor(GTK_CHART(data->RE_bar), minor);
592 gtk_chart_show_minor(GTK_CHART(data->RE_pie), minor);
600 static void repvehicle_setup(struct repvehicle_data
*data
)
602 DB( g_print("(repvehicle) setup\n") );
604 data
->txn_queue
= g_queue_new ();
605 data
->vehicle_list
= NULL
;
607 data
->filter
= da_filter_malloc();
608 filter_default_all_set(data
->filter
);
610 /* 3.4 : make int transfer out of stats */
611 data
->filter
->option
[FILTER_PAYMODE
] = 1;
612 data
->filter
->paymode
[PAYMODE_INTXFER
] = FALSE
;
614 filter_preset_daterange_set(data
->filter
, PREFS
->date_range_rep
, 0);
616 g_signal_handler_block(data
->PO_mindate
, data
->handler_id
[HID_REPVEHICLE_MINDATE
]);
617 g_signal_handler_block(data
->PO_maxdate
, data
->handler_id
[HID_REPVEHICLE_MAXDATE
]);
619 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_mindate
), data
->filter
->mindate
);
620 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_maxdate
), data
->filter
->maxdate
);
622 g_signal_handler_unblock(data
->PO_mindate
, data
->handler_id
[HID_REPVEHICLE_MINDATE
]);
623 g_signal_handler_unblock(data
->PO_maxdate
, data
->handler_id
[HID_REPVEHICLE_MAXDATE
]);
626 ui_cat_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_cat
), GLOBALS
->h_cat
);
628 g_signal_handler_block(data
->PO_cat
, data
->handler_id
[HID_REPVEHICLE_VEHICLE
]);
629 ui_cat_comboboxentry_set_active(GTK_COMBO_BOX(data
->PO_cat
), GLOBALS
->vehicle_category
);
630 g_signal_handler_unblock(data
->PO_cat
, data
->handler_id
[HID_REPVEHICLE_VEHICLE
]);
640 static gboolean
repvehicle_window_dispose(GtkWidget
*widget
, GdkEvent
*event
, gpointer user_data
)
642 struct repvehicle_data
*data
= user_data
;
643 struct WinGeometry
*wg
;
645 DB( g_print("(repvehicle) dispose\n") );
647 g_queue_free (data
->txn_queue
);
649 da_vehiclecost_destroy(data
->vehicle_list
);
651 da_filter_free(data
->filter
);
655 //store position and size
657 gtk_window_get_position(GTK_WINDOW(widget
), &wg
->l
, &wg
->t
);
658 gtk_window_get_size(GTK_WINDOW(widget
), &wg
->w
, &wg
->h
);
660 DB( g_print(" window: l=%d, t=%d, w=%d, h=%d\n", wg
->l
, wg
->t
, wg
->w
, wg
->h
) );
662 //enable define windows
663 GLOBALS
->define_off
--;
664 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
));
670 // the window creation
671 GtkWidget
*repcost_window_new(void)
673 struct repvehicle_data
*data
;
674 struct WinGeometry
*wg
;
675 GtkWidget
*window
, *mainvbox
, *hbox
, *vbox
, *treeview
;
676 GtkWidget
*label
, *widget
, *table
;
679 GtkActionGroup
*actions
;
681 GError
*error
= NULL
;
683 data
= g_malloc0(sizeof(struct repvehicle_data
));
684 if(!data
) return NULL
;
686 DB( g_print("(repvehicle) new\n") );
688 //disable define windows
689 GLOBALS
->define_off
++;
690 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(2));
692 /* create window, etc */
693 window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
694 data
->window
= window
;
696 //store our window private data
697 g_object_set_data(G_OBJECT(window
), "inst_data", (gpointer
)data
);
699 gtk_window_set_title (GTK_WINDOW (window
), _("Vehicle cost report"));
701 //set the window icon
702 gtk_window_set_icon_name(GTK_WINDOW (window
), ICONNAME_HB_REP_CAR
);
707 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
708 gtk_container_add (GTK_CONTAINER (window
), mainvbox
);
710 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
711 gtk_box_pack_start (GTK_BOX (mainvbox
), hbox
, TRUE
, TRUE
, 0);
714 table
= gtk_grid_new ();
715 gtk_widget_set_hexpand (GTK_WIDGET(table
), FALSE
);
716 gtk_box_pack_start (GTK_BOX (hbox
), table
, FALSE
, FALSE
, 0);
718 gtk_container_set_border_width (GTK_CONTAINER (table
), SPACING_SMALL
);
719 gtk_grid_set_row_spacing (GTK_GRID (table
), SPACING_SMALL
);
720 gtk_grid_set_column_spacing (GTK_GRID (table
), SPACING_MEDIUM
);
723 label
= make_label_group(_("Display"));
724 gtk_grid_attach (GTK_GRID (table
), label
, 0, row
, 3, 1);
727 label
= make_label_widget(_("Vehi_cle:"));
728 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
730 widget
= ui_cat_comboboxentry_new(label
);
731 data
->PO_cat
= widget
;
732 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
735 widget
= gtk_check_button_new_with_mnemonic (_("Euro _minor"));
736 data
->CM_minor
= widget
;
737 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
740 widget
= gtk_separator_new(GTK_ORIENTATION_HORIZONTAL
);
741 gtk_grid_attach (GTK_GRID (table
), widget
, 0, row
, 3, 1);
744 label
= make_label_group(_("Date filter"));
745 gtk_grid_attach (GTK_GRID (table
), label
, 0, row
, 3, 1);
748 label
= make_label_widget(_("_Range:"));
749 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
750 data
->CY_range
= make_daterange(label
, FALSE
);
751 gtk_grid_attach (GTK_GRID (table
), data
->CY_range
, 2, row
, 1, 1);
754 label
= make_label_widget(_("_From:"));
755 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
756 data
->PO_mindate
= gtk_date_entry_new();
757 gtk_grid_attach (GTK_GRID (table
), data
->PO_mindate
, 2, row
, 1, 1);
760 label
= make_label_widget(_("_To:"));
761 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
762 data
->PO_maxdate
= gtk_date_entry_new();
763 gtk_grid_attach (GTK_GRID (table
), data
->PO_maxdate
, 2, row
, 1, 1);
766 //part: info + report
767 vbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
768 gtk_box_pack_start (GTK_BOX (hbox
), vbox
, TRUE
, TRUE
, 0);
771 actions
= gtk_action_group_new ("Account");
774 gtk_action_group_set_translation_domain(actions
, GETTEXT_PACKAGE
);
776 // data to action callbacks is set here (data)
777 gtk_action_group_add_actions (actions
, entries
, n_entries
, data
);
779 /* set which action should have priority in the toolbar */
780 action
= gtk_action_group_get_action(actions
, "Refresh");
781 g_object_set(action
, "is_important", TRUE
, NULL
);
784 ui
= gtk_ui_manager_new ();
785 gtk_ui_manager_insert_action_group (ui
, actions
, 0);
786 gtk_window_add_accel_group (GTK_WINDOW (window
), gtk_ui_manager_get_accel_group (ui
));
788 if (!gtk_ui_manager_add_ui_from_string (ui
, ui_info
, -1, &error
))
790 g_message ("building UI failed: %s", error
->message
);
791 g_error_free (error
);
795 data
->actions
= actions
;
798 data
->TB_bar
= gtk_ui_manager_get_widget (ui
, "/ToolBar");
799 gtk_box_pack_start (GTK_BOX (vbox
), data
->TB_bar
, FALSE
, FALSE
, 0);
803 table
= gtk_grid_new ();
804 gtk_widget_set_hexpand (GTK_WIDGET(table
), FALSE
);
805 gtk_box_pack_start (GTK_BOX (vbox
), table
, FALSE
, FALSE
, 0);
807 gtk_container_set_border_width (GTK_CONTAINER (table
), SPACING_SMALL
);
808 gtk_grid_set_row_spacing (GTK_GRID (table
), SPACING_SMALL
);
809 gtk_grid_set_column_spacing (GTK_GRID (table
), SPACING_MEDIUM
);
813 label
= make_label_widget(_("Meter:"));
814 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
817 label
= make_label_widget(_("Consumption:"));
818 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
821 label
= make_label_widget(_("Fuel cost:"));
822 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
825 label
= make_label_widget(_("Other cost:"));
826 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
829 label
= make_label_widget(_("Total cost:"));
830 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
834 label
= make_label_widget(PREFS
->vehicle_unit_100
);
835 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
837 for(col
= 1;col
<MAX_CAR_RES
;col
++)
839 label
= make_label(NULL
, 1.0, 0.5);
840 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
841 data
->LA_avera
[col
] = label
;
846 label
= make_label_widget(_("Total"));
847 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
849 for(col
= 1;col
<MAX_CAR_RES
;col
++)
851 label
= make_label(NULL
, 1.0, 0.5);
852 gtk_grid_attach (GTK_GRID (table
), label
, col
, row
, 1, 1);
853 data
->LA_total
[col
] = label
;
858 widget
= gtk_scrolled_window_new (NULL
, NULL
);
859 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget
), GTK_SHADOW_ETCHED_IN
);
860 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (widget
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
862 treeview
= create_list_repvehicle();
863 data
->LV_report
= treeview
;
864 gtk_container_add (GTK_CONTAINER(widget
), treeview
);
865 gtk_box_pack_start (GTK_BOX (vbox
), widget
, TRUE
, TRUE
, 0);
868 //todo:should move this
869 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_minor
),GLOBALS
->minor
);
873 /* attach our minor to treeview */
874 g_object_set_data(G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_report
))), "minor", (gpointer
)data
->CM_minor
);
879 g_signal_connect (window
, "delete-event", G_CALLBACK (repvehicle_window_dispose
), (gpointer
)data
);
881 g_signal_connect (data
->CM_minor
, "toggled", G_CALLBACK (repvehicle_toggle_minor
), NULL
);
883 data
->handler_id
[HID_REPVEHICLE_MINDATE
] = g_signal_connect (data
->PO_mindate
, "changed", G_CALLBACK (repvehicle_date_change
), (gpointer
)data
);
884 data
->handler_id
[HID_REPVEHICLE_MAXDATE
] = g_signal_connect (data
->PO_maxdate
, "changed", G_CALLBACK (repvehicle_date_change
), (gpointer
)data
);
886 data
->handler_id
[HID_REPVEHICLE_RANGE
] = g_signal_connect (data
->CY_range
, "changed", G_CALLBACK (repvehicle_range_change
), NULL
);
888 data
->handler_id
[HID_REPVEHICLE_VEHICLE
] = g_signal_connect (data
->PO_cat
, "changed", G_CALLBACK (repvehicle_compute
), NULL
);
891 //setup, init and show window
892 repvehicle_setup(data
);
896 if(PREFS->toolbar_style == 0)
897 gtk_toolbar_unset_style(GTK_TOOLBAR(data->TB_bar));
899 gtk_toolbar_set_style(GTK_TOOLBAR(data->TB_bar), PREFS->toolbar_style-1);
902 //setup, init and show window
904 gtk_window_move(GTK_WINDOW(window
), wg
->l
, wg
->t
);
905 gtk_window_resize(GTK_WINDOW(window
), wg
->w
, wg
->h
);
907 gtk_widget_show_all (window
);
910 if( PREFS
->euro_active
)
911 gtk_widget_show(data
->CM_minor
);
913 gtk_widget_hide(data
->CM_minor
);
917 if( PREFS
->date_range_rep
)
918 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->CY_range
), PREFS
->date_range_rep
);
920 repvehicle_compute(window
, NULL
);
926 ** ============================================================================
929 static void repvehicle_date_cell_data_function (GtkTreeViewColumn
*col
, GtkCellRenderer
*renderer
, GtkTreeModel
*model
, GtkTreeIter
*iter
, gpointer user_data
)
935 gtk_tree_model_get(model
, iter
,
936 LST_CAR_DATE
, &julian
,
939 date
= g_date_new_julian (julian
);
940 g_date_strftime (buf
, 256-1, PREFS
->date_format
, date
);
943 g_object_set(renderer
, "text", buf
, NULL
);
946 static void repvehicle_distance_cell_data_function (GtkTreeViewColumn
*col
, GtkCellRenderer
*renderer
, GtkTreeModel
*model
, GtkTreeIter
*iter
, gpointer user_data
)
951 gtk_tree_model_get(model
, iter
, user_data
, &distance
, -1);
955 text
= g_strdup_printf(PREFS
->vehicle_unit_dist
, distance
);
956 g_object_set(renderer
, "text", text
, NULL
);
960 g_object_set(renderer
, "text", "-", NULL
);
963 static void repvehicle_volume_cell_data_function (GtkTreeViewColumn
*col
, GtkCellRenderer
*renderer
, GtkTreeModel
*model
, GtkTreeIter
*iter
, gpointer user_data
)
969 gtk_tree_model_get(model
, iter
, user_data
, &volume
, LST_CAR_PARTIAL
, &partial
, -1);
973 text
= g_strdup_printf(PREFS
->vehicle_unit_vol
, volume
);
974 g_object_set(renderer
,
977 "style", partial
? PANGO_STYLE_ITALIC
: PANGO_STYLE_NORMAL
,
983 g_object_set(renderer
, "text", "-", NULL
);
986 static void repvehicle_amount_cell_data_function (GtkTreeViewColumn
*col
,
987 GtkCellRenderer
*renderer
,
994 gchar buf
[G_ASCII_DTOSTR_BUF_SIZE
];
996 gtk_tree_model_get(model
, iter
,
1002 hb_strfmon(buf
, G_ASCII_DTOSTR_BUF_SIZE
-1, value
, GLOBALS
->kcur
, GLOBALS
->minor
);
1004 color
= get_normal_color_amount(value
);
1006 g_object_set(renderer
,
1007 "foreground", color
,
1012 g_object_set(renderer
, "text", "", NULL
);
1016 static GtkTreeViewColumn
*volume_list_repvehicle_column(gchar
*name
, gint id
)
1018 GtkTreeViewColumn
*column
;
1019 GtkCellRenderer
*renderer
;
1021 column
= gtk_tree_view_column_new();
1022 gtk_tree_view_column_set_title(column
, name
);
1023 renderer
= gtk_cell_renderer_text_new ();
1024 g_object_set(renderer
, "xalign", 1.0, NULL
);
1025 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1026 gtk_tree_view_column_set_cell_data_func(column
, renderer
, repvehicle_volume_cell_data_function
, GINT_TO_POINTER(id
), NULL
);
1027 gtk_tree_view_column_set_alignment (column
, 0.5);
1028 //gtk_tree_view_column_set_sort_column_id (column, id);
1032 static GtkTreeViewColumn
*distance_list_repvehicle_column(gchar
*name
, gint id
)
1034 GtkTreeViewColumn
*column
;
1035 GtkCellRenderer
*renderer
;
1037 column
= gtk_tree_view_column_new();
1038 gtk_tree_view_column_set_title(column
, name
);
1039 renderer
= gtk_cell_renderer_text_new ();
1040 g_object_set(renderer
, "xalign", 1.0, NULL
);
1041 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1042 gtk_tree_view_column_set_cell_data_func(column
, renderer
, repvehicle_distance_cell_data_function
, GINT_TO_POINTER(id
), NULL
);
1043 gtk_tree_view_column_set_alignment (column
, 0.5);
1044 //gtk_tree_view_column_set_sort_column_id (column, id);
1048 static GtkTreeViewColumn
*amount_list_repvehicle_column(gchar
*name
, gint id
)
1050 GtkTreeViewColumn
*column
;
1051 GtkCellRenderer
*renderer
;
1053 column
= gtk_tree_view_column_new();
1054 gtk_tree_view_column_set_title(column
, name
);
1055 renderer
= gtk_cell_renderer_text_new ();
1056 g_object_set(renderer
, "xalign", 1.0, NULL
);
1057 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1058 gtk_tree_view_column_set_cell_data_func(column
, renderer
, repvehicle_amount_cell_data_function
, GINT_TO_POINTER(id
), NULL
);
1059 gtk_tree_view_column_set_alignment (column
, 0.5);
1060 //gtk_tree_view_column_set_sort_column_id (column, id);
1066 ** create our statistic list
1068 static GtkWidget
*create_list_repvehicle(void)
1070 GtkListStore
*store
;
1072 GtkCellRenderer
*renderer
;
1073 GtkTreeViewColumn
*column
;
1075 /* create list store */
1076 store
= gtk_list_store_new(
1090 view
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
));
1091 g_object_unref(store
);
1093 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view
), PREFS
->grid_lines
);
1096 column
= gtk_tree_view_column_new();
1097 gtk_tree_view_column_set_title(column
, _("Date"));
1098 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1099 renderer
= gtk_cell_renderer_text_new();
1100 g_object_set(renderer
, "xalign", 1.0, NULL
);
1101 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1102 //gtk_tree_view_column_add_attribute(column, renderer, "text", LST_CAR_DATE);
1103 gtk_tree_view_column_set_alignment (column
, 0.5);
1104 gtk_tree_view_column_set_cell_data_func(column
, renderer
, repvehicle_date_cell_data_function
, NULL
, NULL
);
1118 /* column: Wording */
1120 column = gtk_tree_view_column_new();
1121 gtk_tree_view_column_set_title(column, _("Wording"));
1122 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
1123 renderer = gtk_cell_renderer_text_new();
1124 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1125 gtk_tree_view_column_add_attribute(column, renderer, "text", LST_CAR_WORDING);
1126 //gtk_tree_view_column_set_cell_data_func(column, renderer, repvehicle_text_cell_data_function, NULL, NULL);
1130 column
= distance_list_repvehicle_column(_("Meter"), LST_CAR_METER
);
1131 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1133 /* column: Fuel load */
1134 column
= volume_list_repvehicle_column(_("Fuel"), LST_CAR_FUEL
);
1135 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1137 /* column: Price by unit */
1138 column
= amount_list_repvehicle_column(_("Price"), LST_CAR_PRICE
);
1139 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1141 /* column: Amount */
1142 column
= amount_list_repvehicle_column(_("Amount"), LST_CAR_AMOUNT
);
1143 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1145 /* column: Distance done */
1146 column
= distance_list_repvehicle_column(_("Dist."), LST_CAR_DIST
);
1147 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1149 /* column: consumption for 100Km */
1150 column
= volume_list_repvehicle_column(PREFS
->vehicle_unit_100
, LST_CAR_100KM
);
1151 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1153 /* column: km by liter (distance by volume */
1154 column
= distance_list_repvehicle_column(PREFS
->vehicle_unit_distbyvol
, LST_CAR_DISTBYVOL
);
1155 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
1158 /* column last: empty */
1159 column
= gtk_tree_view_column_new();
1160 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);