]> Dogcows Code - chaz/homebank/blob - src/dsp_mainwindow.c
ea62b80c3994e9c0e6cdbc8b1b80c4cffa62c63f
[chaz/homebank] / src / dsp_mainwindow.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2017 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 "dsp_mainwindow.h"
24
25 #include "list_account.h"
26 #include "list_upcoming.h"
27 #include "list_topspending.h"
28
29 #include "dsp_account.h"
30 #include "ui-assist-import.h"
31 #include "ui-assist-start.h"
32 #include "ui-account.h"
33 #include "ui-currency.h"
34 #include "ui-payee.h"
35 #include "ui-category.h"
36 #include "ui-archive.h"
37 #include "ui-assign.h"
38 #include "ui-budget.h"
39 #include "ui-pref.h"
40 #include "ui-hbfile.h"
41 #include "ui-transaction.h"
42
43 #include "rep_balance.h"
44 #include "rep_budget.h"
45 #include "rep_stats.h"
46 #include "rep_time.h"
47 #include "rep_vehicle.h"
48
49 #include "gtk-chart.h"
50
51 //#define HOMEBANK_URL_HELP "http://homebank.free.fr/help/"
52 #define HOMEBANK_URL_HELP "index.html"
53 #define HOMEBANK_URL_HELP_ONLINE "https://launchpad.net/homebank/+addquestion"
54 #define HOMEBANK_URL_HELP_TRANSLATE "https://launchpad.net/homebank/+translations"
55 #define HOMEBANK_URL_HELP_PROBLEM "https://launchpad.net/homebank/+filebug"
56
57
58 /****************************************************************************/
59 /* Debug macros */
60 /****************************************************************************/
61 #define MYDEBUG 0
62
63 #if MYDEBUG
64 #define DB(x) (x);
65 #else
66 #define DB(x);
67 #endif
68
69 /* our global datas */
70 extern struct HomeBank *GLOBALS;
71 extern struct Preferences *PREFS;
72 extern gchar *homebank_pixmaps_dir;
73
74
75 /* our functions prototype */
76 static void ui_mainwindow_action_new(void);
77 static void ui_mainwindow_action_open(void);
78 static void ui_mainwindow_action_save(void);
79 static void ui_mainwindow_action_saveas(void);
80 static void ui_mainwindow_action_revert(void);
81 static void ui_mainwindow_action_properties(void);
82 static void ui_mainwindow_action_close(void);
83 static void ui_mainwindow_action_quit(void);
84
85 static void ui_mainwindow_action_defcurrency(void);
86 static void ui_mainwindow_action_defaccount(void);
87 static void ui_mainwindow_action_defpayee(void);
88 static void ui_mainwindow_action_defcategory(void);
89 static void ui_mainwindow_action_defarchive(void);
90 static void ui_mainwindow_action_defbudget(void);
91 static void ui_mainwindow_action_defassign(void);
92 static void ui_mainwindow_action_preferences(void);
93
94 static void ui_mainwindow_action_toggle_toolbar(GtkToggleAction *action);
95 static void ui_mainwindow_action_toggle_upcoming(GtkToggleAction *action);
96 static void ui_mainwindow_action_toggle_topspending(GtkToggleAction *action);
97 static void ui_mainwindow_action_toggle_minor(GtkToggleAction *action);
98
99 static void ui_mainwindow_action_showtransactions(void);
100 static void ui_mainwindow_action_addtransactions(void);
101 static void ui_mainwindow_action_checkscheduled(void);
102
103 static void ui_mainwindow_action_statistic(void);
104 static void ui_mainwindow_action_trendtime(void);
105 static void ui_mainwindow_action_budget(void);
106 static void ui_mainwindow_action_balance(void);
107 static void ui_mainwindow_action_vehiclecost(void);
108
109 static void ui_mainwindow_action_import(GtkAction *action);
110 static void ui_mainwindow_action_export(void);
111 static void ui_mainwindow_action_anonymize(void);
112 static void ui_mainwindow_action_file_statistics(void);
113
114 static void ui_mainwindow_action_help(void);
115 void ui_mainwindow_action_help_welcome(void);
116 static void ui_mainwindow_action_help_online(void);
117 static void ui_mainwindow_action_help_translate(void);
118 static void ui_mainwindow_action_help_problem(void);
119 static void ui_mainwindow_action_about(void);
120
121
122 static GtkWidget *ui_mainwindow_create_recent_chooser_menu (GtkRecentManager *manager);
123
124 static void ui_mainwindow_populate_topspending(GtkWidget *widget, gpointer user_data);
125
126 void ui_mainwindow_open(GtkWidget *widget, gpointer user_data);
127
128 void ui_mainwindow_save(GtkWidget *widget, gpointer user_data);
129 void ui_mainwindow_revert(GtkWidget *widget, gpointer user_data);
130 void ui_mainwindow_action(GtkWidget *widget, gpointer user_data);
131 void ui_mainwindow_toggle_minor(GtkWidget *widget, gpointer user_data);
132 void ui_mainwindow_clear(GtkWidget *widget, gpointer user_data);
133
134 gboolean ui_dialog_msg_savechanges(GtkWidget *widget, gpointer user_data);
135
136 void ui_mainwindow_update(GtkWidget *widget, gpointer user_data);
137 void ui_mainwindow_addtransactions(GtkWidget *widget, gpointer user_data);
138 void ui_mainwindow_recent_add (struct hbfile_data *data, const gchar *path);
139
140 static void ui_panel_topspending_update(GtkWidget *widget, gpointer user_data);
141
142 static void ui_mainwindow_scheduled_populate(GtkWidget *widget, gpointer user_data);
143 void ui_mainwindow_scheduled_postall(GtkWidget *widget, gpointer user_data);
144
145 void ui_mainwindow_recent_add (struct hbfile_data *data, const gchar *path);
146
147 extern gchar *CYA_ACC_TYPE[];
148
149 gchar *CYA_CATSUBCAT[] = {
150 N_("Category"),
151 N_("Subcategory"),
152 NULL
153 };
154
155
156 static GtkActionEntry entries[] = {
157
158 /* name, icon-name, label */
159
160 { "FileMenu" , NULL, N_("_File"), NULL, NULL, NULL },
161 { "ImportMenu" , NULL, N_("_Import"), NULL, NULL, NULL },
162 { "EditMenu" , NULL, N_("_Edit"), NULL, NULL, NULL },
163 { "ViewMenu" , NULL, N_("_View"), NULL, NULL, NULL },
164 { "ManageMenu" , NULL, N_("_Manage"), NULL, NULL, NULL },
165 { "TxnMenu" , NULL, N_("_Transactions"), NULL, NULL, NULL },
166 { "ReportMenu" , NULL, N_("_Reports"), NULL, NULL, NULL },
167 { "ToolsMenu" , NULL, N_("_Tools"), NULL, NULL, NULL },
168 { "HelpMenu" , NULL, N_("_Help"), NULL, NULL, NULL },
169
170 // { "Import" , NULL, N_("Import") },
171 // { "Export" , NULL, N_("Export to") },
172 /* name, icon-name, label, accelerator, tooltip */
173
174 /* FileMenu */
175 { "New" , ICONNAME_NEW , N_("_New") , "<control>N", N_("Create a new file"), G_CALLBACK (ui_mainwindow_action_new) },
176 { "Open" , ICONNAME_OPEN , N_("_Open...") , "<control>O", N_("Open a file"), G_CALLBACK (ui_mainwindow_action_open) },
177 { "Save" , ICONNAME_SAVE , N_("_Save") , "<control>S", N_("Save the current file"), G_CALLBACK (ui_mainwindow_action_save) },
178 { "SaveAs" , ICONNAME_SAVE_AS , N_("Save _As...") , "<shift><control>S", N_("Save the current file with a different name"), G_CALLBACK (ui_mainwindow_action_saveas) },
179 { "Revert" , ICONNAME_REVERT , N_("Revert") , NULL, N_("Revert to a saved version of this file"), G_CALLBACK (ui_mainwindow_action_revert) },
180
181 { "Properties" , ICONNAME_PROPERTIES , N_("Properties..."), NULL, N_("Configure the file"), G_CALLBACK (ui_mainwindow_action_properties) },
182 { "Close" , ICONNAME_CLOSE , N_("_Close") , "<control>W", N_("Close the current file"), G_CALLBACK (ui_mainwindow_action_close) },
183 { "Quit" , ICONNAME_QUIT , N_("_Quit") , "<control>Q", N_("Quit HomeBank"), G_CALLBACK (ui_mainwindow_action_quit) },
184
185 /* Exchange */
186 { "ImportQIF" , ICONNAME_HB_FILE_IMPORT , N_("QIF file...") , NULL, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import) },
187 { "ImportOFX" , ICONNAME_HB_FILE_IMPORT , N_("OFX/QFX file...") , NULL, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import) },
188 { "ImportCSV" , ICONNAME_HB_FILE_IMPORT , N_("CSV file...") , NULL, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import) },
189
190 { "ExportQIF" , ICONNAME_HB_FILE_EXPORT , N_("Export QIF file...") , NULL, N_("Export all account in a QIF file"), G_CALLBACK (ui_mainwindow_action_export) },
191
192 /* EditMenu */
193 { "Preferences", ICONNAME_PREFERENCES , N_("Preferences..."), NULL, N_("Configure HomeBank"), G_CALLBACK (ui_mainwindow_action_preferences) },
194
195 /* ManageMenu */
196 { "Currency" , ICONNAME_HB_CURRENCY , N_("Currencies...") , NULL, N_("Configure the currencies"), G_CALLBACK (ui_mainwindow_action_defcurrency) },
197 { "Account" , ICONNAME_HB_ACCOUNT , N_("Acc_ounts...") , NULL, N_("Configure the accounts"), G_CALLBACK (ui_mainwindow_action_defaccount) },
198 { "Payee" , ICONNAME_HB_PAYEE , N_("_Payees...") , NULL, N_("Configure the payees"), G_CALLBACK (ui_mainwindow_action_defpayee) },
199 { "Category" , ICONNAME_HB_CATEGORY , N_("Categories...") , NULL, N_("Configure the categories"), G_CALLBACK (ui_mainwindow_action_defcategory) },
200 { "Archive" , ICONNAME_HB_ARCHIVE , N_("Scheduled/Template...") , NULL, N_("Configure the scheduled/template transactions"), G_CALLBACK (ui_mainwindow_action_defarchive) },
201 { "Budget" , ICONNAME_HB_BUDGET , N_("Budget...") , NULL, N_("Configure the budget"), G_CALLBACK (ui_mainwindow_action_defbudget) },
202 { "Assign" , ICONNAME_HB_ASSIGN , N_("Assignments..."), NULL, N_("Configure the automatic assignments"), G_CALLBACK (ui_mainwindow_action_defassign) },
203
204 /* TxnMenu */
205 { "ShowOpe" , ICONNAME_HB_OPE_SHOW , N_("Show...") , NULL, N_("Shows selected account transactions"), G_CALLBACK (ui_mainwindow_action_showtransactions) },
206 { "AddOpe" , ICONNAME_HB_OPE_ADD , N_("Add...") , NULL, N_("Add transactions"), G_CALLBACK (ui_mainwindow_action_addtransactions) },
207 { "Scheduler" , NULL , N_("Set scheduler...") , NULL, N_("Configure the transaction scheduler"), G_CALLBACK (ui_mainwindow_action_properties) },
208 { "AddScheduled", NULL , N_("Post scheduled"), NULL, N_("Post pending scheduled transactions"), G_CALLBACK (ui_mainwindow_action_checkscheduled) },
209
210 /* ReportMenu */
211 { "RStatistics" , ICONNAME_HB_REP_STATS , N_("_Statistics...") , NULL, N_("Open the Statistics report"), G_CALLBACK (ui_mainwindow_action_statistic) },
212 { "RTrendTime" , ICONNAME_HB_REP_TIME , N_("_Trend Time...") , NULL, N_("Open the Trend Time report"), G_CALLBACK (ui_mainwindow_action_trendtime) },
213 { "RBudget" , ICONNAME_HB_REP_BUDGET , N_("B_udget...") , NULL, N_("Open the Budget report"), G_CALLBACK (ui_mainwindow_action_budget) },
214 { "RBalance" , ICONNAME_HB_REP_BALANCE, N_("Balance...") , NULL, N_("Open the Balance report"), G_CALLBACK (ui_mainwindow_action_balance) },
215 { "RVehiculeCost", ICONNAME_HB_REP_CAR , N_("_Vehicle cost...") , NULL, N_("Open the Vehicle cost report"), G_CALLBACK (ui_mainwindow_action_vehiclecost) },
216
217 /* Tools */
218 { "Welcome" , NULL , N_("Show welcome dialog...") , NULL, NULL, G_CALLBACK (ui_mainwindow_action_help_welcome) },
219 { "FileStats" , NULL , N_("File statistics...") , NULL, NULL, G_CALLBACK (ui_mainwindow_action_file_statistics) },
220 { "Anonymize" , NULL , N_("Anonymize...") , NULL, NULL, G_CALLBACK (ui_mainwindow_action_anonymize) },
221
222 /* HelpMenu */
223 { "Contents" , ICONNAME_HELP , N_("_Contents") , "F1", N_("Documentation about HomeBank"), G_CALLBACK (ui_mainwindow_action_help) },
224 { "Online" , "lpi-help" , N_("Get Help Online...") , NULL, N_("Connect to the LaunchPad website for online help"), G_CALLBACK (ui_mainwindow_action_help_online) },
225 { "Translate" , "lpi-translate" , N_("Translate this Application..."), NULL, N_("Connect to the LaunchPad website to help translate this application"), G_CALLBACK (ui_mainwindow_action_help_translate) },
226 { "Problem" , "lpi-bug" , N_("Report a Problem...") , NULL, N_("Connect to the LaunchPad website to help fix problems"), G_CALLBACK (ui_mainwindow_action_help_problem) },
227
228 { "About" , ICONNAME_ABOUT , N_("_About") , NULL, N_("About HomeBank") ,G_CALLBACK (ui_mainwindow_action_about) },
229
230 };
231 static guint n_entries = G_N_ELEMENTS (entries);
232
233
234 static GtkToggleActionEntry toggle_entries[] = {
235 /* name , icon-name, label, accelerator, tooltip, callback, is_active */
236 { "Toolbar" , NULL , N_("_Toolbar") , NULL, NULL, G_CALLBACK (ui_mainwindow_action_toggle_toolbar), TRUE },
237 { "Spending" , NULL , N_("_Top spending") , NULL, NULL, G_CALLBACK (ui_mainwindow_action_toggle_topspending), TRUE },
238 { "Upcoming" , NULL , N_("_Scheduled list") , NULL, NULL, G_CALLBACK (ui_mainwindow_action_toggle_upcoming), TRUE },
239 { "AsMinor" , NULL , N_("Euro minor"), "<control>M", NULL, G_CALLBACK (ui_mainwindow_action_toggle_minor), FALSE },
240 };
241
242 static guint n_toggle_entries = G_N_ELEMENTS (toggle_entries);
243
244
245 static const gchar *ui_info =
246 "<ui>"
247
248 " <menubar name='MenuBar'>"
249 " <menu action='FileMenu'>"
250 " <menuitem action='New'/>"
251 " <menuitem action='Open'/>"
252 " <separator/>"
253 " <menuitem action='Save'/>"
254 " <menuitem action='SaveAs'/>"
255 " <menuitem action='Revert'/>"
256 " <separator/>"
257 " <menuitem action='Properties'/>"
258 " <separator/>"
259 " <menu action='ImportMenu'>"
260 " <menuitem action='ImportQIF'/>"
261 " <menuitem action='ImportOFX'/>"
262 " <menuitem action='ImportCSV'/>"
263 " </menu>"
264 " <menuitem action='ExportQIF'/>"
265 //" <separator/>"
266 // print to come here
267 " <separator/>"
268 " <menuitem action='Close'/>"
269 " <menuitem action='Quit'/>"
270 " </menu>"
271 " <menu action='EditMenu'>"
272 " <menuitem action='Preferences'/>"
273 " </menu>"
274 " <menu action='ViewMenu'>"
275 " <menuitem action='Toolbar'/>"
276 " <separator/>"
277 " <menuitem action='Spending'/>"
278 " <menuitem action='Upcoming'/>"
279 " <separator/>"
280 " <menuitem action='AsMinor'/>"
281 " </menu>"
282 " <menu action='ManageMenu'>"
283 " <menuitem action='Account'/>"
284 " <menuitem action='Payee'/>"
285 " <menuitem action='Category'/>"
286 " <menuitem action='Archive'/>"
287 " <menuitem action='Budget'/>"
288 " <menuitem action='Assign'/>"
289 " <menuitem action='Currency'/>"
290 " </menu>"
291 " <menu action='TxnMenu'>"
292 " <menuitem action='ShowOpe'/>"
293 " <menuitem action='AddOpe'/>"
294 " <separator/>"
295 " <menuitem action='Scheduler'/>"
296 " <menuitem action='AddScheduled'/>"
297 " </menu>"
298 " <menu action='ReportMenu'>"
299 " <menuitem action='RStatistics'/>"
300 " <menuitem action='RTrendTime'/>"
301 " <menuitem action='RBalance'/>"
302 " <menuitem action='RBudget'/>"
303 " <menuitem action='RVehiculeCost'/>"
304 " </menu>"
305 " <menu action='ToolsMenu'>"
306 " <menuitem action='Welcome'/>"
307 " <menuitem action='FileStats'/>"
308 " <separator/>"
309 " <menuitem action='Anonymize'/>"
310 " </menu>"
311 " <menu action='HelpMenu'>"
312 " <menuitem action='Contents'/>"
313 " <separator/>"
314 " <menuitem action='Online'/>"
315 " <menuitem action='Translate'/>"
316 " <menuitem action='Problem'/>"
317 " <separator/>"
318 " <menuitem action='About'/>"
319 " </menu>"
320 " </menubar>"
321
322 " <toolbar name='ToolBar'>"
323 " <toolitem action='New'/>"
324 // here Open + recent is coded
325 " <toolitem action='Save'/>"
326 " <separator/>"
327 " <toolitem action='Account'/>"
328 " <toolitem action='Payee'/>"
329 " <toolitem action='Category'/>"
330 " <toolitem action='Archive'/>"
331 " <toolitem action='Budget'/>"
332 " <toolitem action='Assign'/>"
333 " <toolitem action='Currency'/>"
334 " <separator/>"
335 " <toolitem action='ShowOpe'/>"
336 " <toolitem action='AddOpe'/>"
337 " <separator/>"
338 " <toolitem action='RStatistics'/>"
339 " <toolitem action='RTrendTime'/>"
340 " <toolitem action='RBalance'/>"
341 " <toolitem action='RBudget'/>"
342 " <toolitem action='RVehiculeCost'/>"
343 " </toolbar>"
344
345 "</ui>";
346
347
348
349 /* TODO: a bouger */
350
351
352 /*
353 **
354 */
355 void ui_mainwindow_revert(GtkWidget *widget, gpointer user_data)
356 {
357 //struct hbfile_data *data;
358 gchar *basename;
359 gchar *title;
360 gchar *secondtext;
361 gint result;
362
363 DB( g_print("\n[ui-mainwindow] revert\n") );
364
365 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
366
367 basename = g_path_get_basename(GLOBALS->xhb_filepath);
368 title = g_strdup_printf (
369 _("Revert unsaved changes to file '%s'?"), basename);
370
371 secondtext =
372 _("- Changes made to the file will be permanently lost\n"
373 "- File will be reloaded from the last save (.xhb~)");
374
375 result = ui_dialog_msg_confirm_alert(
376 GTK_WINDOW(GLOBALS->mainwindow),
377 title,
378 secondtext,
379 _("_Revert")
380 );
381
382 g_free(title);
383 g_free(basename);
384
385 if( result == GTK_RESPONSE_OK )
386 {
387 DB( g_print(" - should revert\n") );
388
389 hbfile_change_filepath(hb_util_filename_new_with_extension(GLOBALS->xhb_filepath, "xhb~"));
390 ui_mainwindow_open_internal(widget, NULL);
391 hbfile_change_filepath(hb_util_filename_new_with_extension(GLOBALS->xhb_filepath, "xhb"));
392 }
393
394 }
395
396
397 static void
398 activate_url (GtkAboutDialog *about,
399 const gchar *link,
400 gpointer data)
401 {
402 DB( g_print("activate url %s\n", link) );
403
404 homebank_util_url_show (link);
405 }
406
407 static void hbfile_about(void)
408 {
409 GtkWidget *dialog;
410 GdkPixbuf *pixbuf;
411 gchar *pathfilename;
412 gchar *version;
413
414 static const gchar *artists[] = {
415 "Maxime DOYEN",
416 NULL
417 };
418
419 static const gchar *authors[] = {
420 "Lead developer:\n" \
421 "Maxime DOYEN",
422 "\nContributor:\n" \
423 "Ga\xc3\xabtan LORIDANT (Maths formulas for charts)\n",
424 NULL
425 };
426
427 /*
428 const gchar *documenters[] = {
429 "Maxime DOYEN",
430 NULL
431 };
432 */
433
434 static const gchar *copyright = "Copyright \xc2\xa9 1995-2017 - Maxime DOYEN";
435
436
437
438 version = g_strdup_printf (PACKAGE_VERSION "\n<small>Running against GTK+ %d.%d.%d</small>",
439 gtk_get_major_version (),
440 gtk_get_minor_version (),
441 gtk_get_micro_version ());
442
443 dialog = gtk_about_dialog_new();
444
445 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(GLOBALS->mainwindow));
446 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
447
448 gtk_about_dialog_set_program_name (GTK_ABOUT_DIALOG(dialog), g_get_application_name ());
449 gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), version);
450 gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog), copyright);
451 gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog), _("Free, easy, personal accounting for everyone"));
452 gtk_about_dialog_set_license_type (GTK_ABOUT_DIALOG(dialog), GTK_LICENSE_GPL_2_0);
453
454 //gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(dialog), );
455 gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog), "http://homebank.free.fr");
456 gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(dialog), "Visit the HomeBank website");
457
458 gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(dialog), "homebank");
459
460 pathfilename = g_build_filename(homebank_app_get_images_dir(), "splash.png", NULL);
461 pixbuf = gdk_pixbuf_new_from_file(pathfilename, NULL);
462 g_free(pathfilename);
463
464 if( pixbuf )
465 {
466 gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), pixbuf);
467 g_object_unref (pixbuf);
468 }
469
470 gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(dialog), authors);
471 gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(dialog), artists);
472 //gtk_about_dialog_set_documenters(GTK_ABOUT_DIALOG(dialog), );
473 //gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(dialog), );
474
475 g_signal_connect (dialog, "activate-link", G_CALLBACK (activate_url), NULL);
476
477 gtk_dialog_run (GTK_DIALOG (dialog));
478
479 gtk_widget_destroy (dialog);
480
481 g_free(version);
482
483 }
484
485
486 /* hbfile action functions -------------------- */
487 static void ui_mainwindow_action_new(void)
488 {
489 GtkWidget *widget = GLOBALS->mainwindow;
490
491 if( ui_dialog_msg_savechanges(widget,NULL) == TRUE )
492 {
493 //clear all, and init GLOBALS->xhb_filepath to default
494 ui_mainwindow_clear(widget, GINT_TO_POINTER(TRUE)); // GPOINTER_TO_INT(
495 ui_mainwindow_update(widget, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_REFRESHALL));
496
497 ui_start_assistant();
498 ui_mainwindow_populate_accounts(GLOBALS->mainwindow, NULL);
499 ui_mainwindow_scheduled_populate(GLOBALS->mainwindow, NULL);
500 ui_mainwindow_populate_topspending(GLOBALS->mainwindow, NULL);
501 }
502 }
503
504 static void ui_mainwindow_action_open(void)
505 {
506 ui_mainwindow_open(GLOBALS->mainwindow, NULL);
507 }
508
509 static void ui_mainwindow_action_save(void)
510 {
511 ui_mainwindow_save(GLOBALS->mainwindow, GINT_TO_POINTER(FALSE));
512 }
513
514 static void ui_mainwindow_action_saveas(void)
515 {
516 ui_mainwindow_save(GLOBALS->mainwindow, GINT_TO_POINTER(TRUE));
517 }
518
519 static void ui_mainwindow_action_revert(void)
520 {
521 ui_mainwindow_revert(GLOBALS->mainwindow, NULL);
522 }
523
524 static void ui_mainwindow_action_close(void)
525 {
526 GtkWidget *widget = GLOBALS->mainwindow;
527
528 if( ui_dialog_msg_savechanges(widget,NULL) == TRUE )
529 {
530 //clear all, and init GLOBALS->xhb_filepath to default
531 ui_mainwindow_clear(widget, GINT_TO_POINTER(TRUE));
532 ui_mainwindow_update(widget, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_BALANCE+UF_REFRESHALL));
533 }
534
535 }
536
537
538 static void ui_mainwindow_action_quit(void)
539 {
540 gboolean result;
541
542 //gtk_widget_destroy(GLOBALS->mainwindow);
543
544 g_signal_emit_by_name(GLOBALS->mainwindow, "delete-event", NULL, &result);
545
546 //gtk_main_quit();
547 }
548
549 static void ui_mainwindow_action_file_statistics(void)
550 {
551 ui_dialog_file_statistics();
552 }
553
554
555 static void ui_mainwindow_action_properties(void)
556 {
557 create_defhbfile_dialog();
558 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_REFRESHALL));
559 }
560
561 static void ui_mainwindow_action_anonymize(void)
562 {
563 gint result;
564 gchar *title;
565 gchar *secondtext;
566
567 title = _("Are you sure you want to anonymize the file?");
568
569 secondtext =
570 _("Proceeding will anonymize any text, \n"
571 "like 'account x', 'payee y', 'memo z', ...");
572
573 result = ui_dialog_msg_confirm_alert(
574 GTK_WINDOW(GLOBALS->mainwindow),
575 title,
576 secondtext,
577 _("_Anonymize")
578 );
579
580 if( result == GTK_RESPONSE_CANCEL )
581 return;
582
583 hbfile_anonymize();
584 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_REFRESHALL));
585 }
586
587
588 static void ui_mainwindow_action_defcurrency(void)
589 {
590 ui_cur_manage_dialog();
591 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_REFRESHALL));
592 }
593
594
595 static void ui_mainwindow_action_defaccount(void)
596 {
597 ui_acc_manage_dialog();
598
599 //our global list has changed, so update the treeview
600 //todo: optimize this, should not call compute balance here
601 account_compute_balances ();
602 ui_mainwindow_populate_accounts(GLOBALS->mainwindow, NULL);
603
604 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_BALANCE));
605 }
606
607 static void ui_mainwindow_action_defpayee(void)
608 {
609 ui_pay_manage_dialog();
610 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE));
611 }
612
613 static void ui_mainwindow_action_defcategory(void)
614 {
615 ui_cat_manage_dialog();
616 //todo:why refresh upcoming here??
617 //ui_mainwindow_populate_upcoming(GLOBALS->mainwindow, NULL);
618 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE));
619 }
620
621
622 static void ui_mainwindow_defarchive(Archive *arc)
623 {
624 struct hbfile_data *data;
625 GtkTreeModel *model;
626
627 data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
628
629 // upcoming list have direct pointer to the arc (which may have changed)
630 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_upc));
631 gtk_list_store_clear (GTK_LIST_STORE(model));
632
633 ui_arc_manage_dialog(arc);
634
635 ui_mainwindow_scheduled_populate(GLOBALS->mainwindow, NULL);
636
637 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE));
638 }
639
640
641 static void ui_mainwindow_action_defarchive(void)
642 {
643 ui_mainwindow_defarchive(NULL);
644 }
645
646
647 static void ui_mainwindow_action_defbudget(void)
648 {
649 ui_bud_manage_dialog();
650 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE));
651 }
652
653
654 static void ui_mainwindow_action_defassign(void)
655 {
656
657 ui_asg_manage_dialog();
658
659 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE));
660 }
661
662
663 static void ui_mainwindow_action_preferences(void)
664 {
665 struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
666
667 defpref_dialog_new();
668 if(!PREFS->euro_active)
669 {
670 GtkToggleAction *action = (GtkToggleAction *)gtk_ui_manager_get_action(data->manager, "/MenuBar/ViewMenu/AsMinor");
671
672 gtk_toggle_action_set_active(action, FALSE);
673 ui_mainwindow_action_toggle_minor(action);
674 }
675 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_VISUAL+UF_REFRESHALL));
676 }
677
678 /* display action */
679
680 static void ui_mainwindow_action_toggle_toolbar(GtkToggleAction *action)
681 {
682 //struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
683
684 PREFS->wal_toolbar = gtk_toggle_action_get_active(action);
685 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_VISUAL));
686 }
687
688 static void ui_mainwindow_action_toggle_upcoming(GtkToggleAction *action)
689 {
690 //struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
691
692 PREFS->wal_upcoming = gtk_toggle_action_get_active(action);
693 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_VISUAL));
694 }
695
696 static void ui_mainwindow_action_toggle_topspending(GtkToggleAction *action)
697 {
698 //struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
699
700 PREFS->wal_spending = gtk_toggle_action_get_active(action);
701 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_VISUAL));
702 }
703
704 static void ui_mainwindow_action_toggle_minor(GtkToggleAction *action)
705 {
706 struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
707
708 GLOBALS->minor = gtk_toggle_action_get_active(action);
709
710 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_acc));
711 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_upc));
712
713 // top spending
714 gtk_chart_show_minor(GTK_CHART(data->RE_pie), GLOBALS->minor);
715
716 ui_panel_topspending_update(data->window, data);
717
718 }
719
720 static void ui_mainwindow_action_showtransactions(void)
721 {
722 struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
723 GtkWidget *window;
724
725 //todo:change this
726 if( data->acc )
727 {
728 if( data->acc->window == NULL )
729 {
730 window = register_panel_window_new(data->acc->key, data->acc);
731 register_panel_window_init(window, NULL);
732 }
733 else
734 {
735 if(GTK_IS_WINDOW(data->acc->window))
736 gtk_window_present(data->acc->window);
737
738 }
739 }
740 }
741
742
743 static void ui_mainwindow_action_addtransactions(void)
744 {
745 ui_mainwindow_addtransactions(GLOBALS->mainwindow, NULL);
746 }
747
748 static void ui_mainwindow_action_checkscheduled(void)
749 {
750 ui_mainwindow_scheduled_postall(GLOBALS->mainwindow, GINT_TO_POINTER(TRUE));
751 }
752
753 static void ui_mainwindow_action_statistic(void)
754 {
755 ui_repdist_window_new();
756 }
757
758 static void ui_mainwindow_action_trendtime(void)
759 {
760 struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
761
762 ui_reptime_window_new(data->acc != NULL ? data->acc->key : 0);
763 }
764
765 static void ui_mainwindow_action_budget(void)
766 {
767 repbudget_window_new();
768 }
769
770 static void ui_mainwindow_action_balance(void)
771 {
772 struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
773
774 repbalance_window_new(data->acc != NULL ? data->acc->key : 0);
775 }
776
777 static void ui_mainwindow_action_vehiclecost(void)
778 {
779 repcost_window_new();
780 }
781
782 static void ui_mainwindow_action_import(GtkAction *action)
783 {
784 const gchar *name;
785 gint filetype = FILETYPE_UNKNOW;
786
787 name = gtk_action_get_name(action);
788
789 if( g_str_has_suffix (name, "QIF"))
790 filetype= FILETYPE_QIF;
791 else
792 if( g_str_has_suffix (name, "OFX"))
793 filetype= FILETYPE_OFX;
794 else
795 if( g_str_has_suffix (name, "CSV"))
796 filetype= FILETYPE_CSV_HB;
797
798 DB( g_print("action %s type=%d\n", name, filetype) );
799
800 ui_import_assistant_new(filetype);
801
802 }
803
804
805 static void ui_mainwindow_action_about(void)
806 {
807 hbfile_about();
808
809
810 }
811
812 static void ui_mainwindow_action_export(void)
813 {
814 gchar *filename;
815
816 if( ui_file_chooser_qif(NULL, &filename) == TRUE )
817 {
818 hb_export_qif_account_all(filename);
819 g_free( filename );
820 }
821 }
822
823 static void ui_mainwindow_action_help(void)
824 {
825 gchar *link;
826
827 link = g_build_filename("file:///", homebank_app_get_help_dir(), HOMEBANK_URL_HELP, NULL );
828 homebank_util_url_show (link);
829
830 g_free(link);
831 }
832
833
834 //todo: move this to a ui-assist-welcome.c
835
836 static void ui_mainwindow_action_help_welcome1 (GtkButton *button, gpointer user_data)
837 {
838 gtk_dialog_response (GTK_DIALOG(user_data), 1);
839 }
840
841 static void ui_mainwindow_action_help_welcome2 (GtkButton *button, gpointer user_data)
842 {
843 gtk_dialog_response (GTK_DIALOG(user_data), 2);
844 }
845
846 static void ui_mainwindow_action_help_welcome3 (GtkButton *button, gpointer user_data)
847 {
848 gtk_dialog_response (GTK_DIALOG(user_data), 3);
849 }
850
851 static void ui_mainwindow_action_help_welcome4 (GtkButton *button, gpointer user_data)
852 {
853 gtk_dialog_response (GTK_DIALOG(user_data), 4);
854 }
855
856 static void ui_mainwindow_action_help_welcome5 (GtkButton *button, gpointer user_data)
857 {
858 gtk_dialog_response (GTK_DIALOG(user_data), 5);
859 }
860
861 void ui_mainwindow_action_help_welcome(void)
862 {
863 GtkWidget *dialog, *content_area;
864 GtkWidget *mainvbox, *widget, *label;
865
866 dialog = gtk_dialog_new_with_buttons (_("Welcome to HomeBank"),
867 GTK_WINDOW(GLOBALS->mainwindow),
868 0,
869 _("_Close"),
870 GTK_RESPONSE_ACCEPT,
871 NULL);
872
873 content_area = gtk_dialog_get_content_area(GTK_DIALOG (dialog));
874
875 mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
876 gtk_box_pack_start (GTK_BOX (content_area), mainvbox, FALSE, FALSE, 0);
877 gtk_container_set_border_width (GTK_CONTAINER(mainvbox), SPACING_MEDIUM);
878
879 label = make_label (_("HomeBank"), 0, 0);
880 gimp_label_set_attributes(GTK_LABEL(label), PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD, -1);
881 gtk_box_pack_start (GTK_BOX (mainvbox), label, FALSE, FALSE, 0);
882
883 label = make_label (_("Free, easy, personal accounting for everyone"), 0, 0);
884 gtk_box_pack_start (GTK_BOX (mainvbox), label, FALSE, FALSE, 0);
885
886 widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
887 gtk_box_pack_start (GTK_BOX (content_area), widget, FALSE, FALSE, 0);
888
889 mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_MEDIUM);
890 gtk_box_pack_start (GTK_BOX (content_area), mainvbox, TRUE, TRUE, 0);
891 gtk_container_set_border_width (GTK_CONTAINER(mainvbox), SPACING_MEDIUM);
892
893 label = make_label (_("What do you want to do:"), 0, 0);
894 gimp_label_set_attributes(GTK_LABEL(label), PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD, -1);
895 gtk_box_pack_start (GTK_BOX (mainvbox), label, FALSE, FALSE, 0);
896
897 widget = gtk_button_new_with_mnemonic(_("Read HomeBank _Manual"));
898 gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
899 g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome1), dialog);
900
901 widget = gtk_button_new_with_mnemonic(_("Configure _preferences"));
902 gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
903 g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome2), dialog);
904
905 widget = gtk_button_new_with_mnemonic(_("Create a _new file"));
906 gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
907 g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome3), dialog);
908
909 widget = gtk_button_new_with_mnemonic(_("_Open an existing file"));
910 gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
911 g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome4), dialog);
912
913 widget = gtk_button_new_with_mnemonic(_("Open the _example file"));
914 gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
915 g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome5), dialog);
916
917 //connect all our signals
918 g_signal_connect (dialog, "destroy", G_CALLBACK (gtk_widget_destroyed), &dialog);
919
920 gtk_widget_show_all (dialog);
921
922 //wait for the user
923 gint result = gtk_dialog_run (GTK_DIALOG (dialog));
924
925 // cleanup and destroy
926 gtk_widget_destroy (dialog);
927
928 // do appropriate action
929 switch(result)
930 {
931 case 1:
932 ui_mainwindow_action_help();
933 break;
934 case 2:
935 ui_mainwindow_action_preferences();
936 break;
937 case 3:
938 ui_mainwindow_action_new();
939 break;
940 case 4:
941 ui_mainwindow_action_open();
942 break;
943 case 5:
944 hbfile_change_filepath(g_build_filename(homebank_app_get_datas_dir(), "example.xhb", NULL));
945 ui_mainwindow_open_internal(GLOBALS->mainwindow, NULL);
946 break;
947 }
948
949 }
950
951
952
953 static void ui_mainwindow_action_help_online(void)
954 {
955 const gchar *link = HOMEBANK_URL_HELP_ONLINE;
956
957 homebank_util_url_show (link);
958
959 }
960
961 static void ui_mainwindow_action_help_translate(void)
962 {
963 const gchar *link = HOMEBANK_URL_HELP_TRANSLATE;
964
965 homebank_util_url_show (link);
966
967 }
968
969 static void ui_mainwindow_action_help_problem(void)
970 {
971 const gchar *link = HOMEBANK_URL_HELP_PROBLEM;
972
973 homebank_util_url_show (link);
974
975 }
976
977
978
979
980 /* hbfile functions -------------------- */
981
982
983
984
985 /*
986 **
987 */
988 static void ui_mainwindow_selection(GtkTreeSelection *treeselection, gpointer user_data)
989 {
990 ui_mainwindow_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), GINT_TO_POINTER(UF_SENSITIVE));
991 }
992
993
994 static void ui_mainwindow_close_openbooks(void)
995 {
996 GList *lacc, *elt;
997
998 DB( g_print("\n[ui-mainwindow] close openbooks\n") );
999
1000 lacc = elt = g_hash_table_get_values(GLOBALS->h_acc);
1001 while (elt != NULL)
1002 {
1003 Account *item = elt->data;
1004
1005 if(item->window)
1006 {
1007 gtk_widget_destroy(GTK_WIDGET(item->window));
1008 item->window = NULL;
1009 }
1010
1011 elt = g_list_next(elt);
1012 }
1013 g_list_free(lacc);
1014
1015 }
1016
1017
1018
1019 /*
1020 **
1021 */
1022 void ui_mainwindow_clear(GtkWidget *widget, gpointer user_data)
1023 {
1024 struct hbfile_data *data;
1025 gboolean file_clear = GPOINTER_TO_INT(user_data);
1026
1027 DB( g_print("\n[ui-mainwindow] clear\n") );
1028
1029 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1030
1031 // Close opened account window
1032 // Clear TreeView
1033 ui_mainwindow_close_openbooks();
1034 gtk_tree_store_clear(GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_acc))));
1035 gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_upc))));
1036 gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_top))));
1037
1038 data->showall = FALSE;
1039
1040 hbfile_cleanup(file_clear);
1041 hbfile_setup(file_clear);
1042
1043 }
1044
1045
1046 /*
1047 ** add some transactions directly
1048 */
1049 void ui_mainwindow_addtransactions(GtkWidget *widget, gpointer user_data)
1050 {
1051 struct hbfile_data *data;
1052 GtkWidget *window;
1053 gint result = 1;
1054 guint32 date;
1055 gint account, count;
1056
1057 DB( g_print("\n[ui-mainwindow] add transactions\n") );
1058
1059 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1060
1061 /* init the transaction */
1062 date = homebank_app_date_get_julian();
1063
1064 //#1656531
1065 account = 0;
1066 if(data->acc != NULL)
1067 account = data->acc->key;
1068
1069 window = create_deftransaction_window(GTK_WINDOW(data->window), TRANSACTION_EDIT_ADD, FALSE);
1070 count = 0;
1071 while(result == GTK_RESPONSE_ADD || result == GTK_RESPONSE_ADDKEEP)
1072 {
1073 Transaction *ope;
1074
1075 /* fill in the transaction */
1076 if( result == GTK_RESPONSE_ADD )
1077 {
1078 ope = da_transaction_malloc();
1079 ope->date = date;
1080 ope->kacc = account;
1081
1082 if( PREFS->heritdate == FALSE ) //fix: 318733
1083 ope->date = GLOBALS->today;
1084 }
1085
1086 // normally we can't be in addkeep without initialized ope with add
1087
1088 deftransaction_set_transaction(window, ope);
1089
1090 result = gtk_dialog_run (GTK_DIALOG (window));
1091
1092 DB( g_print(" - dialog result is %d\n", result) );
1093
1094 if(result == GTK_RESPONSE_ADD || result == GTK_RESPONSE_ADDKEEP || result == GTK_RESPONSE_ACCEPT)
1095 {
1096 deftransaction_get(window, NULL);
1097 transaction_add(ope, NULL, ope->kacc);
1098
1099 DB( g_print(" - added 1 transaction to %d\n", ope->kacc) );
1100
1101 ui_mainwindow_populate_accounts(GLOBALS->mainwindow, NULL);
1102
1103 count++;
1104 //todo: still usefull ? store last date
1105 date = ope->date;
1106 }
1107
1108 if( result == GTK_RESPONSE_ADD )
1109 {
1110 da_transaction_free(ope);
1111 ope = NULL;
1112 }
1113
1114 }
1115
1116
1117 deftransaction_dispose(window, NULL);
1118 gtk_widget_destroy (window);
1119
1120 /* todo optimize this */
1121 if(count > 0)
1122 {
1123 GLOBALS->changes_count += count;
1124 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_BALANCE+UF_REFRESHALL));
1125 }
1126 }
1127
1128 struct tmptop
1129 {
1130 guint32 key;
1131 gdouble value;
1132 };
1133
1134
1135 #define MAX_TOPSPENDING 5
1136
1137
1138 static gint tmptop_compare_func(struct tmptop *tt1, struct tmptop *tt2)
1139 {
1140 return tt1->value > tt2->value ? 1 : -1;
1141 }
1142
1143
1144 static void ui_panel_topspending_update(GtkWidget *widget, gpointer user_data)
1145 {
1146 struct hbfile_data *data;
1147 GtkTreeModel *model;
1148 gchar *title;
1149 gchar strbuffer[G_ASCII_DTOSTR_BUF_SIZE];
1150
1151 DB( g_print("\n[ui-mainwindow] topspending_update\n") );
1152
1153 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1154
1155 hb_strfmon(strbuffer, G_ASCII_DTOSTR_BUF_SIZE-1, data->toptotal, GLOBALS->kcur, GLOBALS->minor);
1156 //hb_label_set_amount(GTK_LABEL(data->TX_topamount), total, GLOBALS->kcur, GLOBALS->minor);
1157 title = g_strdup_printf("%s %s", _("Top spending"), strbuffer);
1158
1159 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_top));
1160
1161 gtk_chart_set_color_scheme(GTK_CHART(data->RE_pie), PREFS->report_color_scheme);
1162 gtk_chart_set_currency(GTK_CHART(data->RE_pie), GLOBALS->kcur);
1163 gtk_chart_set_datas(GTK_CHART(data->RE_pie), model, LST_TOPSPEND_AMOUNT, title, NULL);
1164
1165 g_free(title);
1166
1167 //future usage
1168 gchar *fu = _("Top %d spending"); title = fu;
1169 }
1170
1171
1172 static void ui_mainwindow_populate_topspending(GtkWidget *widget, gpointer user_data)
1173 {
1174 struct hbfile_data *data;
1175 GtkTreeModel *model;
1176 GtkTreeIter iter;
1177 GList *list;
1178 gint type, range;
1179 guint n_result, i, n_items;
1180 GArray *garray;
1181 gdouble total, other;
1182 Account *acc;
1183
1184
1185 DB( g_print("\n[ui-mainwindow] populate_topspending\n") );
1186
1187 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1188
1189 type = radio_get_active(GTK_CONTAINER(data->RA_type));
1190 range = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_range));
1191
1192 DB( g_print(" - type=%d, range=%d\n", type, range) );
1193 DB( g_print(" - pref range=%d\n", PREFS->date_range_wal) );
1194
1195 if(range == FLT_RANGE_OTHER)
1196 return;
1197
1198 filter_preset_daterange_set(data->filter, range, 0);
1199
1200
1201 n_result = da_cat_get_max_key() + 1;
1202 total = 0.0;
1203
1204 DB( g_print(" - max key is %d\n", n_result) );
1205
1206 /* allocate some memory */
1207 garray = g_array_sized_new(FALSE, FALSE, sizeof(struct tmptop), n_result);
1208
1209 if(garray)
1210 {
1211 struct tmptop zero = { .key=0, .value=0.0 };
1212 GQueue *txn_queue;
1213
1214 //DB( g_print(" - array length=%d\n", garray->len) );
1215
1216 for(i=0 ; i<n_result ; i++)
1217 {
1218 g_array_append_vals(garray, &zero, 1);
1219 //g_array_insert_vals(garray, i, &zero, 1);
1220
1221 //struct tmptop *tt = &g_array_index (garray, struct tmptop, i);
1222 //DB( g_print("%4d, %4d %f\n", i, tt->key, tt->value) );
1223 }
1224
1225 //DB( g_print("\n - end array length=%d\n", garray->len) );
1226
1227 //todo: not ideal, has ot force to get_acc for each txn below
1228 txn_queue = hbfile_transaction_get_partial(data->filter->mindate, data->filter->maxdate);
1229
1230 /* compute the results */
1231 list = g_queue_peek_head_link(txn_queue);
1232 while (list != NULL)
1233 {
1234 Transaction *ope = list->data;
1235
1236 //DB( g_print(" - eval txn: '%s', cat=%d ==> flt-test=%d\n", ope->wording, ope->kcat, filter_test(data->filter, ope)) );
1237
1238 if( !(ope->paymode == PAYMODE_INTXFER) )
1239 {
1240 guint32 pos = 0;
1241 gdouble trn_amount;
1242
1243 //todo: optimize here
1244 trn_amount = ope->amount;
1245 acc = da_acc_get(ope->kacc);
1246 if(acc)
1247 trn_amount = hb_amount_base(ope->amount, acc->kcur);
1248
1249 if( ope->flags & OF_SPLIT )
1250 {
1251 guint nbsplit = da_splits_count(ope->splits);
1252 Split *split;
1253 struct tmptop *item;
1254
1255 for(i=0;i<nbsplit;i++)
1256 {
1257 split = ope->splits[i];
1258 pos = category_report_id(split->kcat, type);
1259
1260 trn_amount = hb_amount_base(split->amount, acc->kcur);
1261 //trn_amount = split->amount;
1262 //#1297054 if( trn_amount < 0 ) {
1263 item = &g_array_index (garray, struct tmptop, pos);
1264 item->key = pos;
1265 item->value += trn_amount;
1266 //DB( g_print(" - stored %.2f to item %d\n", trn_amount, pos) );
1267 //}
1268 }
1269 }
1270 else
1271 {
1272 struct tmptop *item;
1273
1274 pos = category_report_id(ope->kcat, type);
1275
1276 //#1297054 if( trn_amount < 0 ) {
1277 item = &g_array_index (garray, struct tmptop, pos);
1278 item->key = pos;
1279 item->value += trn_amount;
1280 //DB( g_print(" - stored %.2f to item %d\n", trn_amount, pos) );
1281 //}
1282 }
1283
1284
1285 }
1286
1287 list = g_list_next(list);
1288 }
1289
1290 g_queue_free (txn_queue);
1291
1292 // we need to sort this and limit before
1293 g_array_sort(garray, (GCompareFunc)tmptop_compare_func);
1294
1295 n_items = MIN(garray->len,MAX_TOPSPENDING);
1296 other = 0;
1297 for(i=0 ; i<garray->len ; i++)
1298 {
1299 struct tmptop *item;
1300
1301 item = &g_array_index (garray, struct tmptop, i);
1302 if(item->value < 0)
1303 {
1304 total += item->value;
1305
1306 if(i >= n_items)
1307 other += item->value;
1308
1309 DB( g_print(" - %d : k='%d' v='%f' t='%f'\n", i, item->key, item->value, total) );
1310
1311 }
1312 }
1313
1314 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_top));
1315 gtk_list_store_clear (GTK_LIST_STORE(model));
1316 g_object_ref(model); /* Make sure the model stays with us after the tree view unrefs it */
1317 gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_top), NULL); /* Detach model from view */
1318
1319 /* insert into the treeview */
1320 for(i=0 ; i<MIN(garray->len,MAX_TOPSPENDING) ; i++)
1321 {
1322 gchar *name;
1323 Category *entry;
1324 struct tmptop *item;
1325 gdouble value;
1326
1327 item = &g_array_index (garray, struct tmptop, i);
1328
1329 if(!item->value) continue;
1330
1331 value = hb_amount_round(item->value, 2);
1332 entry = da_cat_get(item->key);
1333 if(entry == NULL) continue;
1334
1335 name = entry->key == 0 ? _("(no category)") : da_cat_get_fullname(entry);
1336
1337 // append test
1338 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
1339 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
1340 LST_TOPSPEND_ID, i,
1341 LST_TOPSPEND_KEY, 0,
1342 LST_TOPSPEND_NAME, name,
1343 LST_TOPSPEND_AMOUNT, value,
1344 //LST_TOPSPEND_RATE, (gint)(((ABS(value)*100)/ABS(total)) + 0.5),
1345 -1);
1346
1347 }
1348
1349 // append test
1350 if(ABS(other) > 0)
1351 {
1352 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
1353 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
1354 LST_TOPSPEND_ID, n_items,
1355 LST_TOPSPEND_KEY, 0,
1356 LST_TOPSPEND_NAME, _("Other"),
1357 LST_TOPSPEND_AMOUNT, other,
1358 //LST_TOPSPEND_RATE, (gint)(((ABS(other)*100)/ABS(total)) + 0.5),
1359 -1);
1360 }
1361
1362 /* Re-attach model to view */
1363 gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_top), model);
1364 g_object_unref(model);
1365
1366
1367 // update chart and widgets
1368 {
1369 gchar *daterange;
1370
1371 data->toptotal = total;
1372 ui_panel_topspending_update(widget, data);
1373
1374 daterange = filter_daterange_text_get(data->filter);
1375 gtk_widget_set_tooltip_markup(GTK_WIDGET(data->CY_range), daterange);
1376 g_free(daterange);
1377 }
1378 }
1379
1380 /* free our memory */
1381 g_array_free (garray, TRUE);
1382
1383 }
1384
1385
1386 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
1387 /* scheduled */
1388 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
1389 static Archive *
1390 ui_mainwindow_scheduled_get_selected_item(GtkTreeView *treeview)
1391 {
1392 GtkTreeSelection *treeselection;
1393 GtkTreeModel *model;
1394 GtkTreeIter iter;
1395
1396 treeselection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
1397 if( gtk_tree_selection_get_selected(treeselection, &model, &iter) )
1398 {
1399 Archive *arc;
1400
1401 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, LST_DSPUPC_DATAS, &arc, -1);
1402 return arc;
1403 }
1404
1405 return NULL;
1406 }
1407
1408
1409 static void ui_mainwindow_scheduled_onRowActivated (GtkTreeView *treeview,
1410 GtkTreePath *path,
1411 GtkTreeViewColumn *col,
1412 gpointer userdata)
1413 {
1414 //struct hbfile_data *data;
1415 Archive *arc;
1416
1417 DB( g_print ("\n[ui-mainwindow] A scheduled row has been double-clicked!\n") );
1418
1419 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(treeview, GTK_TYPE_WINDOW)), "inst_data");
1420
1421 arc = ui_mainwindow_scheduled_get_selected_item(treeview);
1422 ui_mainwindow_defarchive(arc);
1423 }
1424
1425
1426 static void ui_mainwindow_scheduled_do_post(Archive *arc, gboolean doedit, gpointer user_data)
1427 {
1428 struct hbfile_data *data = user_data;
1429 GtkWidget *window;
1430 gint result;
1431 Transaction *txn;
1432
1433 window = create_deftransaction_window(GTK_WINDOW(data->window), TRANSACTION_EDIT_ADD, TRUE);
1434
1435 /* fill in the transaction */
1436 txn = da_transaction_malloc();
1437 da_transaction_init_from_template(txn, arc);
1438 txn->date = scheduled_get_postdate(arc, arc->nextdate);
1439
1440 deftransaction_set_transaction(window, txn);
1441
1442 result = gtk_dialog_run (GTK_DIALOG (window));
1443
1444 DB( g_print(" - dialog result is %d\n", result) );
1445
1446 if(result == GTK_RESPONSE_ADD || result == GTK_RESPONSE_ACCEPT)
1447 {
1448 deftransaction_get(window, NULL);
1449 transaction_add(txn, NULL, txn->kacc);
1450 GLOBALS->changes_count++;
1451
1452 scheduled_date_advance(arc);
1453
1454 DB( g_print(" - added 1 transaction to %d\n", txn->kacc) );
1455 }
1456
1457 da_transaction_free(txn);
1458
1459 deftransaction_dispose(window, NULL);
1460 gtk_widget_destroy (window);
1461
1462 }
1463
1464
1465 static void ui_mainwindow_scheduled_editpost_cb(GtkWidget *widget, gpointer user_data)
1466 {
1467 struct hbfile_data *data = user_data;
1468
1469 Archive *arc = ui_mainwindow_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
1470
1471 if( (arc != NULL) )
1472 {
1473 ui_mainwindow_scheduled_do_post(arc, TRUE, data);
1474 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE|UF_REFRESHALL));
1475 }
1476 }
1477
1478
1479 static void ui_mainwindow_scheduled_post_cb(GtkWidget *widget, gpointer user_data)
1480 {
1481 struct hbfile_data *data = user_data;
1482
1483 Archive *arc = ui_mainwindow_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
1484
1485 if( (arc != NULL) )
1486 {
1487 if( scheduled_is_postable(arc) )
1488 {
1489 Transaction *txn = da_transaction_malloc ();
1490
1491 da_transaction_init_from_template(txn, arc);
1492 txn->date = scheduled_get_postdate(arc, arc->nextdate);
1493 transaction_add(txn, NULL, 0);
1494
1495 GLOBALS->changes_count++;
1496 scheduled_date_advance(arc);
1497
1498 da_transaction_free (txn);
1499 }
1500 else
1501 {
1502 ui_mainwindow_scheduled_do_post(arc, FALSE, data);
1503 }
1504
1505 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE|UF_REFRESHALL));
1506 }
1507 }
1508
1509
1510 static void ui_mainwindow_scheduled_skip_cb(GtkWidget *widget, gpointer user_data)
1511 {
1512 struct hbfile_data *data = user_data;
1513
1514 Archive *arc = ui_mainwindow_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
1515 if( (arc != NULL) && (arc->flags & OF_AUTO) )
1516 {
1517 GLOBALS->changes_count++;
1518 scheduled_date_advance(arc);
1519
1520 ui_mainwindow_scheduled_populate(GLOBALS->mainwindow, NULL);
1521 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
1522 }
1523 }
1524
1525
1526
1527 static void ui_mainwindow_scheduled_update(GtkWidget *widget, gpointer user_data)
1528 {
1529 struct hbfile_data *data;
1530 //gint filter;
1531
1532 DB( g_print("\n[ui-mainwindow] scheduled update\n") );
1533
1534 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1535
1536 //filter = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_sched_filter));
1537
1538 Archive *arc = ui_mainwindow_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
1539
1540 if(arc)
1541 {
1542 DB( g_print("archive is %s\n", arc->wording) );
1543
1544 gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_skip), TRUE);
1545 gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_post), TRUE);
1546 gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_editpost), TRUE);
1547 }
1548 else
1549 {
1550 gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_skip), FALSE);
1551 gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_post), FALSE);
1552 gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_editpost), FALSE);
1553 }
1554
1555 }
1556
1557
1558
1559 static void ui_mainwindow_scheduled_selection_cb(GtkTreeSelection *treeselection, gpointer user_data)
1560 {
1561
1562
1563 ui_mainwindow_scheduled_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), GINT_TO_POINTER(UF_SENSITIVE));
1564 }
1565
1566
1567
1568 /*
1569 ** called after load, importamiga, on demand
1570 */
1571 void ui_mainwindow_scheduled_postall(GtkWidget *widget, gpointer user_data)
1572 {
1573 //struct hbfile_data *data;
1574 gint count;
1575 gint usermode = GPOINTER_TO_INT(user_data);
1576
1577 DB( g_print("\n[ui-mainwindow] check scheduled\n") );
1578
1579 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1580
1581 count = scheduled_post_all_pending();
1582
1583 //inform the user
1584 if(usermode == TRUE)
1585 {
1586 gchar *txt;
1587
1588 //#125534
1589 if( count > 0 )
1590 {
1591 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_REFRESHALL));
1592 }
1593
1594 if(count == 0)
1595 txt = _("No transaction to add");
1596 else
1597 txt = _("transaction added: %d");
1598
1599 ui_dialog_msg_infoerror(GTK_WINDOW(GLOBALS->mainwindow), GTK_MESSAGE_INFO,
1600 _("Check scheduled transactions result"),
1601 txt,
1602 count);
1603 }
1604
1605 }
1606
1607
1608 static void ui_mainwindow_scheduled_populate(GtkWidget *widget, gpointer user_data)
1609 {
1610 struct hbfile_data *data;
1611 GtkTreeModel *model;
1612 GtkTreeIter iter;
1613 GList *list;
1614 gdouble totexp = 0;
1615 gdouble totinc = 0;
1616 gint count = 0;
1617 gchar buffer[256];
1618 guint32 maxpostdate;
1619 GDate *date;
1620 //Account *acc;
1621
1622 DB( g_print("\n[ui-mainwindow] scheduled populate list\n") );
1623
1624 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1625
1626 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_upc));
1627 gtk_list_store_clear (GTK_LIST_STORE(model));
1628
1629 homebank_app_date_get_julian();
1630
1631 maxpostdate = scheduled_date_get_post_max();
1632
1633 date = g_date_new_julian (maxpostdate);
1634 g_date_strftime (buffer, 256-1, PREFS->date_format, date);
1635 g_date_free(date);
1636
1637 gtk_label_set_text(GTK_LABEL(data->LB_maxpostdate), buffer);
1638
1639
1640 list = g_list_first(GLOBALS->arc_list);
1641 while (list != NULL)
1642 {
1643 Archive *arc = list->data;
1644 Account *acc;
1645 gdouble inc, exp;
1646 guint nbdays, nblate;
1647
1648 if((arc->flags & OF_AUTO) ) //&& arc->kacc > 0)
1649 {
1650 count++;
1651 nbdays = arc->nextdate - maxpostdate;
1652 nblate = scheduled_get_latepost_count(arc, GLOBALS->today);
1653
1654 DB( g_print(" - append '%s' : %d\n", arc->wording, nbdays) );
1655
1656 if(arc->flags & OF_INCOME)
1657 {
1658 inc = arc->amount;
1659 exp = 0.0;
1660 }
1661 else
1662 {
1663 exp = arc->amount;
1664 inc = 0.0;
1665 }
1666
1667 /* insert normal txn */
1668 acc = da_acc_get(arc->kacc);
1669 if( acc)
1670 {
1671 totinc += hb_amount_base(inc, acc->kcur);
1672 totexp += hb_amount_base(exp, acc->kcur);
1673 }
1674 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
1675 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
1676 LST_DSPUPC_DATAS, arc,
1677 LST_DSPUPC_ACCOUNT, acc,
1678 LST_DSPUPC_WORDING, arc->wording,
1679 LST_DSPUPC_EXPENSE, exp,
1680 LST_DSPUPC_INCOME, inc,
1681 LST_DSPUPC_REMAINING, nbdays,
1682 LST_DSPUPC_NB_LATE, nblate,
1683 -1);
1684
1685 /* insert internal xfer txn : 1378836 */
1686 if(arc->paymode == PAYMODE_INTXFER)
1687 {
1688 acc = da_acc_get(arc->kxferacc);
1689 if( acc)
1690 {
1691 totinc += hb_amount_base(-inc, acc->kcur);
1692 totexp += hb_amount_base(-exp, acc->kcur);
1693 }
1694 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
1695 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
1696 LST_DSPUPC_DATAS, arc,
1697 LST_DSPUPC_ACCOUNT, acc,
1698 LST_DSPUPC_WORDING, arc->wording,
1699 LST_DSPUPC_EXPENSE, -inc,
1700 LST_DSPUPC_INCOME, -exp,
1701 LST_DSPUPC_REMAINING, nbdays,
1702 LST_DSPUPC_NB_LATE, nblate,
1703 -1);
1704 }
1705
1706 }
1707 list = g_list_next(list);
1708 }
1709
1710 // insert total
1711 if(count > 0 )
1712 {
1713 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
1714 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
1715 LST_DSPUPC_DATAS, NULL,
1716 LST_DSPUPC_ACCOUNT, NULL,
1717 LST_DSPUPC_WORDING, _("Total"),
1718 LST_DSPUPC_EXPENSE, totexp,
1719 LST_DSPUPC_INCOME, totinc,
1720 -1);
1721 }
1722
1723
1724 ui_mainwindow_scheduled_update(widget, NULL);
1725
1726 }
1727
1728
1729
1730
1731 /*
1732 **
1733 */
1734 void ui_mainwindow_open(GtkWidget *widget, gpointer user_data)
1735 {
1736 //struct hbfile_data *data;
1737 gchar *filename = NULL;
1738
1739 DB( g_print("\n[ui-mainwindow] open\n") );
1740
1741 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1742
1743 if( ui_dialog_msg_savechanges(widget,NULL) == TRUE )
1744 {
1745 if(ui_file_chooser_xhb(GTK_FILE_CHOOSER_ACTION_OPEN, &filename) == TRUE)
1746 {
1747 hbfile_change_filepath(filename);
1748
1749 ui_mainwindow_open_internal(widget, NULL);
1750
1751
1752 }
1753 }
1754 }
1755
1756 /*
1757 * open the file stored in GLOBALS->xhb_filepath
1758 */
1759 void ui_mainwindow_open_internal(GtkWidget *widget, gpointer user_data)
1760 {
1761 struct hbfile_data *data;
1762 gint r;
1763
1764 DB( g_print("\n[ui-mainwindow] open internal\n") );
1765
1766 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1767
1768 DB( g_print(" - filename: '%s'\n", GLOBALS->xhb_filepath) );
1769
1770 if( GLOBALS->xhb_filepath != NULL )
1771 {
1772 ui_mainwindow_clear(GLOBALS->mainwindow, GINT_TO_POINTER(FALSE));
1773 GLOBALS->hbfile_is_new = FALSE;
1774
1775 r = homebank_load_xml(GLOBALS->xhb_filepath);
1776 if( r == XML_OK )
1777 {
1778 DB( g_print(" - file loaded ok : rcode=%d\n", r) );
1779
1780 hbfile_file_hasbackup(GLOBALS->xhb_filepath);
1781
1782 if(PREFS->appendscheduled)
1783 scheduled_post_all_pending();
1784
1785 if(PREFS->do_update_currency)
1786 ui_cur_manage_dialog_update_currencies(GTK_WINDOW(GLOBALS->mainwindow));
1787
1788 homebank_lastopenedfiles_save();
1789
1790 //todo: delete this after computing done at xml read
1791 account_compute_balances();
1792
1793 ui_mainwindow_recent_add(data, GLOBALS->xhb_filepath);
1794 }
1795 else
1796 {
1797 gchar *msg = _("Unknow error");
1798
1799 switch(r)
1800 {
1801 case XML_IO_ERROR:
1802 msg = _("I/O error for file '%s'.");
1803 break;
1804 case XML_FILE_ERROR:
1805 msg = _("The file '%s' is not a valid HomeBank file.");
1806 break;
1807 case XML_VERSION_ERROR:
1808 msg = _("The file '%s' was saved with a higher version of HomeBank\nand cannot be loaded by the current version.");
1809 break;
1810 }
1811
1812 ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_ERROR,
1813 _("File error"),
1814 msg,
1815 GLOBALS->xhb_filepath
1816 );
1817
1818 ui_mainwindow_clear(GLOBALS->mainwindow, GINT_TO_POINTER(TRUE));
1819
1820 }
1821
1822 ui_mainwindow_populate_accounts(GLOBALS->mainwindow, NULL);
1823 ui_mainwindow_scheduled_populate(GLOBALS->mainwindow, NULL);
1824 ui_mainwindow_populate_topspending(GLOBALS->mainwindow, NULL);
1825 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_VISUAL));
1826 }
1827
1828
1829 }
1830
1831 /*
1832 **
1833 */
1834 void ui_mainwindow_save(GtkWidget *widget, gpointer user_data)
1835 {
1836 struct hbfile_data *data;
1837 gboolean saveas = GPOINTER_TO_INT(user_data);
1838 gchar *filename = NULL;
1839 gint r = XML_UNSET;
1840
1841 DB( g_print("\n[ui-mainwindow] save\n") );
1842
1843 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1844
1845 if( GLOBALS->hbfile_is_new == TRUE )
1846 saveas = 1;
1847
1848 if(saveas == 1)
1849 {
1850 if(ui_file_chooser_xhb(GTK_FILE_CHOOSER_ACTION_SAVE, &filename) == TRUE)
1851 {
1852 DB( g_print(" + should save as '%s'\n", filename) );
1853 homebank_file_ensure_xhb(filename);
1854 homebank_backup_current_file();
1855 r = homebank_save_xml(GLOBALS->xhb_filepath);
1856 GLOBALS->hbfile_is_new = FALSE;
1857 }
1858 else
1859 return;
1860 }
1861 else
1862 {
1863 DB( g_print(" + should quick save %s\n", GLOBALS->xhb_filepath) );
1864 homebank_file_ensure_xhb(NULL);
1865 homebank_backup_current_file();
1866 r = homebank_save_xml(GLOBALS->xhb_filepath);
1867 }
1868
1869
1870 if(r == XML_OK)
1871 {
1872 GLOBALS->changes_count = 0;
1873 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_VISUAL));
1874 }
1875 else
1876 {
1877 gchar *msg = _("I/O error for file '%s'.");
1878
1879 ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_ERROR,
1880 _("File error"),
1881 msg,
1882 GLOBALS->xhb_filepath
1883 );
1884
1885 }
1886
1887
1888 }
1889
1890
1891 static void ui_panel_accounts_expand_all(GtkWidget *widget, gpointer user_data)
1892 {
1893 struct hbfile_data *data;
1894
1895 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1896 gtk_tree_view_expand_all(GTK_TREE_VIEW(data->LV_acc));
1897 }
1898
1899
1900 static void ui_panel_accounts_collapse_all(GtkWidget *widget, gpointer user_data)
1901 {
1902 struct hbfile_data *data;
1903
1904 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1905 gtk_tree_view_collapse_all(GTK_TREE_VIEW(data->LV_acc));
1906 }
1907
1908
1909
1910 static GHashTable *ui_panel_accounts_groups_get(GList *lacc, gint groupby, gboolean showall)
1911 {
1912 GHashTable *hash;
1913 GList *elt;
1914 gchar *groupname;
1915 gint nballoc;
1916
1917 nballoc = da_acc_length ();
1918 hash = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL);
1919 elt = g_list_first(lacc);
1920 while (elt != NULL)
1921 {
1922 Account *acc = elt->data;
1923 GPtrArray *group;
1924
1925 if( showall || !(acc->flags & (AF_CLOSED|AF_NOSUMMARY)) )
1926 {
1927 if( groupby == DSPACC_GROUP_BY_BANK )
1928 {
1929 groupname = _("(no institution)");
1930 if( (acc->bankname != NULL) && strlen(acc->bankname) > 0 )
1931 groupname = acc->bankname;
1932 }
1933 else
1934 {
1935 //pre 5.1.3 historical by type display
1936 groupname = _(CYA_ACC_TYPE[acc->type]);
1937 }
1938
1939 if( g_hash_table_contains(hash, groupname) == FALSE )
1940 {
1941 g_hash_table_insert(hash, g_strdup(groupname), g_ptr_array_sized_new(nballoc) );
1942 //DB( g_print(" - type hash insert '%s' = %d\n", groupname, inserted) );
1943 }
1944
1945 group = g_hash_table_lookup(hash, groupname);
1946 if( group != NULL )
1947 {
1948 g_ptr_array_add(group, (gpointer)acc);
1949 DB( g_print(" -- add '%s' to group '%s'\n", acc->name, groupname) );
1950 }
1951 }
1952 elt = g_list_next(elt);
1953 }
1954
1955 return hash;
1956 }
1957
1958
1959
1960
1961
1962
1963 void ui_mainwindow_populate_accounts(GtkWidget *widget, gpointer user_data)
1964 {
1965 struct hbfile_data *data;
1966 GtkTreeModel *model;
1967 GtkTreeIter iter1, child_iter;
1968 GList *lacc, *elt;
1969 Account *acc;
1970 guint j, nbtype;
1971 gdouble gtbank, gttoday, gtfuture;
1972
1973 GHashTable *h_group;
1974 GHashTableIter grp_iter;
1975 gpointer key, value;
1976
1977 DB( g_print("\n[ui-mainwindow] populate accounts\n") );
1978
1979 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1980
1981 /* here we create a count and a list of every account pointer by type */
1982 lacc = elt = g_hash_table_get_values(GLOBALS->h_acc);
1983
1984 h_group = ui_panel_accounts_groups_get(lacc, PREFS->pnl_acc_show_by, data->showall);
1985 g_list_free(lacc);
1986
1987
1988 gtbank = gttoday = gtfuture = 0;
1989
1990 DB( g_print(" populate listview\n") );
1991
1992 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_acc));
1993 gtk_tree_store_clear (GTK_TREE_STORE(model));
1994
1995 nbtype = 0;
1996 g_hash_table_iter_init (&grp_iter, h_group);
1997 while (g_hash_table_iter_next (&grp_iter, &key, &value))
1998 {
1999 GPtrArray *gpa = value;
2000 gdouble tbank, ttoday, tfuture;
2001
2002 if(gpa != NULL)
2003 {
2004 nbtype++;
2005 //1: Header: Bank, Cash, ...
2006 //DB( g_print(" - append type '%s'\n", CYA_ACC_TYPE[i]) );
2007 DB( g_print("\n - append type '%d'\n", key) );
2008
2009 gtk_tree_store_append (GTK_TREE_STORE(model), &iter1, NULL);
2010 gtk_tree_store_set (GTK_TREE_STORE(model), &iter1,
2011 LST_DSPACC_DATATYPE, DSPACC_TYPE_HEADER,
2012 LST_DSPACC_NAME, key,
2013 -1);
2014
2015 tbank = ttoday = tfuture = 0;
2016
2017 //2: Accounts for real
2018 for(j=0;j<gpa->len;j++)
2019 {
2020 acc = g_ptr_array_index(gpa, j);
2021
2022 //tbank += acc->bal_bank;
2023 //ttoday += acc->bal_today;
2024 //tfuture += acc->bal_future;
2025 tbank += hb_amount_base(acc->bal_bank, acc->kcur);
2026 ttoday += hb_amount_base(acc->bal_today, acc->kcur);
2027 tfuture += hb_amount_base(acc->bal_future, acc->kcur);
2028
2029 DB( g_print(" - insert '%s' :: %.2f %.2f %.2f\n", acc->name, acc->bal_bank, acc->bal_today, acc->bal_future) );
2030
2031 gtk_tree_store_append (GTK_TREE_STORE(model), &child_iter, &iter1);
2032 gtk_tree_store_set (GTK_TREE_STORE(model), &child_iter,
2033 LST_DSPACC_DATAS, acc,
2034 LST_DSPACC_DATATYPE, DSPACC_TYPE_NORMAL,
2035 LST_DSPACC_BANK, acc->bal_bank,
2036 LST_DSPACC_TODAY, acc->bal_today,
2037 LST_DSPACC_FUTURE, acc->bal_future,
2038 -1);
2039 }
2040
2041 if(gpa->len > 1)
2042 {
2043 DB( g_print(" - type totals :: %.2f %.2f %.2f\n", tbank, ttoday, tfuture) );
2044
2045 // insert the total line
2046 gtk_tree_store_append (GTK_TREE_STORE(model), &child_iter, &iter1);
2047 gtk_tree_store_set (GTK_TREE_STORE(model), &child_iter,
2048 LST_DSPACC_DATATYPE, DSPACC_TYPE_SUBTOTAL,
2049 LST_DSPACC_NAME, _("Total"),
2050 LST_DSPACC_BANK, tbank,
2051 LST_DSPACC_TODAY, ttoday,
2052 LST_DSPACC_FUTURE, tfuture,
2053 -1);
2054 }
2055
2056 /* set balance to header to display when collasped */
2057 DB( g_print(" - enrich totals to header :: %.2f %.2f %.2f\n", tbank, ttoday, tfuture) );
2058 gtk_tree_store_set (GTK_TREE_STORE(model), &iter1,
2059 LST_DSPACC_BANK, tbank,
2060 LST_DSPACC_TODAY, ttoday,
2061 LST_DSPACC_FUTURE, tfuture,
2062 -1);
2063
2064 /* add to grand total */
2065 gtbank += tbank;
2066 gttoday += ttoday;
2067 gtfuture += tfuture;
2068
2069 }
2070
2071 }
2072
2073 DB( g_print(" - grand totals :: %.2f %.2f %.2f\n", gtbank, gttoday, gtfuture) );
2074
2075 // Grand total
2076 if( nbtype > 1 )
2077 {
2078 gtk_tree_store_append (GTK_TREE_STORE(model), &iter1, NULL);
2079 gtk_tree_store_set (GTK_TREE_STORE(model), &iter1,
2080 LST_DSPACC_DATATYPE, DSPACC_TYPE_SUBTOTAL,
2081 LST_DSPACC_NAME, _("Grand total"),
2082 LST_DSPACC_BANK, gtbank,
2083 LST_DSPACC_TODAY, gttoday,
2084 LST_DSPACC_FUTURE, gtfuture,
2085 -1);
2086 }
2087
2088
2089 gtk_tree_view_expand_all(GTK_TREE_VIEW(data->LV_acc));
2090
2091 DB( g_print(" - free ressources\n") );
2092
2093 g_hash_table_iter_init (&grp_iter, h_group);
2094 while (g_hash_table_iter_next (&grp_iter, &key, &value))
2095 {
2096 g_ptr_array_free (value, TRUE);
2097 }
2098 g_hash_table_destroy (h_group);
2099
2100 }
2101
2102
2103 void ui_mainwindow_update(GtkWidget *widget, gpointer user_data)
2104 {
2105 struct hbfile_data *data;
2106 gint flags;
2107
2108 DB( g_print("\n[ui-mainwindow] refresh_display\n") );
2109
2110 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
2111 //data = INST_DATA(widget);
2112
2113 flags = GPOINTER_TO_INT(user_data);
2114
2115 /* set window title */
2116 if(flags & UF_TITLE)
2117 {
2118 gchar *basename;
2119 gchar *changed;
2120
2121 DB( g_print(" + 1: wintitle %x\n", data->wintitle) );
2122
2123 basename = g_path_get_basename(GLOBALS->xhb_filepath);
2124
2125 DB( g_print(" global changes: %d\n", GLOBALS->changes_count) );
2126
2127 g_free(data->wintitle);
2128
2129 changed = (GLOBALS->changes_count > 0) ? "*" : "";
2130
2131 data->wintitle = g_strdup_printf("%s%s - %s - " PROGNAME, changed, basename, GLOBALS->owner);
2132
2133 gtk_window_set_title (GTK_WINDOW (gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), data->wintitle);
2134
2135 g_free(basename);
2136 }
2137
2138 /* update disabled things */
2139 if(flags & UF_SENSITIVE)
2140 {
2141 GtkTreeSelection *selection;
2142 GtkTreeModel *model;
2143 GtkTreeIter iter;
2144 GtkTreePath *path;
2145 gboolean active,sensitive;
2146
2147 DB( g_print(" + 2: disabled, opelist count\n") );
2148
2149 //#1656531
2150 data->acc = NULL;
2151
2152 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_acc));
2153 active = gtk_tree_selection_get_selected(selection, &model, &iter);
2154 if(active)
2155 {
2156 Account *acc;
2157 gint depth;
2158
2159 path = gtk_tree_model_get_path(model, &iter);
2160 depth = gtk_tree_path_get_depth(path);
2161
2162 if( depth > 1 )
2163 {
2164 DB( g_print(" depth is %d\n", depth) );
2165
2166 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, LST_DSPACC_DATAS, &acc, -1);
2167 data->acc = acc;
2168 }
2169 else
2170 active = FALSE;
2171 }
2172
2173
2174 // no change: disable save
2175 DB( g_print(" changes %d - new %d\n", GLOBALS->changes_count, GLOBALS->hbfile_is_new) );
2176
2177
2178 sensitive = (GLOBALS->changes_count != 0 ) ? TRUE : FALSE;
2179 //gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/FileMenu/SaveAs"), sensitive);
2180 //if(sensitive == TRUE && GLOBALS->hbfile_is_new == TRUE) sensitive = FALSE;
2181 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/FileMenu/Save"), sensitive);
2182 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/FileMenu/Revert"), GLOBALS->xhb_hasbak);
2183
2184
2185 // define off ?
2186 sensitive = GLOBALS->define_off == 0 ? TRUE : FALSE;
2187
2188 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ManageMenu/Account"), sensitive);
2189 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ManageMenu/Payee"), sensitive);
2190 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ManageMenu/Category"), sensitive);
2191 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ManageMenu/Budget"), sensitive);
2192 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/EditMenu/Preferences"), sensitive);
2193
2194 // empty account list: disable Import, Archives, Edit, Filter, Add, Statistics, Overdrawn, Car Cost
2195 sensitive = da_acc_length() > 0 ? TRUE : FALSE;
2196
2197 //gtk_action_set_sensitive(gtk_ui_manager_get_action(data-data->manager, "/MenuBar/FileMenu/Import"), sensitive);
2198
2199 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/FileMenu/Close"), sensitive);
2200 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ManageMenu/Archive"), sensitive);
2201 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/TxnMenu/AddOpe"), sensitive);
2202 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/TxnMenu/ShowOpe"), sensitive);
2203 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ReportMenu/RStatistics"), sensitive);
2204 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ReportMenu/RTrendTime"), sensitive);
2205 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ReportMenu/RBudget"), sensitive);
2206 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ReportMenu/RBalance"), sensitive);
2207 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ReportMenu/RVehiculeCost"), sensitive);
2208
2209 // empty category list: disable Budget
2210 sensitive = da_cat_length() > 1 ? TRUE : FALSE;
2211 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ManageMenu/Budget"), sensitive);
2212
2213 //#1501129 no need to disable, P & C can be created from assign dialog
2214 //sensitive = ((da_cat_length() > 1) || (da_pay_length() > 1)) ? TRUE : FALSE;
2215 //gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ManageMenu/Assign"), sensitive);
2216
2217 // empty archive list: disable scheduled check
2218 sensitive = g_list_length(GLOBALS->arc_list) > 0 ? TRUE : FALSE;
2219
2220 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/TxnMenu/AddScheduled"), sensitive);
2221
2222 // no active account: disable Edit, Over
2223 sensitive = (active == TRUE ) ? TRUE : FALSE;
2224 if(data->acc && data->acc->window != NULL)
2225 sensitive = FALSE;
2226
2227 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/TxnMenu/ShowOpe"), sensitive);
2228
2229 }
2230
2231 /* update toolbar, list */
2232 if(flags & UF_VISUAL)
2233 {
2234 DB( g_print(" + 8: visual\n") );
2235
2236 if(PREFS->toolbar_style == 0)
2237 gtk_toolbar_unset_style(GTK_TOOLBAR(data->toolbar));
2238 else
2239 gtk_toolbar_set_style(GTK_TOOLBAR(data->toolbar), PREFS->toolbar_style-1);
2240
2241 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (data->LV_acc), PREFS->grid_lines);
2242 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_acc));
2243
2244 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (data->LV_upc), PREFS->grid_lines);
2245 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_upc));
2246
2247 DB( g_print(" - show toolbar=%d\n", PREFS->wal_toolbar) );
2248 if(PREFS->wal_toolbar)
2249 gtk_widget_show(GTK_WIDGET(data->toolbar));
2250 else
2251 gtk_widget_hide(GTK_WIDGET(data->toolbar));
2252
2253
2254 DB( g_print(" - show top_spending=%d\n", PREFS->wal_spending) );
2255
2256 gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_range), PREFS->date_range_wal);
2257
2258 if(PREFS->wal_spending)
2259 gtk_widget_show(GTK_WIDGET(data->GR_top));
2260 else
2261 gtk_widget_hide(GTK_WIDGET(data->GR_top));
2262
2263
2264
2265 DB( g_print(" - show upcoming=%d\n", PREFS->wal_upcoming) );
2266 if(PREFS->wal_upcoming)
2267 gtk_widget_show(GTK_WIDGET(data->GR_upc));
2268 else
2269 gtk_widget_hide(GTK_WIDGET(data->GR_upc));
2270
2271 DB( g_print(" minor %d\n", PREFS->euro_active) );
2272 gtk_action_set_visible(gtk_ui_manager_get_action(data->manager, "/MenuBar/ViewMenu/AsMinor"), PREFS->euro_active);
2273 }
2274
2275 /* update balances */
2276 if(flags & UF_BALANCE)
2277 {
2278
2279 DB( g_print(" + 4: balances\n") );
2280
2281 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_acc));
2282
2283 //minor = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_minor));
2284
2285 /*
2286 hb-label_set_colvalue(GTK_LABEL(data->TX_balance[0]), data->bank, minor);
2287 hb-label_set_colvalue(GTK_LABEL(data->TX_balance[1]), data->today, minor);
2288 hb-label_set_colvalue(GTK_LABEL(data->TX_balance[2]), data->future, minor);
2289 */
2290 }
2291
2292 if(flags & UF_REFRESHALL)
2293 {
2294 DB( g_print(" + 8: refreshall\n") );
2295
2296 ui_mainwindow_populate_accounts(GLOBALS->mainwindow, NULL);
2297 ui_mainwindow_populate_topspending(GLOBALS->mainwindow, NULL);
2298 ui_mainwindow_scheduled_populate(GLOBALS->mainwindow, NULL);
2299 }
2300
2301
2302 }
2303
2304
2305
2306 static void
2307 ui_mainwindow_onRowActivated (GtkTreeView *treeview,
2308 GtkTreePath *path,
2309 GtkTreeViewColumn *col,
2310 gpointer userdata)
2311 {
2312 GtkTreeModel *model;
2313 GtkTreeIter iter;
2314
2315 DB( g_print ("\n[ui-mainwindow] A row has been double-clicked!\n") );
2316
2317 model = gtk_tree_view_get_model(treeview);
2318
2319 if (gtk_tree_model_get_iter(model, &iter, path))
2320 {
2321 Account *acc;
2322
2323 gtk_tree_model_get(model, &iter, LST_DSPACC_DATAS, &acc, -1);
2324
2325 if( acc != NULL )
2326 {
2327
2328 DB( g_print ("Double-clicked row contains name %s\n", acc->name) );
2329
2330 ui_mainwindow_action_showtransactions();
2331
2332 //g_free(name);
2333 }
2334 }
2335 }
2336
2337 /*
2338 **
2339 */
2340 static gboolean ui_mainwindow_dispose(GtkWidget *widget, GdkEvent *event, gpointer user_data)
2341 {
2342 struct hbfile_data *data = user_data;
2343 struct WinGeometry *wg;
2344 gboolean retval = FALSE;
2345
2346 DB( g_print("\n[ui-mainwindow] dispose\n") );
2347
2348 //store position and size
2349 wg = &PREFS->wal_wg;
2350 gtk_window_get_position(GTK_WINDOW(widget), &wg->l, &wg->t);
2351 gtk_window_get_size(GTK_WINDOW(widget), &wg->w, &wg->h);
2352 GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(widget));
2353 GdkWindowState state = gdk_window_get_state(gdk_window);
2354 wg->s = (state & GDK_WINDOW_STATE_MAXIMIZED) ? 1 : 0;
2355
2356 DB( g_print(" window: l=%d, t=%d, w=%d, h=%d s=%d, state=%d\n", wg->l, wg->t, wg->w, wg->h, wg->s, state & GDK_WINDOW_STATE_MAXIMIZED) );
2357
2358 PREFS->wal_vpaned = gtk_paned_get_position(GTK_PANED(data->vpaned));
2359 PREFS->wal_hpaned = gtk_paned_get_position(GTK_PANED(data->hpaned));
2360
2361 DB( g_print(" - vpaned=%d hpaned=%d\n", PREFS->wal_vpaned, PREFS->wal_hpaned) );
2362
2363 //todo
2364 if(ui_dialog_msg_savechanges(widget, NULL) == FALSE)
2365 {
2366 retval = TRUE;
2367 }
2368 else
2369 {
2370 DB( g_print(" free wintitle %x\n", data->wintitle) );
2371
2372 gtk_widget_destroy(data->LV_top);
2373
2374 g_free(data->wintitle);
2375 da_filter_free(data->filter);
2376 g_free(user_data);
2377 gtk_main_quit();
2378 }
2379
2380
2381
2382 //delete-event TRUE abort/FALSE destroy
2383 return retval;
2384 }
2385
2386
2387 static void ui_mainwindow_recent_chooser_item_activated_cb (GtkRecentChooser *chooser, struct hbfile_data *data)
2388 {
2389 gchar *uri, *path;
2390 GError *error = NULL;
2391
2392 uri = gtk_recent_chooser_get_current_uri (chooser);
2393
2394 path = g_filename_from_uri (uri, NULL, NULL);
2395 if (error)
2396 {
2397 g_warning ("Could not convert uri \"%s\" to a local path: %s", uri, error->message);
2398 g_error_free (error);
2399 return;
2400 }
2401
2402 if( ui_dialog_msg_savechanges(data->window, NULL) == TRUE )
2403 {
2404
2405 //todo: FixMe
2406 /*
2407 if (! load)
2408 {
2409 gpw_recent_remove (gpw, path);
2410 }
2411 */
2412
2413 hbfile_change_filepath(path);
2414 ui_mainwindow_open_internal(data->window, NULL);
2415 }
2416 else
2417 {
2418 g_free (path);
2419 }
2420 g_free (uri);
2421 }
2422
2423
2424 static void ui_mainwindow_window_screen_changed_cb (GtkWidget *widget,
2425 GdkScreen *old_screen,
2426 struct hbfile_data *data)
2427 {
2428
2429 DB( g_print("\n[ui-mainwindow] screen_changed_cb\n") );
2430
2431
2432 data->recent_manager = gtk_recent_manager_get_default ();
2433
2434 gtk_menu_detach (GTK_MENU (data->recent_menu));
2435 g_object_unref (G_OBJECT (data->recent_menu));
2436
2437 data->recent_menu = ui_mainwindow_create_recent_chooser_menu (data->recent_manager);
2438
2439 g_signal_connect (data->recent_menu,
2440 "item-activated",
2441 G_CALLBACK (ui_mainwindow_recent_chooser_item_activated_cb),
2442 data);
2443
2444 //menu_item = gtk_ui_manager_get_widget (data->manager, "/MenuBar/FileMenu/OpenRecent");
2445 //gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), data->recent_menu);
2446 }
2447
2448
2449 void ui_mainwindow_recent_add (struct hbfile_data *data, const gchar *path)
2450 {
2451 GtkRecentData *recent_data;
2452 gchar *uri;
2453 GError *error = NULL;
2454
2455 DB( g_print("\n[ui-mainwindow] recent_add\n") );
2456
2457 DB( g_print(" - file has .xhb suffix = %d\n", g_str_has_suffix (path, ".xhb") ) );
2458
2459 if( g_str_has_suffix (path, ".xhb") == FALSE ) //ignore reverted file
2460 return;
2461
2462 uri = g_filename_to_uri (path, NULL, &error);
2463 if (error)
2464 {
2465 g_warning ("Could not convert uri \"%s\" to a local path: %s", uri, error->message);
2466 g_error_free (error);
2467 return;
2468 }
2469
2470 recent_data = g_slice_new (GtkRecentData);
2471
2472 recent_data->display_name = NULL;
2473 recent_data->description = NULL;
2474 recent_data->mime_type = "application/x-homebank";
2475 recent_data->app_name = (gchar *) g_get_application_name ();
2476 recent_data->app_exec = g_strjoin (" ", g_get_prgname (), "%u", NULL);
2477 recent_data->groups = NULL;
2478 recent_data->is_private = FALSE;
2479
2480 if (!gtk_recent_manager_add_full (data->recent_manager,
2481 uri,
2482 recent_data))
2483 {
2484 g_warning ("Unable to add '%s' to the list of recently used documents", uri);
2485 }
2486
2487 g_free (uri);
2488 g_free (recent_data->app_exec);
2489 g_slice_free (GtkRecentData, recent_data);
2490
2491 }
2492
2493
2494
2495
2496
2497 enum
2498 {
2499 TARGET_URI_LIST
2500 };
2501
2502 static GtkTargetEntry drop_types[] =
2503 {
2504 {"text/uri-list", 0, TARGET_URI_LIST}
2505 };
2506
2507 static void ui_mainwindow_drag_data_received (GtkWidget *widget,
2508 GdkDragContext *context,
2509 gint x, gint y,
2510 GtkSelectionData *selection_data,
2511 guint info, guint time, GtkWindow *window)
2512 {
2513 gchar **uris, **str;
2514 gchar *newseldata;
2515 gint filetype, slen;
2516
2517 if (info != TARGET_URI_LIST)
2518 return;
2519
2520 DB( g_print("\n[ui-mainwindow] drag_data_received\n") );
2521
2522 /* On MS-Windows, it looks like `selection_data->data' is not NULL terminated. */
2523 slen = gtk_selection_data_get_length(selection_data);
2524 newseldata = g_new (gchar, slen + 1);
2525 memcpy (newseldata, gtk_selection_data_get_data(selection_data), slen);
2526 newseldata[slen] = 0;
2527
2528 uris = g_uri_list_extract_uris (newseldata);
2529
2530 DB( g_print(" - dragged %d %d files\n", slen, g_strv_length(uris) ) );
2531
2532 str = uris;
2533 //for (str = uris; *str; str++)
2534 if( *str )
2535 {
2536 GError *error = NULL;
2537 gchar *path = g_filename_from_uri (*str, NULL, &error);
2538
2539 if (path)
2540 {
2541 filetype = homebank_alienfile_recognize(path);
2542
2543 DB( g_print(" - dragged %s, type is %d\n", path, filetype ) );
2544
2545 if( filetype == FILETYPE_HOMEBANK)
2546 {
2547 hbfile_change_filepath(g_strdup(path));
2548 ui_mainwindow_open_internal(GTK_WIDGET(window), NULL);
2549 }
2550 else
2551 {
2552 //todo: future here to implement import for other filetype
2553 // ui_import_assistant_new();
2554 // + write a method into assistant to catch other filename
2555
2556
2557 ui_dialog_msg_infoerror(GTK_WINDOW(window), GTK_MESSAGE_ERROR,
2558 _("File error"),
2559 _("The file %s is not a valid HomeBank file."),
2560 path
2561 );
2562
2563
2564 }
2565
2566 }
2567 else
2568 {
2569 g_warning ("Could not convert uri to local path: %s", error->message);
2570
2571 g_error_free (error);
2572 }
2573 g_free (path);
2574 }
2575 g_strfreev (uris);
2576
2577 g_free(newseldata);
2578 }
2579
2580
2581 static GtkWidget *ui_mainwindow_create_recent_chooser_menu (GtkRecentManager *manager)
2582 {
2583 GtkWidget *toolbar_recent_menu;
2584 GtkRecentFilter *filter;
2585
2586 toolbar_recent_menu = gtk_recent_chooser_menu_new_for_manager (manager);
2587
2588 gtk_recent_chooser_set_local_only (GTK_RECENT_CHOOSER (toolbar_recent_menu),
2589 FALSE);
2590 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (toolbar_recent_menu),
2591 GTK_RECENT_SORT_MRU);
2592 //todo: add a user pref for this
2593 gtk_recent_chooser_set_limit(GTK_RECENT_CHOOSER (toolbar_recent_menu),
2594 10);
2595
2596
2597 //gtk_recent_chooser_set_show_icons (GTK_RECENT_CHOOSER (toolbar_recent_menu), FALSE);
2598
2599 //gtk_recent_chooser_menu_set_show_numbers (GTK_RECENT_CHOOSER_MENU (toolbar_recent_menu), TRUE);
2600
2601 filter = gtk_recent_filter_new ();
2602 //gtk_recent_filter_add_application (filter, g_get_application_name());
2603 gtk_recent_filter_add_pattern (filter, "*.[Xx][Hh][Bb]");
2604 gtk_recent_chooser_set_filter (GTK_RECENT_CHOOSER (toolbar_recent_menu), filter);
2605
2606 return toolbar_recent_menu;
2607 }
2608
2609
2610 static void ui_mainwindow_create_menu_bar_and_toolbar(struct hbfile_data *data, GtkWidget *mainvbox)
2611 {
2612 GtkUIManager *manager;
2613 GtkActionGroup *actions;
2614 GtkAction *action;
2615 GError *error = NULL;
2616
2617 manager = gtk_ui_manager_new ();
2618 data->manager = manager;
2619
2620 gtk_window_add_accel_group (GTK_WINDOW (data->window),
2621 gtk_ui_manager_get_accel_group(manager));
2622
2623 actions = gtk_action_group_new ("MainWindow");
2624 gtk_action_group_set_translation_domain(actions, GETTEXT_PACKAGE);
2625
2626 gtk_action_group_add_actions (actions,
2627 entries,
2628 n_entries,
2629 NULL);
2630
2631 gtk_action_group_add_toggle_actions (actions,
2632 toggle_entries,
2633 n_toggle_entries,
2634 NULL);
2635
2636 gtk_ui_manager_insert_action_group (data->manager, actions, 0);
2637 g_object_unref (actions);
2638 data->actions = actions;
2639
2640 /* set short labels to use in the toolbar */
2641 action = gtk_action_group_get_action(actions, "Open");
2642 g_object_set(action, "short_label", _("Open"), NULL);
2643
2644 //action = gtk_action_group_get_action(action_group, "Save");
2645 //g_object_set(action, "is_important", TRUE, NULL);
2646
2647 action = gtk_action_group_get_action(actions, "Account");
2648 g_object_set(action, "short_label", _("Account"), NULL);
2649
2650 action = gtk_action_group_get_action(actions, "Payee");
2651 g_object_set(action, "short_label", _("Payee"), NULL);
2652
2653 action = gtk_action_group_get_action(actions, "Category");
2654 g_object_set(action, "short_label", _("Category"), NULL);
2655
2656 action = gtk_action_group_get_action(actions, "Archive");
2657 //TRANSLATORS: an archive is stored transaction buffers (kind of bookmark to prefill manual insertion)
2658 g_object_set(action, "short_label", _("Archive"), NULL);
2659
2660 action = gtk_action_group_get_action(actions, "Budget");
2661 g_object_set(action, "short_label", _("Budget"), NULL);
2662
2663 action = gtk_action_group_get_action(actions, "ShowOpe");
2664 g_object_set(action, "short_label", _("Show"), NULL);
2665
2666 action = gtk_action_group_get_action(actions, "AddOpe");
2667 g_object_set(action, "is_important", TRUE, "short_label", _("Add"), NULL);
2668
2669 action = gtk_action_group_get_action(actions, "RStatistics");
2670 g_object_set(action, "short_label", _("Statistics"), NULL);
2671
2672 action = gtk_action_group_get_action(actions, "RBudget");
2673 g_object_set(action, "short_label", _("Budget"), NULL);
2674
2675 action = gtk_action_group_get_action(actions, "RBalance");
2676 g_object_set(action, "short_label", _("Balance"), NULL);
2677
2678 action = gtk_action_group_get_action(actions, "RVehiculeCost");
2679 g_object_set(action, "short_label", _("Vehicle cost"), NULL);
2680
2681 /* now load the UI definition */
2682 gtk_ui_manager_add_ui_from_string (data->manager, ui_info, -1, &error);
2683 if (error != NULL)
2684 {
2685 g_message ("Building menus failed: %s", error->message);
2686 g_error_free (error);
2687 }
2688
2689 //todo: this generate a warning
2690 data->menubar = gtk_ui_manager_get_widget (manager, "/MenuBar");
2691 gtk_box_pack_start (GTK_BOX (mainvbox),
2692 data->menubar,
2693 FALSE,
2694 FALSE,
2695 0);
2696
2697 data->toolbar = gtk_ui_manager_get_widget (manager, "/ToolBar");
2698 gtk_box_pack_start (GTK_BOX (mainvbox),
2699 data->toolbar,
2700 FALSE,
2701 FALSE,
2702 0);
2703
2704 /* recent files menu */
2705
2706 data->recent_manager = gtk_recent_manager_get_default ();
2707
2708 data->recent_menu = ui_mainwindow_create_recent_chooser_menu (data->recent_manager);
2709
2710 g_signal_connect (data->recent_menu,
2711 "item-activated",
2712 G_CALLBACK (ui_mainwindow_recent_chooser_item_activated_cb),
2713 data);
2714
2715 /*
2716 widget = gtk_ui_manager_get_widget (data->manager, "/MenuBar/FileMenu/OpenRecent");
2717 gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), data->recent_menu);
2718 */
2719
2720 /* test */
2721 /* add the custom Open button to the toolbar */
2722 GtkWidget *image = gtk_image_new_from_icon_name (ICONNAME_OPEN, GTK_ICON_SIZE_BUTTON);
2723
2724 GtkToolItem *open_button = gtk_menu_tool_button_new(image, _("_Open"));
2725 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (open_button), data->recent_menu);
2726
2727 gtk_tool_item_set_tooltip_text (open_button, _("Open a file"));
2728 gtk_menu_tool_button_set_arrow_tooltip_text (GTK_MENU_TOOL_BUTTON (open_button), _("Open a recently used file"));
2729
2730 action = gtk_action_group_get_action (data->actions, "Open");
2731 g_object_set (action, "short_label", _("Open"), NULL);
2732 //gtk_action_connect_proxy (action, GTK_WIDGET (open_button));
2733 gtk_activatable_set_related_action (GTK_ACTIVATABLE (open_button), action);
2734
2735 gtk_toolbar_insert (GTK_TOOLBAR (data->toolbar), open_button, 1);
2736 /* end test */
2737
2738 }
2739
2740 /* Callback function for the undo action */
2741 /*static void
2742 activate_action (GSimpleAction *action, GVariant *parameter, gpointer user_data)
2743 {
2744 g_print ("Action %s activated\n", g_action_get_name (G_ACTION (action)));
2745 }*/
2746
2747 static void
2748 activate_toggle (GSimpleAction *action, GVariant *parameter, gpointer user_data)
2749 {
2750 struct hbfile_data *data = user_data;
2751 GVariant *old_state, *new_state;
2752
2753 old_state = g_action_get_state (G_ACTION (action));
2754 new_state = g_variant_new_boolean (!g_variant_get_boolean (old_state));
2755
2756 DB( g_print ("Toggle action %s activated, state changes from %d to %d\n",
2757 g_action_get_name (G_ACTION (action)),
2758 g_variant_get_boolean (old_state),
2759 g_variant_get_boolean (new_state)) );
2760
2761 data->showall = g_variant_get_boolean (new_state);
2762 ui_mainwindow_populate_accounts(GLOBALS->mainwindow, NULL);
2763
2764 g_simple_action_set_state (action, new_state);
2765 g_variant_unref (old_state);
2766 }
2767
2768 static void
2769 activate_radio (GSimpleAction *action, GVariant *parameter, gpointer user_data)
2770 {
2771 //struct hbfile_data *data = user_data;
2772 GVariant *old_state, *new_state;
2773
2774 old_state = g_action_get_state (G_ACTION (action));
2775 new_state = g_variant_new_string (g_variant_get_string (parameter, NULL));
2776
2777 DB( g_print ("Radio action %s activated, state changes from %s to %s\n",
2778 g_action_get_name (G_ACTION (action)),
2779 g_variant_get_string (old_state, NULL),
2780 g_variant_get_string (new_state, NULL)) );
2781
2782 PREFS->pnl_acc_show_by = DSPACC_GROUP_BY_TYPE;
2783 if( !strcmp("bank", g_variant_get_string(new_state, NULL)) )
2784 PREFS->pnl_acc_show_by = DSPACC_GROUP_BY_BANK;
2785
2786 ui_mainwindow_populate_accounts(GLOBALS->mainwindow, NULL);
2787
2788 g_simple_action_set_state (action, new_state);
2789 g_variant_unref (old_state);
2790 }
2791
2792
2793 static const GActionEntry actions[] = {
2794 // { "paste", activate_action, NULL, NULL, NULL, {0,0,0} },
2795 { "showall" , activate_toggle, NULL, "false", NULL, {0,0,0} },
2796 { "groupby", activate_radio, "s", "'type'", NULL, {0,0,0} }
2797 };
2798
2799
2800 static GtkWidget *ui_mainwindow_create_youraccounts(struct hbfile_data *data)
2801 {
2802 GtkWidget *panel, *label, *widget, *sw, *tbar, *hbox, *image;
2803 GtkToolItem *toolitem;
2804
2805 panel = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
2806 gtk_container_set_border_width(GTK_CONTAINER(panel), SPACING_SMALL);
2807
2808 sw = gtk_scrolled_window_new (NULL, NULL);
2809 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
2810 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2811 gtk_box_pack_start (GTK_BOX (panel), sw, TRUE, TRUE, 0);
2812 widget = (GtkWidget *)create_list_account();
2813 data->LV_acc = widget;
2814 gtk_container_add (GTK_CONTAINER (sw), widget);
2815
2816 //list toolbar
2817 tbar = gtk_toolbar_new();
2818 gtk_toolbar_set_icon_size (GTK_TOOLBAR(tbar), GTK_ICON_SIZE_MENU);
2819 gtk_toolbar_set_style(GTK_TOOLBAR(tbar), GTK_TOOLBAR_ICONS);
2820 gtk_style_context_add_class (gtk_widget_get_style_context (tbar), GTK_STYLE_CLASS_INLINE_TOOLBAR);
2821 gtk_box_pack_start (GTK_BOX (panel), tbar, FALSE, FALSE, 0);
2822
2823 label = make_label_group(_("Your accounts"));
2824 toolitem = gtk_tool_item_new();
2825 gtk_container_add (GTK_CONTAINER(toolitem), label);
2826 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
2827
2828 toolitem = gtk_separator_tool_item_new ();
2829 gtk_tool_item_set_expand (toolitem, TRUE);
2830 gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
2831 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
2832
2833 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
2834 toolitem = gtk_tool_item_new();
2835 gtk_container_add (GTK_CONTAINER(toolitem), hbox);
2836 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
2837
2838 widget = make_image_button(ICONNAME_HB_BUTTON_EXPAND, _("Expand all"));
2839 data->BT_expandall = widget;
2840 gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
2841
2842 widget = make_image_button(ICONNAME_HB_BUTTON_COLLAPSE, _("Collapse all"));
2843 data->BT_collapseall = widget;
2844 gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
2845
2846 toolitem = gtk_separator_tool_item_new ();
2847 gtk_tool_item_set_expand (toolitem, FALSE);
2848 gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
2849 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
2850
2851
2852 //gmenu test (see test folder into gtk)
2853 widget = gtk_menu_button_new();
2854 gtk_menu_button_set_direction (GTK_MENU_BUTTON(widget), GTK_ARROW_UP);
2855 gtk_widget_set_halign (widget, GTK_ALIGN_END);
2856 image = gtk_image_new_from_icon_name (ICONNAME_EMBLEM_SYSTEM, GTK_ICON_SIZE_MENU);
2857 g_object_set (widget, "image", image, NULL);
2858
2859 toolitem = gtk_tool_item_new();
2860 gtk_container_add (GTK_CONTAINER(toolitem), widget);
2861 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
2862
2863 GMenu *menu, *section;
2864
2865 menu = g_menu_new ();
2866 //g_menu_append (menumodel, "About", "actions.undo");
2867 //g_menu_append (menumodel, "Test", "actions.redo");
2868 section = g_menu_new ();
2869 g_menu_append (section, _("Show all"), "actions.showall");
2870 g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
2871 g_object_unref (section);
2872
2873 section = g_menu_new ();
2874 g_menu_append (section, _("By type"), "actions.groupby::type");
2875 g_menu_append (section, _("By institition"), "actions.groupby::bank");
2876 g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
2877 g_object_unref (section);
2878
2879
2880 GSimpleActionGroup *group = g_simple_action_group_new ();
2881 g_action_map_add_action_entries (G_ACTION_MAP (group), actions, G_N_ELEMENTS (actions), data);
2882
2883 //init radio
2884 GAction *action = g_action_map_lookup_action (G_ACTION_MAP (group), "groupby");
2885 const gchar *value = (PREFS->pnl_acc_show_by == DSPACC_GROUP_BY_TYPE) ? "type" : "bank";
2886 g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_string (value));
2887
2888 gtk_widget_insert_action_group (widget, "actions", G_ACTION_GROUP(group));
2889
2890 gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (widget), G_MENU_MODEL (menu));
2891
2892 return panel;
2893 }
2894
2895
2896 static GtkWidget *ui_mainwindow_create_topspending(struct hbfile_data *data)
2897 {
2898 GtkWidget *panel, *hbox, *tbar;
2899 GtkWidget *label, *widget;
2900 GtkToolItem *toolitem;
2901
2902 widget = (GtkWidget *)create_list_topspending();
2903 data->LV_top = widget;
2904
2905 panel = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
2906 gtk_container_set_border_width(GTK_CONTAINER(panel), SPACING_SMALL);
2907 data->GR_top = panel;
2908
2909 /* chart + listview */
2910 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
2911 gtk_box_pack_start (GTK_BOX (panel), hbox, TRUE, TRUE, 0);
2912
2913 widget = gtk_chart_new(CHART_TYPE_PIE);
2914 data->RE_pie = widget;
2915 gtk_chart_set_minor_prefs(GTK_CHART(widget), PREFS->euro_value, PREFS->minor_cur.symbol);
2916 gtk_chart_show_legend(GTK_CHART(data->RE_pie), TRUE, TRUE);
2917 gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
2918
2919 //list toolbar
2920 tbar = gtk_toolbar_new();
2921 gtk_toolbar_set_icon_size (GTK_TOOLBAR(tbar), GTK_ICON_SIZE_MENU);
2922 gtk_toolbar_set_style(GTK_TOOLBAR(tbar), GTK_TOOLBAR_ICONS);
2923 gtk_style_context_add_class (gtk_widget_get_style_context (tbar), GTK_STYLE_CLASS_INLINE_TOOLBAR);
2924 gtk_box_pack_start (GTK_BOX (panel), tbar, FALSE, FALSE, 0);
2925
2926 label = make_label_group(_("Where your money goes"));
2927 toolitem = gtk_tool_item_new();
2928 gtk_container_add (GTK_CONTAINER(toolitem), label);
2929 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
2930
2931 toolitem = gtk_separator_tool_item_new ();
2932 gtk_tool_item_set_expand (toolitem, TRUE);
2933 gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
2934 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
2935
2936 /* total + date range */
2937 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
2938 toolitem = gtk_tool_item_new();
2939 gtk_container_add (GTK_CONTAINER(toolitem), hbox);
2940 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
2941
2942 data->CY_range = make_daterange(label, FALSE);
2943 gtk_box_pack_end (GTK_BOX (hbox), data->CY_range, FALSE, FALSE, 0);
2944
2945 widget = make_radio(CYA_CATSUBCAT, TRUE, GTK_ORIENTATION_HORIZONTAL);
2946 data->RA_type = widget;
2947 gtk_box_pack_end (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
2948
2949 return panel;
2950 }
2951
2952
2953 static GtkWidget *ui_mainwindow_scheduled_create(struct hbfile_data *data)
2954 {
2955 GtkWidget *panel, *hbox, *vbox, *bbox, *sw, *tbar;
2956 GtkWidget *label, *widget;
2957 GtkToolItem *toolitem;
2958
2959 panel = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
2960 gtk_container_set_border_width(GTK_CONTAINER(panel), SPACING_SMALL);
2961 data->GR_upc = panel;
2962
2963 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
2964 //gtk_widget_set_margin_top(GTK_WIDGET(vbox), 0);
2965 //gtk_widget_set_margin_bottom(GTK_WIDGET(vbox), SPACING_SMALL);
2966 //gtk_widget_set_margin_start(GTK_WIDGET(vbox), 2*SPACING_SMALL);
2967 //gtk_widget_set_margin_end(GTK_WIDGET(vbox), SPACING_SMALL);
2968 gtk_box_pack_start (GTK_BOX (panel), vbox, TRUE, TRUE, 0);
2969
2970 sw = gtk_scrolled_window_new (NULL, NULL);
2971 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
2972 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2973 gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
2974
2975 widget = (GtkWidget *)create_list_upcoming();
2976 data->LV_upc = widget;
2977 gtk_container_add (GTK_CONTAINER (sw), widget);
2978
2979 tbar = gtk_toolbar_new();
2980 gtk_toolbar_set_icon_size (GTK_TOOLBAR(tbar), GTK_ICON_SIZE_MENU);
2981 gtk_toolbar_set_style(GTK_TOOLBAR(tbar), GTK_TOOLBAR_ICONS);
2982 gtk_style_context_add_class (gtk_widget_get_style_context (tbar), GTK_STYLE_CLASS_INLINE_TOOLBAR);
2983 gtk_box_pack_start (GTK_BOX (vbox), tbar, FALSE, FALSE, 0);
2984
2985 label = make_label_group(_("Scheduled transactions"));
2986 toolitem = gtk_tool_item_new();
2987 gtk_container_add (GTK_CONTAINER(toolitem), label);
2988 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
2989
2990 toolitem = gtk_separator_tool_item_new ();
2991 gtk_tool_item_set_expand (toolitem, FALSE);
2992 gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
2993 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
2994
2995
2996 bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
2997 toolitem = gtk_tool_item_new();
2998 gtk_container_add (GTK_CONTAINER(toolitem), bbox);
2999 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
3000
3001 widget = gtk_button_new_with_label(_("Skip"));
3002 data->BT_sched_skip = widget;
3003 gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
3004
3005 widget = gtk_button_new_with_label(_("Edit & Post"));
3006 data->BT_sched_editpost = widget;
3007 gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
3008
3009 //TRANSLATORS: Posting a scheduled transaction is the action to materialize it into its target account.
3010 //TRANSLATORS: Before that action the automated transaction occurrence is pending and not yet really existing.
3011 widget = gtk_button_new_with_label (_("Post"));
3012 data->BT_sched_post = widget;
3013 gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
3014
3015 toolitem = gtk_separator_tool_item_new ();
3016 gtk_tool_item_set_expand (toolitem, FALSE);
3017 gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
3018 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
3019
3020 hbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
3021 gtk_widget_set_valign (hbox, GTK_ALIGN_CENTER);
3022 toolitem = gtk_tool_item_new();
3023 gtk_container_add (GTK_CONTAINER(toolitem), hbox);
3024 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
3025
3026 label = make_label(_("maximum post date"), 0.0, 0.7);
3027 gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
3028 gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
3029 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
3030
3031 label = make_label(NULL, 0.0, 0.7);
3032 data->LB_maxpostdate = label;
3033 gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
3034 gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
3035 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
3036
3037 return panel;
3038 }
3039
3040
3041 /*
3042 ** the window creation
3043 */
3044 GtkWidget *create_hbfile_window(GtkWidget *do_widget)
3045 {
3046 struct hbfile_data *data;
3047 struct WinGeometry *wg;
3048 GtkWidget *mainvbox, *vbox, *vpaned, *hpaned;
3049 GtkWidget *widget;
3050 GtkWidget *window;
3051 GtkAction *action;
3052
3053 DB( g_print("\n[ui-mainwindow] create main window\n") );
3054
3055 data = g_malloc0(sizeof(struct hbfile_data));
3056 if(!data) return NULL;
3057
3058 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3059
3060 //store our window private data
3061 g_object_set_data(G_OBJECT(window), "inst_data", (gpointer)data);
3062 DB( g_print(" - new window=%x, inst_data=%0x\n", window, data) );
3063
3064 // this is our mainwindow, so store it to GLOBALS data
3065 data->window = window;
3066 GLOBALS->mainwindow = window;
3067
3068 mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
3069 gtk_container_add (GTK_CONTAINER (window), mainvbox);
3070
3071 ui_mainwindow_create_menu_bar_and_toolbar (data, mainvbox);
3072
3073 #if HB_UNSTABLE_SHOW == TRUE
3074 GtkWidget *bar, *label;
3075
3076 bar = gtk_info_bar_new ();
3077 gtk_box_pack_start (GTK_BOX (mainvbox), bar, FALSE, FALSE, 0);
3078 gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_WARNING);
3079 label = make_label(NULL, 0.5, 0.5);
3080 gtk_label_set_markup (GTK_LABEL(label), "Unstable Development Version");
3081 gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label, FALSE, FALSE, 0);
3082 #endif
3083
3084 /* Add the main area */
3085 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
3086 //gtk_container_set_border_width (GTK_CONTAINER(vbox), SPACING_MEDIUM);
3087 gtk_box_pack_start (GTK_BOX (mainvbox), vbox, TRUE, TRUE, 0);
3088
3089 vpaned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3090 data->vpaned = vpaned;
3091 gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
3092
3093 hpaned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3094 data->hpaned = hpaned;
3095 gtk_paned_pack1 (GTK_PANED(vpaned), hpaned, FALSE, FALSE);
3096
3097 widget = ui_mainwindow_scheduled_create(data);
3098 gtk_paned_pack2 (GTK_PANED(vpaned), widget, FALSE, FALSE);
3099
3100 widget = ui_mainwindow_create_youraccounts(data);
3101 gtk_paned_pack1 (GTK_PANED(hpaned), widget, FALSE, FALSE);
3102
3103 widget = ui_mainwindow_create_topspending(data);
3104 gtk_paned_pack2 (GTK_PANED(hpaned), widget, FALSE, FALSE);
3105
3106
3107 DB( g_print(" - vpaned=%d hpaned=%d\n", PREFS->wal_vpaned, PREFS->wal_hpaned) );
3108
3109 if(PREFS->wal_hpaned > 0)
3110 gtk_paned_set_position(GTK_PANED(data->hpaned), PREFS->wal_hpaned);
3111 if(PREFS->wal_vpaned > 0)
3112 gtk_paned_set_position(GTK_PANED(data->vpaned), PREFS->wal_vpaned);
3113
3114 //setup, init and show window
3115 wg = &PREFS->wal_wg;
3116 if(wg->s == 0)
3117 {
3118 gtk_window_move(GTK_WINDOW(window), wg->l, wg->t);
3119 gtk_window_resize(GTK_WINDOW(window), wg->w, wg->h);
3120 }
3121 else
3122 gtk_window_maximize(GTK_WINDOW(window));
3123
3124 gtk_widget_show_all (window);
3125
3126 //todo: move this elsewhere
3127 DB( g_print(" - setup stuff\n") );
3128
3129 data->filter = da_filter_malloc();
3130 filter_default_all_set(data->filter);
3131 gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_range), PREFS->date_range_wal);
3132
3133 action = gtk_ui_manager_get_action(data->manager, "/MenuBar/ViewMenu/Toolbar");
3134 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), PREFS->wal_toolbar);
3135 action = gtk_ui_manager_get_action(data->manager, "/MenuBar/ViewMenu/Spending");
3136 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), PREFS->wal_spending);
3137 action = gtk_ui_manager_get_action(data->manager, "/MenuBar/ViewMenu/Upcoming");
3138 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), PREFS->wal_upcoming);
3139
3140 /* Drag and drop support, set targets to NULL because we add the
3141 default uri_targets below */
3142
3143 /* support for opening a file by dragging onto the project window */
3144 gtk_drag_dest_set (GTK_WIDGET (window),
3145 GTK_DEST_DEFAULT_ALL,
3146 drop_types,
3147 G_N_ELEMENTS (drop_types),
3148 GDK_ACTION_COPY);
3149
3150 g_signal_connect (G_OBJECT (window), "drag-data-received",
3151 G_CALLBACK (ui_mainwindow_drag_data_received), window);
3152
3153
3154
3155 //connect all our signals
3156 DB( g_print(" - connect signals\n") );
3157
3158
3159 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_acc)), "changed", G_CALLBACK (ui_mainwindow_selection), NULL);
3160 g_signal_connect (GTK_TREE_VIEW(data->LV_acc ), "row-activated", G_CALLBACK (ui_mainwindow_onRowActivated), GINT_TO_POINTER(2));
3161 g_signal_connect (G_OBJECT (data->BT_expandall ), "clicked" , G_CALLBACK (ui_panel_accounts_expand_all), NULL);
3162 g_signal_connect (G_OBJECT (data->BT_collapseall), "clicked" , G_CALLBACK (ui_panel_accounts_collapse_all), NULL);
3163
3164 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_upc)), "changed", G_CALLBACK (ui_mainwindow_scheduled_selection_cb), NULL);
3165 g_signal_connect (GTK_TREE_VIEW(data->LV_upc), "row-activated", G_CALLBACK (ui_mainwindow_scheduled_onRowActivated), NULL);
3166 g_signal_connect (G_OBJECT (data->BT_sched_skip), "clicked", G_CALLBACK (ui_mainwindow_scheduled_skip_cb), data);
3167 g_signal_connect (G_OBJECT (data->BT_sched_editpost), "clicked", G_CALLBACK (ui_mainwindow_scheduled_editpost_cb), data);
3168 g_signal_connect (G_OBJECT (data->BT_sched_post), "clicked", G_CALLBACK (ui_mainwindow_scheduled_post_cb), data);
3169
3170 widget = radio_get_nth_widget(GTK_CONTAINER(data->RA_type), 1);
3171 if(widget)
3172 g_signal_connect (widget, "toggled", G_CALLBACK (ui_mainwindow_populate_topspending), &data);
3173
3174 g_signal_connect (data->CY_range, "changed", G_CALLBACK (ui_mainwindow_populate_topspending), NULL);
3175
3176
3177 /* GtkWindow events */
3178 g_signal_connect (window, "delete-event", G_CALLBACK (ui_mainwindow_dispose), (gpointer)data);
3179
3180
3181 g_signal_connect (window, "screen-changed",
3182 G_CALLBACK (ui_mainwindow_window_screen_changed_cb),
3183 data);
3184
3185
3186 //gtk_action_group_set_sensitive(data->actions, FALSE);
3187
3188
3189 return window;
3190 }
3191
This page took 0.18128 seconds and 4 git commands to generate.