1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2021 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 "hub-account.h"
24
25 #include "dsp-mainwindow.h"
26
27 #include "list-account.h"
28
29 #include "hub-scheduled.h"
30 #include "hub-spending.h"
31 #include "hub-transaction.h"
32
33 #include "dsp-account.h"
34 #include "ui-assist-import.h"
35 #include "ui-assist-start.h"
36 #include "ui-account.h"
37 #include "ui-currency.h"
38 #include "ui-payee.h"
39 #include "ui-category.h"
40 #include "ui-archive.h"
41 #include "ui-assign.h"
42 #include "ui-budget.h"
43 #include "ui-budget-tabview.h"
44 #include "ui-pref.h"
45 #include "ui-hbfile.h"
46 #include "ui-transaction.h"
47 #include "ui-tag.h"
48
49 #include "rep-balance.h"
50 #include "rep-budget.h"
51 #include "rep-stats.h"
52 #include "rep-time.h"
53 #include "rep-vehicle.h"
54
55 #include "gtk-chart.h"
56
57 //old url prior 2019
58 //#define HOMEBANK_URL_HELP "http://homebank.free.fr/help/"
59 //#define HOMEBANK_URL_HELP_ONLINE "https://launchpad.net/homebank/+addquestion"
60 //#define HOMEBANK_URL_HELP_PROBLEM "https://launchpad.net/homebank/+filebug"
61 //#define HOMEBANK_URL_HELP_TRANSLATE "https://launchpad.net/homebank/+translations"
62
63 #define HOMEBANK_URL_HELP "index.html"
64 #define HOMEBANK_URL_HELP_ONLINE "http://homebank.free.fr/support.php"
65 #define HOMEBANK_URL_HELP_DONATE "http://homebank.free.fr/donate.php"
66 #define HOMEBANK_URL_HELP_UPDATES "http://homebank.free.fr/downloads.php"
67 #define HOMEBANK_URL_HELP_PROBLEM "http://homebank.free.fr/development.php#bug"
68 #define HOMEBANK_URL_HELP_TRANSLATE "http://homebank.free.fr/development.php#translate"
69
70
71 /****************************************************************************/
72 /* Debug macros */
73 /****************************************************************************/
74 #define MYDEBUG 0
75
76 #if MYDEBUG
77 #define DB(x) (x);
78 #else
79 #define DB(x);
80 #endif
81
82 /* our global datas */
83 extern struct HomeBank *GLOBALS;
84 extern struct Preferences *PREFS;
85
86
87 /* our functions prototype */
88
89 void ui_mainwindow_open(GtkWidget *widget, gpointer user_data);
90
91 void ui_mainwindow_save(GtkWidget *widget, gpointer user_data);
92 void ui_mainwindow_revert(GtkWidget *widget, gpointer user_data);
93 void ui_mainwindow_action(GtkWidget *widget, gpointer user_data);
94 void ui_mainwindow_toggle_minor(GtkWidget *widget, gpointer user_data);
95 void ui_mainwindow_clear(GtkWidget *widget, gpointer user_data);
96
97 void ui_mainwindow_update(GtkWidget *widget, gpointer user_data);
98 void ui_mainwindow_addtransactions(GtkWidget *widget, gpointer user_data);
99 void ui_mainwindow_recent_add (struct hbfile_data *data, const gchar *path);
100
101 void ui_mainwindow_recent_add (struct hbfile_data *data, const gchar *path);
102
103
104 static void ui_mainwindow_action_toggle_minor(GtkCheckMenuItem *menuitem, gpointer user_data);
105
106 /* TODO: a bouger */
107
108
109 /*
110 **
111 */
ui_mainwindow_revert(GtkWidget * widget,gpointer user_data)112 void ui_mainwindow_revert(GtkWidget *widget, gpointer user_data)
113 {
114 //struct hbfile_data *data;
115 gchar *basename;
116 gchar *title;
117 gchar *secondtext;
118 gint result;
119
120 DB( g_print("\n[ui-mainwindow] revert\n") );
121
122 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
123
124 basename = g_path_get_basename(GLOBALS->xhb_filepath);
125 title = g_strdup_printf (
126 _("Revert unsaved changes to file '%s'?"), basename);
127
128 secondtext =
129 _("- Changes made to the file will be permanently lost\n"
130 "- File will be reloaded from the last save (.xhb~)");
131
132 result = ui_dialog_msg_confirm_alert(
133 GTK_WINDOW(GLOBALS->mainwindow),
134 title,
135 secondtext,
136 _("_Revert")
137 );
138
139 g_free(title);
140 g_free(basename);
141
142 if( result == GTK_RESPONSE_OK )
143 {
144 DB( g_print(" - should revert\n") );
145
146 hbfile_change_filepath(hb_filename_new_with_extension(GLOBALS->xhb_filepath, "xhb~"));
147 ui_mainwindow_open_internal(widget, NULL);
148 hbfile_change_filepath(hb_filename_new_with_extension(GLOBALS->xhb_filepath, "xhb"));
149 }
150
151 }
152
153
154 static void
activate_url(GtkAboutDialog * about,const gchar * link,gpointer data)155 activate_url (GtkAboutDialog *about,
156 const gchar *link,
157 gpointer data)
158 {
159 DB( g_print("activate url %s\n", link) );
160
161 homebank_util_url_show (link);
162 }
163
hbfile_about(void)164 static void hbfile_about(void)
165 {
166 GtkWidget *dialog;
167 GdkPixbuf *pixbuf;
168 gchar *pathfilename;
169 gchar *version;
170
171 static const gchar *artists[] = {
172 "Maxime DOYEN",
173 NULL
174 };
175
176 static const gchar *authors[] = {
177 "Lead developer:\n" \
178 "Maxime DOYEN",
179 "\nContributor:\n" \
180 "Ga\xc3\xabtan LORIDANT (Maths formulas for charts)\n",
181 NULL
182 };
183
184 /*
185 const gchar *documenters[] = {
186 "Maxime DOYEN",
187 NULL
188 };
189 */
190
191 static const gchar *copyright = "Copyright \xc2\xa9 1995-2021 - Maxime DOYEN";
192
193
194
195 version = g_strdup_printf (PACKAGE_VERSION "\n<small>Running against GTK+ %d.%d.%d</small>",
196 gtk_get_major_version (),
197 gtk_get_minor_version (),
198 gtk_get_micro_version ());
199
200 dialog = gtk_about_dialog_new();
201
202 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(GLOBALS->mainwindow));
203 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
204
205 gtk_about_dialog_set_program_name (GTK_ABOUT_DIALOG(dialog), g_get_application_name ());
206 gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), version);
207 gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog), copyright);
208 gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog), _("Free, easy, personal accounting for everyone"));
209 gtk_about_dialog_set_license_type (GTK_ABOUT_DIALOG(dialog), GTK_LICENSE_GPL_2_0);
210
211 //gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(dialog), );
212 gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog), "http://homebank.free.fr");
213 gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(dialog), "Visit the HomeBank website");
214
215 gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(dialog), "homebank");
216
217 pathfilename = g_build_filename(homebank_app_get_images_dir(), "splash.png", NULL);
218 pixbuf = gdk_pixbuf_new_from_file(pathfilename, NULL);
219 g_free(pathfilename);
220
221 if( pixbuf )
222 {
223 gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), pixbuf);
224 g_object_unref (pixbuf);
225 }
226
227 gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(dialog), authors);
228 gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(dialog), artists);
229 //gtk_about_dialog_set_documenters(GTK_ABOUT_DIALOG(dialog), );
230 //gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(dialog), );
231
232 g_signal_connect (dialog, "activate-link", G_CALLBACK (activate_url), NULL);
233
234 gtk_dialog_run (GTK_DIALOG (dialog));
235
236 gtk_widget_destroy (dialog);
237
238 g_free(version);
239
240 }
241
242
243 /* hbfile action functions -------------------- */
ui_mainwindow_action_new(void)244 static void ui_mainwindow_action_new(void)
245 {
246 GtkWidget *widget = GLOBALS->mainwindow;
247
248 if( ui_dialog_msg_savechanges(widget,NULL) == TRUE )
249 {
250 //clear all, and init GLOBALS->xhb_filepath to default
251 ui_mainwindow_clear(widget, GINT_TO_POINTER(TRUE)); // GPOINTER_TO_INT(
252 ui_mainwindow_update(widget, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_REFRESHALL));
253
254 ui_newfile_assitant_new();
255 }
256 }
257
ui_mainwindow_action_open(void)258 static void ui_mainwindow_action_open(void)
259 {
260 ui_mainwindow_open(GLOBALS->mainwindow, GINT_TO_POINTER(FALSE));
261 }
262
ui_mainwindow_action_openbak(void)263 static void ui_mainwindow_action_openbak(void)
264 {
265 ui_mainwindow_open(GLOBALS->mainwindow, GINT_TO_POINTER(TRUE));
266 }
267
ui_mainwindow_action_save(void)268 static void ui_mainwindow_action_save(void)
269 {
270 ui_mainwindow_save(GLOBALS->mainwindow, GINT_TO_POINTER(FALSE));
271 }
272
ui_mainwindow_action_saveas(void)273 static void ui_mainwindow_action_saveas(void)
274 {
275 ui_mainwindow_save(GLOBALS->mainwindow, GINT_TO_POINTER(TRUE));
276 }
277
ui_mainwindow_action_revert(void)278 static void ui_mainwindow_action_revert(void)
279 {
280 ui_mainwindow_revert(GLOBALS->mainwindow, NULL);
281 }
282
ui_mainwindow_action_close(void)283 static void ui_mainwindow_action_close(void)
284 {
285 GtkWidget *widget = GLOBALS->mainwindow;
286
287 if( ui_dialog_msg_savechanges(widget,NULL) == TRUE )
288 {
289 //clear all, and init GLOBALS->xhb_filepath to default
290 ui_mainwindow_clear(widget, GINT_TO_POINTER(TRUE));
291 ui_mainwindow_update(widget, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_REFRESHALL));
292 }
293
294 }
295
296
ui_mainwindow_action_quit(void)297 static void ui_mainwindow_action_quit(void)
298 {
299 gboolean result;
300
301 //emulate the wm close button
302 g_signal_emit_by_name(GLOBALS->mainwindow, "delete-event", NULL, &result);
303 }
304
305
ui_mainwindow_action_file_statistics(void)306 static void ui_mainwindow_action_file_statistics(void)
307 {
308 ui_dialog_file_statistics();
309 }
310
311
ui_mainwindow_action_properties(void)312 static void ui_mainwindow_action_properties(void)
313 {
314 create_defhbfile_dialog();
315 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_REFRESHALL));
316 }
317
ui_mainwindow_action_anonymize(void)318 static void ui_mainwindow_action_anonymize(void)
319 {
320 gint result;
321 gchar *title;
322 gchar *secondtext;
323
324 title = _("Are you sure you want to anonymize the file?");
325
326 secondtext =
327 _("Proceeding will anonymize any text, \n"
328 "like 'account x', 'payee y', 'memo z', ...");
329
330 result = ui_dialog_msg_confirm_alert(
331 GTK_WINDOW(GLOBALS->mainwindow),
332 title,
333 secondtext,
334 _("_Anonymize")
335 );
336
337 //#1707201
338 //if( result == GTK_RESPONSE_CANCEL )
339 // return;
340 if( result == GTK_RESPONSE_OK )
341 {
342 hbfile_anonymize();
343 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_REFRESHALL));
344 }
345 }
346
347
ui_mainwindow_action_defcurrency(void)348 static void ui_mainwindow_action_defcurrency(void)
349 {
350 ui_cur_manage_dialog();
351 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE+UF_REFRESHALL));
352 }
353
354
ui_mainwindow_action_defaccount(void)355 static void ui_mainwindow_action_defaccount(void)
356 {
357 ui_acc_manage_dialog();
358
359 //our global list has changed, so update the treeview
360 //todo: optimize this, should not call compute balance here
361 account_compute_balances ();
362 ui_hub_account_populate(GLOBALS->mainwindow, NULL);
363
364 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
365 }
366
ui_mainwindow_action_defpayee(void)367 static void ui_mainwindow_action_defpayee(void)
368 {
369 ui_pay_manage_dialog();
370 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
371 }
372
ui_mainwindow_action_defcategory(void)373 static void ui_mainwindow_action_defcategory(void)
374 {
375 ui_cat_manage_dialog();
376 //todo:why refresh upcoming here??
377 //ui_mainwindow_populate_upcoming(GLOBALS->mainwindow, NULL);
378 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE+UF_REFRESHALL));
379 }
380
381
382 //TODO: not ideal to do this
ui_mainwindow_defarchive(Archive * arc)383 void ui_mainwindow_defarchive(Archive *arc)
384 {
385 struct hbfile_data *data;
386 GtkTreeModel *model;
387
388 data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
389
390 // upcoming list have direct pointer to the arc (which may change during edit)
391 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_upc));
392 gtk_list_store_clear (GTK_LIST_STORE(model));
393
394 ui_arc_manage_dialog(arc);
395
396 ui_hub_scheduled_populate(GLOBALS->mainwindow, NULL);
397
398 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
399 }
400
401
ui_mainwindow_action_defarchive(void)402 static void ui_mainwindow_action_defarchive(void)
403 {
404 ui_mainwindow_defarchive(NULL);
405 }
406
407
ui_mainwindow_action_defbudget(void)408 static void ui_mainwindow_action_defbudget(void)
409 {
410 ui_bud_manage_dialog();
411 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
412 }
413
ui_mainwindow_action_defbudgettable(void)414 static void ui_mainwindow_action_defbudgettable(void)
415 {
416 ui_bud_tabview_manage_dialog();
417 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
418 }
419
ui_mainwindow_action_defassign(void)420 static void ui_mainwindow_action_defassign(void)
421 {
422
423 ui_asg_manage_dialog();
424
425 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
426 }
427
428
ui_mainwindow_action_deftag(void)429 static void ui_mainwindow_action_deftag(void)
430 {
431
432 ui_tag_manage_dialog();
433
434 //ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
435 }
436
437
ui_mainwindow_action_preferences(void)438 static void ui_mainwindow_action_preferences(void)
439 {
440 struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
441 gboolean prv_includeremind;
442
443 //#1914935 store previous includeremind state to detect a change
444 prv_includeremind = PREFS->includeremind;
445
446 defpref_dialog_new();
447
448 if(!PREFS->euro_active)
449 {
450 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data->MI_eurominor), FALSE);
451 //gtk_toggle_action_set_active(action, FALSE);
452 //ui_mainwindow_action_toggle_minor(GTK_CHECK_MENU_ITEM(data->MI_eurominor), NULL);
453 }
454
455 homebank_pref_apply ();
456
457 //#1914935 if include remind change, we update balance
458 if( prv_includeremind != PREFS->includeremind )
459 {
460 account_compute_balances();
461 }
462
463 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_VISUAL+UF_REFRESHALL));
464 }
465
466 /* display action */
467
ui_mainwindow_action_toggle_toolbar(GtkCheckMenuItem * menuitem,gpointer user_data)468 static void ui_mainwindow_action_toggle_toolbar(GtkCheckMenuItem *menuitem, gpointer user_data)
469 {
470 //struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
471
472 PREFS->wal_toolbar = gtk_check_menu_item_get_active(menuitem);
473 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_VISUAL));
474 }
475
ui_mainwindow_action_toggle_upcoming(GtkCheckMenuItem * menuitem,gpointer user_data)476 static void ui_mainwindow_action_toggle_upcoming(GtkCheckMenuItem *menuitem, gpointer user_data)
477 {
478 //struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
479
480 PREFS->wal_upcoming = gtk_check_menu_item_get_active(menuitem);
481 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_VISUAL));
482 }
483
ui_mainwindow_action_toggle_topspending(GtkCheckMenuItem * menuitem,gpointer user_data)484 static void ui_mainwindow_action_toggle_topspending(GtkCheckMenuItem *menuitem, gpointer user_data)
485 {
486 //struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
487
488 PREFS->wal_spending = gtk_check_menu_item_get_active(menuitem);
489 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_VISUAL));
490 }
491
ui_mainwindow_action_toggle_minor(GtkCheckMenuItem * menuitem,gpointer user_data)492 static void ui_mainwindow_action_toggle_minor(GtkCheckMenuItem *menuitem, gpointer user_data)
493 {
494 struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
495
496 GLOBALS->minor = gtk_check_menu_item_get_active(menuitem);
497
498 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_acc));
499 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_upc));
500
501 // top spending
502 gtk_chart_show_minor(GTK_CHART(data->RE_pie), GLOBALS->minor);
503
504 ui_hub_spending_update(data->window, data);
505
506 }
507
508
509 static void
ui_mainwindow_action_showalltransactions(GtkMenuItem * menuitem,gpointer user_data)510 ui_mainwindow_action_showalltransactions(GtkMenuItem *menuitem, gpointer user_data)
511 {
512 GtkWidget *window;
513
514 if( GLOBALS->alltxnwindow == NULL )
515 {
516 window = register_panel_window_new(NULL);
517 register_panel_window_init(window, NULL);
518 }
519 else
520 {
521 if(GTK_IS_WINDOW(GLOBALS->alltxnwindow))
522 gtk_window_present(GTK_WINDOW(GLOBALS->alltxnwindow));
523 }
524 }
525
526
527 static void
ui_mainwindow_action_showtransactions(GtkMenuItem * menuitem,gpointer user_data)528 ui_mainwindow_action_showtransactions(GtkMenuItem *menuitem, gpointer user_data)
529 {
530 struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
531 GtkWidget *window;
532
533 //TODO: change this
534 if( data->acc && data->acc->window == NULL )
535 {
536 window = register_panel_window_new(data->acc);
537 register_panel_window_init(window, NULL);
538 }
539 else
540 {
541 if(GTK_IS_WINDOW(data->acc->window))
542 gtk_window_present(GTK_WINDOW(data->acc->window));
543 }
544
545 }
546
547
ui_mainwindow_action_addtransactions(void)548 static void ui_mainwindow_action_addtransactions(void)
549 {
550 ui_mainwindow_addtransactions(GLOBALS->mainwindow, NULL);
551 }
552
ui_mainwindow_action_checkscheduled(void)553 static void ui_mainwindow_action_checkscheduled(void)
554 {
555 ui_hub_scheduled_postall(GLOBALS->mainwindow, GINT_TO_POINTER(TRUE));
556 }
557
ui_mainwindow_action_statistic(void)558 static void ui_mainwindow_action_statistic(void)
559 {
560 repstats_window_new();
561 }
562
ui_mainwindow_action_trendtime(void)563 static void ui_mainwindow_action_trendtime(void)
564 {
565 struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
566
567 reptime_window_new(data->acc != NULL ? data->acc->key : 0);
568 }
569
ui_mainwindow_action_budget(void)570 static void ui_mainwindow_action_budget(void)
571 {
572 repbudget_window_new();
573 }
574
ui_mainwindow_action_balance(void)575 static void ui_mainwindow_action_balance(void)
576 {
577 struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
578
579 repbalance_window_new(data->acc != NULL ? data->acc->key : 0);
580 }
581
ui_mainwindow_action_vehiclecost(void)582 static void ui_mainwindow_action_vehiclecost(void)
583 {
584 repvehicle_window_new();
585 }
586
ui_mainwindow_action_import(GtkAction * action)587 static void ui_mainwindow_action_import(GtkAction *action)
588 {
589 /*const gchar *name;
590 gint filetype = FILETYPE_UNKNOWN;
591
592 name = gtk_action_get_name(action);
593
594 if( g_str_has_suffix (name, "QIF"))
595 filetype= FILETYPE_QIF;
596 else
597 if( g_str_has_suffix (name, "OFX"))
598 filetype= FILETYPE_OFX;
599 else
600 if( g_str_has_suffix (name, "CSV"))
601 filetype= FILETYPE_CSV_HB;*/
602
603 //DB( g_print("action %s type=%d\n", name, filetype) );
604
605 ui_import_assistant_new(NULL);
606
607 }
608
609
ui_mainwindow_action_about(void)610 static void ui_mainwindow_action_about(void)
611 {
612 hbfile_about();
613
614
615 }
616
617
ui_mainwindow_action_export(void)618 static void ui_mainwindow_action_export(void)
619 {
620 gchar *filename;
621
622 if( ui_file_chooser_qif(NULL, &filename) == TRUE )
623 {
624 hb_export_qif_account_all(filename);
625 g_free( filename );
626 }
627 }
628
629
ui_mainwindow_action_help(void)630 static void ui_mainwindow_action_help(void)
631 {
632 gchar *link;
633
634 link = g_build_filename("file:///", homebank_app_get_help_dir(), HOMEBANK_URL_HELP, NULL );
635 homebank_util_url_show (link);
636 g_free(link);
637 }
638
639
ui_mainwindow_action_help_releasenotes(void)640 static void ui_mainwindow_action_help_releasenotes(void)
641 {
642 gchar *link;
643
644 #ifdef G_OS_WIN32
645 link = g_build_filename("file:///", homebank_app_get_datas_dir(), "ChangeLog.txt", NULL );
646 #else
647 link = g_build_filename("file:///", homebank_app_get_datas_dir(), "ChangeLog", NULL );
648 #endif
649 homebank_util_url_show (link);
650 g_free(link);
651 }
652
653
654 //todo: move this to a ui-assist-welcome.c
655
656
657
ui_mainwindow_action_help_welcome_cb(GtkWidget * widget,gpointer user_data)658 static void ui_mainwindow_action_help_welcome_cb (GtkWidget *widget, gpointer user_data)
659 {
660 GtkWidget *dialog;
661 gint response = GPOINTER_TO_INT(user_data);
662
663 dialog = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
664 if( GTK_IS_DIALOG(dialog) )
665 gtk_dialog_response (GTK_DIALOG(dialog), response);
666 }
667
668
ui_mainwindow_action_help_welcome(void)669 gint ui_mainwindow_action_help_welcome(void)
670 {
671 GtkWidget *dialog, *content_area;
672 GtkWidget *mainvbox, *table, *widget, *label, *check;
673 gchar *pathfilename;
674
675 dialog = gtk_dialog_new_with_buttons (_("Welcome to HomeBank"),
676 GTK_WINDOW(GLOBALS->mainwindow),
677 0,
678 _("_Close"),
679 //_("_Exit"),
680 GTK_RESPONSE_CLOSE,
681 NULL);
682
683 content_area = gtk_dialog_get_content_area(GTK_DIALOG (dialog));
684
685 table = gtk_grid_new ();
686 //gtk_grid_set_row_spacing (GTK_GRID (table), SPACING_SMALL);
687 gtk_grid_set_column_spacing (GTK_GRID (table), SPACING_MEDIUM);
688 gtk_container_set_border_width (GTK_CONTAINER(table), SPACING_LARGE);
689 gtk_box_pack_start (GTK_BOX (content_area), table, FALSE, FALSE, 0);
690
691 //get our icon
692 pathfilename = g_build_filename(homebank_app_get_images_dir(), "homebank-icon.svg", NULL);
693 if (g_file_test (pathfilename, G_FILE_TEST_EXISTS) == TRUE)
694 widget = gtk_image_new_from_file((const gchar *)pathfilename);
695 else
696 widget = gtk_image_new_from_icon_name ("homebank", GTK_ICON_SIZE_DIALOG);
697 g_free(pathfilename);
698 gtk_grid_attach (GTK_GRID (table), widget, 0, 0, 1, 2);
699
700 label = make_label (_("HomeBank"), 0, 0);
701 gimp_label_set_attributes(GTK_LABEL(label), PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD, PANGO_ATTR_SCALE, PANGO_SCALE_XX_LARGE, -1);
702 gtk_grid_attach (GTK_GRID (table), label, 1, 0, 1, 1);
703
704 label = make_label (_("Free, easy, personal accounting for everyone"), 0, 0);
705 gimp_label_set_attributes(GTK_LABEL(label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
706 gtk_grid_attach (GTK_GRID (table), label, 1, 1, 1, 1);
707
708
709 widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
710 gtk_box_pack_start (GTK_BOX (content_area), widget, FALSE, FALSE, 0);
711
712
713 mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_MEDIUM);
714 gtk_box_pack_start (GTK_BOX (content_area), mainvbox, FALSE, FALSE, 0);
715 gtk_widget_set_halign (mainvbox, GTK_ALIGN_CENTER);
716 gtk_container_set_border_width (GTK_CONTAINER(mainvbox), SPACING_LARGE);
717
718 //label = make_label (_("What do you want to do:"), 0, 0);
719 //gimp_label_set_attributes(GTK_LABEL(label), PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD, -1);
720 //gtk_box_pack_start (GTK_BOX (mainvbox), label, FALSE, FALSE, 0);
721
722 widget = gtk_button_new_with_mnemonic(_("Open _last opened file"));
723 gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
724 g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome_cb), GINT_TO_POINTER(HB_WELCOME_OPENLAST));
725
726 widget = gtk_button_new_with_mnemonic(_("Create a _new file"));
727 gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
728 g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome_cb), GINT_TO_POINTER(HB_WELCOME_CREATENEW));
729
730 widget = gtk_button_new_with_mnemonic(_("_Open an existing file"));
731 gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
732 g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome_cb), GINT_TO_POINTER(HB_WELCOME_OPENEXISTING));
733
734 widget = gtk_button_new_with_mnemonic(_("Open the _example file"));
735 gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
736 g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome_cb), GINT_TO_POINTER(HB_WELCOME_OPENSAMPLE));
737
738 widget = gtk_button_new_with_mnemonic(_("Read HomeBank _Manual"));
739 gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
740 g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome_cb), GINT_TO_POINTER(HB_WELCOME_READMANUAL));
741
742 widget = gtk_button_new_with_mnemonic(_("Configure _preferences"));
743 gtk_box_pack_start (GTK_BOX (mainvbox), widget, FALSE, FALSE, 0);
744 g_signal_connect (widget, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome_cb), GINT_TO_POINTER(HB_WELCOME_CONFIGPREF));
745
746 check = gtk_check_button_new_with_mnemonic (_("Show this window next time"));
747 gtk_box_pack_end (GTK_BOX (mainvbox), check, FALSE, FALSE, SPACING_SMALL);
748
749 //init
750 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(check), PREFS->showwelcome);
751
752 //connect all our signals
753 g_signal_connect (dialog, "destroy", G_CALLBACK (gtk_widget_destroyed), &dialog);
754
755 gtk_widget_show_all (dialog);
756
757 //wait for the user
758 gint result = gtk_dialog_run (GTK_DIALOG (dialog));
759
760 PREFS->showwelcome = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(check));
761
762 // cleanup and destroy
763 gtk_widget_destroy (dialog);
764
765 // do appropriate action
766 switch(result)
767 {
768 case HB_WELCOME_OPENLAST:
769 {
770 gchar *rawfilepath = homebank_lastopenedfiles_load();
771 ui_mainwindow_open_check(GLOBALS->mainwindow, rawfilepath);
772 }
773 break;
774 case HB_WELCOME_READMANUAL:
775 ui_mainwindow_action_help();
776 break;
777 case HB_WELCOME_CONFIGPREF:
778 ui_mainwindow_action_preferences();
779 break;
780 case HB_WELCOME_CREATENEW:
781 ui_mainwindow_action_new();
782 break;
783 case HB_WELCOME_OPENEXISTING:
784 ui_mainwindow_action_open();
785 break;
786 case HB_WELCOME_OPENSAMPLE:
787 hbfile_change_filepath(g_build_filename(homebank_app_get_datas_dir(), "example.xhb", NULL));
788 ui_mainwindow_open_internal(GLOBALS->mainwindow, NULL);
789 break;
790 }
791
792 return result;
793 }
794
795
ui_mainwindow_action_help_updates(void)796 static void ui_mainwindow_action_help_updates(void)
797 {
798 const gchar *link = HOMEBANK_URL_HELP_UPDATES;
799
800 homebank_util_url_show (link);
801 }
802
803
ui_mainwindow_action_help_online(void)804 static void ui_mainwindow_action_help_online(void)
805 {
806 const gchar *link = HOMEBANK_URL_HELP_ONLINE;
807
808 homebank_util_url_show (link);
809 }
810
ui_mainwindow_action_help_donate(void)811 static void ui_mainwindow_action_help_donate(void)
812 {
813 const gchar *link = HOMEBANK_URL_HELP_DONATE;
814
815 homebank_util_url_show (link);
816 }
817
818
ui_mainwindow_action_help_translate(void)819 static void ui_mainwindow_action_help_translate(void)
820 {
821 const gchar *link = HOMEBANK_URL_HELP_TRANSLATE;
822
823 homebank_util_url_show (link);
824 }
825
826
ui_mainwindow_action_help_problem(void)827 static void ui_mainwindow_action_help_problem(void)
828 {
829 const gchar *link = HOMEBANK_URL_HELP_PROBLEM;
830
831 homebank_util_url_show (link);
832 }
833
834
835 /* hbfile functions -------------------- */
836
837
838 /*
839 **
840 */
ui_mainwindow_selection(GtkTreeSelection * treeselection,gpointer user_data)841 static void ui_mainwindow_selection(GtkTreeSelection *treeselection, gpointer user_data)
842 {
843 ui_mainwindow_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), GINT_TO_POINTER(UF_SENSITIVE));
844 }
845
846
ui_mainwindow_close_openbooks(void)847 static void ui_mainwindow_close_openbooks(void)
848 {
849 GList *lacc, *elt;
850
851 DB( g_print("\n[ui-mainwindow] close openbooks\n") );
852
853 lacc = elt = g_hash_table_get_values(GLOBALS->h_acc);
854 while (elt != NULL)
855 {
856 Account *item = elt->data;
857
858 if(item->window)
859 {
860 gtk_widget_destroy(GTK_WIDGET(item->window));
861 item->window = NULL;
862 }
863
864 elt = g_list_next(elt);
865 }
866 g_list_free(lacc);
867
868 }
869
870
871
872 /*
873 **
874 */
ui_mainwindow_clear(GtkWidget * widget,gpointer user_data)875 void ui_mainwindow_clear(GtkWidget *widget, gpointer user_data)
876 {
877 struct hbfile_data *data;
878 gboolean file_clear = GPOINTER_TO_INT(user_data);
879 GSList *list;
880
881 DB( g_print("\n[ui-mainwindow] clear\n") );
882
883 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
884
885 // Close opened account window
886 // Clear TreeView
887 ui_mainwindow_close_openbooks();
888
889 //5.5.1 should close any toplevel windows as well (reports...)
890 DB( g_print(" closing %d windows\n", g_slist_length(GLOBALS->openwindows) ));
891 list = GLOBALS->openwindows;
892 while( list != NULL)
893 {
894 GtkWindow *window = GTK_WINDOW(list->data);
895
896 DB( g_print(" closing type:%d title:'%s'\n",
897 gtk_window_get_window_type(window),
898 gtk_window_get_title(window) ));
899
900 gtk_widget_destroy(GTK_WIDGET(window));
901 list = g_slist_next(list);
902 }
903
904 gtk_tree_store_clear(GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_acc))));
905 gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_upc))));
906 gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_top))));
907
908 data->showall = FALSE;
909 ui_hub_account_dispose(data);
910 ui_hub_account_setup(data);
911
912 hbfile_cleanup(file_clear);
913 hbfile_setup(file_clear);
914
915 }
916
917
918 /*
919 ** add some transactions directly
920 */
ui_mainwindow_addtransactions(GtkWidget * widget,gpointer user_data)921 void ui_mainwindow_addtransactions(GtkWidget *widget, gpointer user_data)
922 {
923 struct hbfile_data *data;
924 GtkWidget *window;
925 gint result = HB_RESPONSE_ADD;
926 gint kacc, count;
927 Transaction *ope;
928
929 DB( g_print("\n[ui-mainwindow] add transactions\n") );
930
931 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
932
933 /* init the transaction */
934 homebank_app_date_get_julian();
935
936 //#1656531
937 kacc = (data->acc != NULL) ? data->acc->key : 0;
938 window = create_deftransaction_window(GTK_WINDOW(data->window), TXN_DLG_ACTION_ADD, TXN_DLG_TYPE_TXN, kacc);
939 ope = da_transaction_malloc();
940 count = 0;
941 while(result == HB_RESPONSE_ADD || result == HB_RESPONSE_ADDKEEP)
942 {
943 /* fill in the transaction */
944 if( result == HB_RESPONSE_ADD )
945 {
946 da_transaction_init(ope, kacc);
947 }
948
949 deftransaction_set_transaction(window, ope);
950
951 result = gtk_dialog_run (GTK_DIALOG (window));
952
953 DB( g_print(" - dialog result is %d\n", result) );
954
955 if(result == HB_RESPONSE_ADD || result == HB_RESPONSE_ADDKEEP || result == GTK_RESPONSE_ACCEPT)
956 {
957 deftransaction_get(window, NULL);
958 transaction_add(GTK_WINDOW(GLOBALS->mainwindow), ope);
959 //#1831975
960 if(PREFS->txn_showconfirm)
961 deftransaction_external_confirm(window, ope);
962
963 DB( g_print(" - added 1 transaction to %d\n", ope->kacc) );
964
965 ui_hub_account_compute(GLOBALS->mainwindow, NULL);
966
967 count++;
968 }
969 }
970
971 da_transaction_free(ope);
972
973 deftransaction_dispose(window, NULL);
974 gtk_widget_destroy (window);
975
976 /* todo optimize this */
977 if(count > 0)
978 {
979 GLOBALS->changes_count += count;
980 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE+UF_REFRESHALL));
981 }
982 }
983
984
ui_mainwindow_open_backup_check_confirm(gchar * filepath)985 static gboolean ui_mainwindow_open_backup_check_confirm(gchar *filepath)
986 {
987 gboolean retval = FALSE;
988 gchar *basename, *secondtext;
989 gboolean result;
990
991 basename = g_path_get_basename(filepath);
992 secondtext = g_strdup_printf (
993 _("You are about to open the backup file '%s'.\n\nAre you sure you want to do this?"), basename);
994
995 result = ui_dialog_msg_confirm_alert(
996 GTK_WINDOW(GLOBALS->mainwindow),
997 _("Open the backup file?"),
998 secondtext,
999 _("_Open backup")
1000 );
1001
1002 g_free(secondtext);
1003 g_free(basename);
1004
1005 if( result == GTK_RESPONSE_OK )
1006 retval = TRUE;
1007
1008 return retval;
1009 }
1010
1011
ui_mainwindow_open_check(GtkWidget * widget,gchar * filepath)1012 void ui_mainwindow_open_check(GtkWidget *widget, gchar *filepath)
1013 {
1014 //struct hbfile_data *data;
1015 gboolean doopen = TRUE;
1016
1017 if( filepath == NULL )
1018 return;
1019
1020 DB( g_print("\n[ui-mainwindow] open check\n") );
1021
1022 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1023
1024 DB( g_print(" path='%s'\n", filepath) );
1025
1026 if (g_file_test (filepath, G_FILE_TEST_EXISTS) == TRUE)
1027 {
1028 //#1710955 test for backup open
1029 if( hbfile_file_isbackup(filepath) )
1030 {
1031 if( ui_mainwindow_open_backup_check_confirm(filepath) == TRUE )
1032 {
1033 GLOBALS->hbfile_is_bak = TRUE;
1034 doopen = TRUE;
1035 }
1036 else
1037 {
1038 doopen = FALSE;
1039 }
1040 }
1041 }
1042 else
1043 {
1044 g_warning (_("Unable to open '%s', the file does not exist.\n"), filepath);
1045 }
1046
1047 if(doopen)
1048 {
1049 hbfile_change_filepath(g_strdup(filepath));
1050 ui_mainwindow_open_internal(widget, NULL);
1051 }
1052
1053 g_free(filepath);
1054 }
1055
1056
ui_mainwindow_open(GtkWidget * widget,gpointer user_data)1057 void ui_mainwindow_open(GtkWidget *widget, gpointer user_data)
1058 {
1059 //struct hbfile_data *data;
1060 gboolean bakmode = GPOINTER_TO_INT(user_data);;
1061 gboolean doopen = TRUE;
1062 gchar *filename = NULL;
1063
1064 DB( g_print("\n[ui-mainwindow] open\n") );
1065
1066 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1067
1068 //#1791554 do ask for save confirm
1069 if( bakmode != TRUE )
1070 doopen = ui_dialog_msg_savechanges(widget,NULL);
1071
1072 if( doopen == TRUE )
1073 {
1074 if( ui_file_chooser_xhb(GTK_FILE_CHOOSER_ACTION_OPEN, &filename, bakmode) == TRUE )
1075 {
1076 ui_mainwindow_open_check(widget, filename);
1077 }
1078 }
1079 }
1080
1081
1082 /*
1083 * open the file stored in GLOBALS->xhb_filepath
1084 */
ui_mainwindow_open_internal(GtkWidget * widget,gpointer user_data)1085 void ui_mainwindow_open_internal(GtkWidget *widget, gpointer user_data)
1086 {
1087 struct hbfile_data *data;
1088 gint r;
1089
1090 DB( g_print("\n[ui-mainwindow] open internal\n") );
1091
1092 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1093
1094 if( GLOBALS->xhb_filepath != NULL )
1095 {
1096 DB( g_print(" - filename: '%s'\n", GLOBALS->xhb_filepath) );
1097
1098 ui_mainwindow_clear(GLOBALS->mainwindow, GINT_TO_POINTER(FALSE));
1099 GLOBALS->hbfile_is_new = FALSE;
1100
1101 r = homebank_load_xml(GLOBALS->xhb_filepath);
1102 if( r == XML_OK )
1103 {
1104 DB( g_print(" - file loaded ok : rcode=%d\n", r) );
1105
1106 GLOBALS->xhb_timemodified = hbfile_file_get_time_modified(GLOBALS->xhb_filepath);
1107 hbfile_file_hasrevert(GLOBALS->xhb_filepath);
1108
1109 if(PREFS->appendscheduled)
1110 scheduled_post_all_pending();
1111
1112 if(PREFS->do_update_currency)
1113 ui_cur_manage_dialog_update_currencies(GTK_WINDOW(GLOBALS->mainwindow));
1114
1115 homebank_lastopenedfiles_save();
1116
1117 //TODO: delete this after computing done at xml read
1118 account_compute_balances();
1119
1120 ui_mainwindow_recent_add(data, GLOBALS->xhb_filepath);
1121 }
1122 else
1123 {
1124 gchar *msg = _("Unknown error");
1125
1126 switch(r)
1127 {
1128 case XML_IO_ERROR:
1129 msg = _("I/O error for file '%s'.");
1130 break;
1131 case XML_FILE_ERROR:
1132 msg = _("The file '%s' is not a valid HomeBank file.");
1133 break;
1134 case XML_VERSION_ERROR:
1135 msg = _("The file '%s' was saved with a higher version of HomeBank\nand cannot be loaded by the current version.");
1136 break;
1137 }
1138
1139 ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_ERROR,
1140 _("File error"),
1141 msg,
1142 GLOBALS->xhb_filepath
1143 );
1144
1145 ui_mainwindow_clear(GLOBALS->mainwindow, GINT_TO_POINTER(TRUE));
1146
1147 }
1148
1149 ui_hub_account_populate(GLOBALS->mainwindow, NULL);
1150 ui_hub_scheduled_populate(GLOBALS->mainwindow, NULL);
1151 ui_hub_spending_populate(GLOBALS->mainwindow, NULL);
1152 ui_hub_transaction_populate(data);
1153
1154 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_VISUAL));
1155 }
1156
1157
1158 }
1159
1160
1161 /*
1162 **
1163 */
ui_mainwindow_save(GtkWidget * widget,gpointer user_data)1164 void ui_mainwindow_save(GtkWidget *widget, gpointer user_data)
1165 {
1166 struct hbfile_data *data;
1167 gboolean saveas = GPOINTER_TO_INT(user_data);
1168 gchar *filename = NULL;
1169 gint r = XML_UNSET;
1170
1171 DB( g_print("\n[ui-mainwindow] save\n") );
1172
1173 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1174
1175 if( GLOBALS->hbfile_is_new == TRUE )
1176 saveas = 1;
1177
1178 //#1710955 test for backup open
1179 if( GLOBALS->hbfile_is_bak == TRUE )
1180 {
1181 //todo: later for backup, should also remove datetime and .bak
1182 hbfile_change_filepath(hb_filename_new_with_extension(GLOBALS->xhb_filepath, "xhb"));
1183 saveas = 1;
1184 }
1185
1186 if(saveas == 1)
1187 {
1188 if(ui_file_chooser_xhb(GTK_FILE_CHOOSER_ACTION_SAVE, &filename, FALSE) == TRUE)
1189 {
1190 DB( g_print(" + should save as '%s'\n", filename) );
1191 homebank_file_ensure_xhb(filename);
1192 homebank_backup_current_file();
1193 r = homebank_save_xml(GLOBALS->xhb_filepath);
1194 GLOBALS->hbfile_is_new = FALSE;
1195 GLOBALS->hbfile_is_bak = FALSE;
1196 }
1197 else
1198 return;
1199 }
1200 else
1201 {
1202 guint64 time_modified = hbfile_file_get_time_modified (GLOBALS->xhb_filepath);
1203 gint result = GTK_RESPONSE_OK;
1204
1205 DB( g_print(" + should quick save '%s'\n + time: open=%lu :: now=%lu\n", GLOBALS->xhb_filepath, GLOBALS->xhb_timemodified, time_modified) );
1206
1207 if( GLOBALS->xhb_timemodified != time_modified )
1208 {
1209 result = ui_dialog_msg_confirm_alert(
1210 GTK_WINDOW(GLOBALS->mainwindow),
1211 _("The file has been modified since reading it."),
1212 _("If you save it, all the external changes could be lost. Save it anyway?"),
1213 _("S_ave Anyway")
1214 );
1215
1216 if( result != GTK_RESPONSE_OK )
1217 return;
1218 }
1219
1220 DB( g_print(" + saving...\n") );
1221 homebank_file_ensure_xhb(NULL);
1222 homebank_backup_current_file();
1223 r = homebank_save_xml(GLOBALS->xhb_filepath);
1224 }
1225
1226 if(r == XML_OK)
1227 {
1228 DB( g_print(" + OK...\n") );
1229 GLOBALS->changes_count = 0;
1230 GLOBALS->xhb_timemodified = hbfile_file_get_time_modified (GLOBALS->xhb_filepath);
1231 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_VISUAL));
1232 }
1233 else
1234 {
1235 gchar *msg = _("I/O error for file '%s'.");
1236
1237 ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_ERROR,
1238 _("File error"),
1239 msg,
1240 GLOBALS->xhb_filepath
1241 );
1242 }
1243 }
1244
1245
ui_mainwindow_update(GtkWidget * widget,gpointer user_data)1246 void ui_mainwindow_update(GtkWidget *widget, gpointer user_data)
1247 {
1248 struct hbfile_data *data;
1249 gint flags;
1250
1251 DB( g_print("\n[ui-mainwindow] update %p\n", user_data) );
1252
1253 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1254 //data = INST_DATA(widget);
1255
1256 flags = GPOINTER_TO_INT(user_data);
1257
1258 /* changes */
1259 #if MYDEBUG == 1
1260 gchar *chgtxt = g_strdup_printf("%d", GLOBALS->changes_count);
1261 gtk_label_set_label(GTK_LABEL(data->dbgchange), chgtxt);
1262 g_free(chgtxt);
1263 #endif
1264
1265 /* set window title */
1266 if(flags & UF_TITLE)
1267 {
1268 gchar *basename;
1269 gchar *changed;
1270
1271 DB( g_print(" 1: wintitle %p\n", data->wintitle) );
1272
1273 basename = g_path_get_basename(GLOBALS->xhb_filepath);
1274 g_free(data->wintitle);
1275 changed = (GLOBALS->changes_count > 0) ? "*" : "";
1276 data->wintitle = g_strdup_printf("%s%s - %s - " PROGNAME, changed, basename, GLOBALS->owner);
1277 gtk_window_set_title (GTK_WINDOW (gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), data->wintitle);
1278 g_free(basename);
1279 }
1280
1281 /* update disabled things */
1282 if(flags & UF_SENSITIVE)
1283 {
1284 GtkTreeSelection *selection;
1285 GtkTreeModel *model;
1286 GtkTreeIter iter;
1287 GtkTreePath *path;
1288 gboolean active,sensitive;
1289
1290 DB( g_print(" 2: disabled, opelist count\n") );
1291
1292 //#1656531
1293 data->acc = NULL;
1294
1295 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_acc));
1296 active = gtk_tree_selection_get_selected(selection, &model, &iter);
1297 if(active)
1298 {
1299 Account *acc;
1300 gint depth;
1301
1302 path = gtk_tree_model_get_path(model, &iter);
1303 depth = gtk_tree_path_get_depth(path);
1304
1305 if( depth > 1 )
1306 {
1307 DB( g_print(" depth is %d\n", depth) );
1308
1309 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, LST_DSPACC_DATAS, &acc, -1);
1310 data->acc = acc;
1311 }
1312 else
1313 active = FALSE;
1314 }
1315
1316 DB( g_print(" changes %d - new %d\n", GLOBALS->changes_count, GLOBALS->hbfile_is_new) );
1317
1318 // save
1319 DB( g_print(" save\n") );
1320 sensitive = (GLOBALS->changes_count != 0 ) ? TRUE : FALSE;
1321 gtk_widget_set_sensitive(data->MI_save, sensitive);
1322 gtk_widget_set_sensitive(data->BT_save, sensitive);
1323
1324 // backup
1325 DB( g_print(" has changes & revert\n") );
1326 sensitive = ( (GLOBALS->changes_count != 0) && GLOBALS->xhb_hasrevert ) ? TRUE : FALSE;
1327 gtk_widget_set_sensitive(data->MI_revert, sensitive);
1328 //1859346 restore backup avail anytime
1329 //gtk_widget_set_sensitive(data->MI_openbak, sensitive);
1330
1331 // report dialog ope, disable manage acc/pay/cat/bud/tag
1332 DB( g_print(" has report open ?\n") );
1333 sensitive = GLOBALS->define_off == 0 ? TRUE : FALSE;
1334 gtk_widget_set_sensitive(data->MI_manacc, sensitive);
1335 gtk_widget_set_sensitive(data->MI_manpay, sensitive);
1336 gtk_widget_set_sensitive(data->MI_mancat, sensitive);
1337 gtk_widget_set_sensitive(data->MI_manbud, sensitive);
1338 gtk_widget_set_sensitive(data->MI_manbudtable, sensitive);
1339 gtk_widget_set_sensitive(data->MI_mantag, sensitive);
1340 gtk_widget_set_sensitive(data->MI_prefs, sensitive);
1341
1342 gtk_widget_set_sensitive(data->BT_manacc, sensitive);
1343 gtk_widget_set_sensitive(data->BT_manpay, sensitive);
1344 gtk_widget_set_sensitive(data->BT_mancat, sensitive);
1345 gtk_widget_set_sensitive(data->BT_manbud, sensitive);
1346
1347 // empty account list: disable Archives, Edit, Filter, Add, Statistics, Overdrawn, Car Cost
1348 DB( g_print(" has acc ?\n") );
1349 sensitive = da_acc_length() > 0 ? TRUE : FALSE;
1350 gtk_widget_set_sensitive(data->MI_close, sensitive);
1351 gtk_widget_set_sensitive(data->MI_exportqif, sensitive);
1352 gtk_widget_set_sensitive(data->MI_anonymise, sensitive);
1353 gtk_widget_set_sensitive(data->MI_mantpl, sensitive);
1354 gtk_widget_set_sensitive(data->MI_txnadd, sensitive);
1355 gtk_widget_set_sensitive(data->MI_txnshow, sensitive);
1356 gtk_widget_set_sensitive(data->MI_txnshowall, sensitive);
1357 gtk_widget_set_sensitive(data->MI_repstat, sensitive);
1358 gtk_widget_set_sensitive(data->MI_reptime, sensitive);
1359 gtk_widget_set_sensitive(data->MI_repbal, sensitive);
1360 gtk_widget_set_sensitive(data->MI_repbudg, sensitive);
1361 gtk_widget_set_sensitive(data->MI_repvehi, sensitive);
1362
1363 gtk_widget_set_sensitive(data->BT_mantpl, sensitive);
1364 gtk_widget_set_sensitive(data->BT_txnshow, sensitive);
1365 gtk_widget_set_sensitive(data->BT_txnadd, sensitive);
1366 gtk_widget_set_sensitive(data->BT_repstat, sensitive);
1367 gtk_widget_set_sensitive(data->BT_reptime, sensitive);
1368 gtk_widget_set_sensitive(data->BT_repbal, sensitive);
1369 gtk_widget_set_sensitive(data->BT_repbudg, sensitive);
1370 gtk_widget_set_sensitive(data->BT_repvehi, sensitive);
1371
1372 // empty category list: disable Budget
1373 DB( g_print(" has cat ?\n") );
1374 sensitive = da_cat_length() > 1 ? TRUE : FALSE;
1375 gtk_widget_set_sensitive(data->MI_manbud, sensitive);
1376 gtk_widget_set_sensitive(data->MI_manbudtable, sensitive);
1377 gtk_widget_set_sensitive(data->BT_manbud, sensitive);
1378
1379
1380 //#1501129 no need to disable, P & C can be created from assign dialog
1381 //sensitive = ((da_cat_length() > 1) || (da_pay_length() > 1)) ? TRUE : FALSE;
1382 //gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ManageMenu/Assign"), sensitive);
1383 gtk_widget_set_sensitive(data->MI_manasg, sensitive);
1384 gtk_widget_set_sensitive(data->BT_manasg, sensitive);
1385
1386 // empty archive list: disable scheduled check
1387 DB( g_print(" has archive ?\n") );
1388 sensitive = da_archive_length() > 0 ? TRUE : FALSE;
1389 gtk_widget_set_sensitive(data->MI_addscheduled, sensitive);
1390
1391 // no active account: disable Edit, Over
1392 DB( g_print(" account active ?\n") );
1393 sensitive = (active == TRUE ) ? TRUE : FALSE;
1394 if(data->acc && data->acc->window != NULL)
1395 sensitive = FALSE;
1396 gtk_widget_set_sensitive(data->MI_txnshow, sensitive);
1397 gtk_widget_set_sensitive(data->BT_txnshow, sensitive);
1398 }
1399
1400 /* update toolbar, list */
1401 if(flags & UF_VISUAL)
1402 {
1403 DB( g_print(" 8: visual\n") );
1404
1405 if(PREFS->toolbar_style == 0)
1406 gtk_toolbar_unset_style(GTK_TOOLBAR(data->toolbar));
1407 else
1408 gtk_toolbar_set_style(GTK_TOOLBAR(data->toolbar), PREFS->toolbar_style-1);
1409
1410 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (data->LV_acc), PREFS->grid_lines);
1411 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_acc));
1412
1413 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (data->LV_upc), PREFS->grid_lines);
1414 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_upc));
1415
1416 //TODO: should add txn listview here as well
1417 DB( g_print(" - show toolbar=%d\n", PREFS->wal_toolbar) );
1418 hb_widget_visible(data->toolbar, PREFS->wal_toolbar);
1419
1420 DB( g_print(" - show top_spending=%d\n", PREFS->wal_spending) );
1421 hb_widget_visible(data->GR_top, PREFS->wal_spending);
1422
1423 //TODO: why this ? to redraw ?
1424 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data->CY_range), PREFS->date_range_wal);
1425
1426 DB( g_print(" - show upcoming=%d\n", PREFS->wal_upcoming) );
1427 hb_widget_visible(data->GR_upc, PREFS->wal_upcoming);
1428
1429 DB( g_print(" minor %d\n", PREFS->euro_active) );
1430 hb_widget_visible(data->MI_eurominor, PREFS->euro_active);
1431 }
1432
1433 if(flags & UF_REFRESHALL)
1434 {
1435 DB( g_print(" 16: refreshall\n") );
1436
1437 ui_hub_account_compute(GLOBALS->mainwindow, NULL);
1438 ui_hub_spending_populate(GLOBALS->mainwindow, NULL);
1439 ui_hub_scheduled_populate(GLOBALS->mainwindow, NULL);
1440 ui_hub_transaction_populate(data);
1441 }
1442
1443
1444 }
1445
1446
1447 static void
ui_mainwindow_onRowActivated(GtkTreeView * treeview,GtkTreePath * path,GtkTreeViewColumn * col,gpointer userdata)1448 ui_mainwindow_onRowActivated (GtkTreeView *treeview,
1449 GtkTreePath *path,
1450 GtkTreeViewColumn *col,
1451 gpointer userdata)
1452 {
1453 GtkTreeModel *model;
1454 GtkTreeIter iter;
1455
1456 DB( g_print ("\n[ui-mainwindow] A row has been double-clicked!\n") );
1457
1458 model = gtk_tree_view_get_model(treeview);
1459
1460 if (gtk_tree_model_get_iter(model, &iter, path))
1461 {
1462 Account *acc;
1463 gint dt;
1464
1465 gtk_tree_model_get(model, &iter, LST_DSPACC_DATAS, &acc, LST_DSPACC_DATATYPE, &dt, -1);
1466
1467 if( (dt == DSPACC_TYPE_NORMAL) && (acc != NULL) )
1468 {
1469
1470 DB( g_print ("Double-clicked row contains name %s\n", acc->name) );
1471
1472 ui_mainwindow_action_showtransactions(NULL, userdata);
1473
1474 //g_free(name);
1475 }
1476 }
1477 }
1478
1479
ui_mainwindow_destroy(GtkTreeView * treeview,gpointer user_data)1480 static void ui_mainwindow_destroy(GtkTreeView *treeview, gpointer user_data)
1481 {
1482 DB( g_print("\n[ui-mainwindow] destroy\n") );
1483
1484 }
1485
1486
1487 /*
1488 **
1489 */
ui_mainwindow_dispose(GtkWidget * widget,GdkEvent * event,gpointer user_data)1490 static gboolean ui_mainwindow_dispose(GtkWidget *widget, GdkEvent *event, gpointer user_data)
1491 {
1492 struct hbfile_data *data = user_data;
1493 struct WinGeometry *wg;
1494 gboolean retval = FALSE;
1495
1496 DB( g_print("\n[ui-mainwindow] delete-event\n") );
1497
1498 //store position and size
1499 wg = &PREFS->wal_wg;
1500 gtk_window_get_position(GTK_WINDOW(widget), &wg->l, &wg->t);
1501 gtk_window_get_size(GTK_WINDOW(widget), &wg->w, &wg->h);
1502 GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(widget));
1503 GdkWindowState state = gdk_window_get_state(gdk_window);
1504 wg->s = (state & GDK_WINDOW_STATE_MAXIMIZED) ? 1 : 0;
1505 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) );
1506
1507 PREFS->wal_vpaned = gtk_paned_get_position(GTK_PANED(data->vpaned));
1508 PREFS->wal_hpaned = gtk_paned_get_position(GTK_PANED(data->hpaned));
1509 DB( g_print(" - vpaned=%d hpaned=%d\n", PREFS->wal_vpaned, PREFS->wal_hpaned) );
1510
1511 if(PREFS->pnl_list_tab)
1512 g_free(PREFS->pnl_list_tab);
1513 PREFS->pnl_list_tab = g_strdup(gtk_stack_get_visible_child_name(GTK_STACK(data->stack)));
1514
1515 //todo
1516 if(ui_dialog_msg_savechanges(widget, NULL) == FALSE)
1517 {
1518 retval = TRUE;
1519 }
1520 else
1521 {
1522 //TODO: retval is useless and below should move to destroy
1523 retval = TRUE;
1524 gtk_widget_destroy(data->LV_top);
1525
1526 ui_hub_account_dispose(data);
1527
1528 g_free(data->wintitle);
1529 da_flt_free(data->filter);
1530 g_free(user_data);
1531
1532 gtk_main_quit();
1533 }
1534
1535 //TRUE:stop other handlers from being invoked for the event | FALSE: propagate
1536 return retval;
1537 }
1538
1539 #define HB_MIMETYPE "application/x-homebank"
1540
1541 static void
ui_mainwindow_cb_recent_chooser_clear(GtkRecentChooser * chooser,struct hbfile_data * data)1542 ui_mainwindow_cb_recent_chooser_clear (GtkRecentChooser *chooser, struct hbfile_data *data)
1543 {
1544 GList *list;
1545
1546 DB( g_print("\n[ui-mainwindow] recent chooser clear\n") );
1547
1548 list = gtk_recent_manager_get_items(data->recent_manager);
1549 while (list != NULL)
1550 {
1551 GtkRecentInfo *recentinfo = list->data;
1552
1553 if( !g_strcmp0(HB_MIMETYPE, gtk_recent_info_get_mime_type(recentinfo)) )
1554 {
1555 GError *error = NULL;
1556 const gchar *uri = gtk_recent_info_get_uri(recentinfo);
1557
1558 //DB( g_print(" mime-type='%s'\n", gtk_recent_info_get_mime_type(recentinfo)) );
1559
1560 gtk_recent_manager_remove_item(data->recent_manager, uri, &error);
1561 if (error)
1562 {
1563 g_warning ("Could not remove uri \"%s\": %s", uri, error->message);
1564 g_error_free (error);
1565 }
1566 }
1567 gtk_recent_info_unref(recentinfo);
1568 list = g_list_next(list);
1569 }
1570
1571 g_list_free(list);
1572 }
1573
1574
1575 static void
ui_mainwindow_recent_chooser_item_activated_cb(GtkRecentChooser * chooser,struct hbfile_data * data)1576 ui_mainwindow_recent_chooser_item_activated_cb (GtkRecentChooser *chooser, struct hbfile_data *data)
1577 {
1578 gchar *uri, *path;
1579 GError *error = NULL;
1580
1581 DB( g_print("\n[ui-mainwindow] recent chooser activated\n") );
1582
1583 uri = gtk_recent_chooser_get_current_uri (chooser);
1584
1585 DB( g_print(" '%s'\n", uri) );
1586
1587
1588 path = g_filename_from_uri (uri, NULL, &error);
1589 if (error)
1590 {
1591 g_warning ("Could not convert uri \"%s\" to a local path: %s", uri, error->message);
1592 g_error_free (error);
1593 return;
1594 }
1595
1596 if( ui_dialog_msg_savechanges(data->window, NULL) == TRUE )
1597 {
1598
1599 //todo: FixMe
1600 /*
1601 if (! load)
1602 {
1603 gpw_recent_remove (gpw, path);
1604 }
1605 */
1606
1607 hbfile_change_filepath(path);
1608 ui_mainwindow_open_internal(data->window, NULL);
1609 }
1610 else
1611 {
1612 g_free (path);
1613 }
1614 g_free (uri);
1615 }
1616
1617
ui_mainwindow_recent_add(struct hbfile_data * data,const gchar * path)1618 void ui_mainwindow_recent_add (struct hbfile_data *data, const gchar *path)
1619 {
1620 GtkRecentData *recent_data;
1621 gchar *uri;
1622 GError *error = NULL;
1623
1624 DB( g_print("\n[ui-mainwindow] recent_add\n") );
1625
1626 DB( g_print(" - file has .xhb suffix = %d\n", g_str_has_suffix (path, ".xhb") ) );
1627
1628 if( g_str_has_suffix (path, ".xhb") == FALSE ) //ignore reverted file
1629 return;
1630
1631 uri = g_filename_to_uri (path, NULL, &error);
1632 if (error)
1633 {
1634 g_warning ("Could not convert uri \"%s\" to a local path: %s", uri, error->message);
1635 g_error_free (error);
1636 return;
1637 }
1638
1639 recent_data = g_slice_new (GtkRecentData);
1640
1641 recent_data->display_name = NULL;
1642 recent_data->description = NULL;
1643 recent_data->mime_type = HB_MIMETYPE;
1644 recent_data->app_name = (gchar *) g_get_application_name ();
1645 recent_data->app_exec = g_strjoin (" ", g_get_prgname (), "%u", NULL);
1646 recent_data->groups = NULL;
1647 recent_data->is_private = FALSE;
1648
1649 if (!gtk_recent_manager_add_full (data->recent_manager,
1650 uri,
1651 recent_data))
1652 {
1653 g_warning ("Unable to add '%s' to the list of recently used documents", uri);
1654 }
1655
1656 g_free (uri);
1657 g_free (recent_data->app_exec);
1658 g_slice_free (GtkRecentData, recent_data);
1659
1660 }
1661
1662
1663 enum
1664 {
1665 TARGET_URI_LIST
1666 };
1667
1668 static GtkTargetEntry drop_types[] =
1669 {
1670 {"text/uri-list", 0, TARGET_URI_LIST}
1671 };
1672
ui_mainwindow_drag_data_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * selection_data,guint info,guint time,GtkWindow * window)1673 static void ui_mainwindow_drag_data_received (GtkWidget *widget,
1674 GdkDragContext *context,
1675 gint x, gint y,
1676 GtkSelectionData *selection_data,
1677 guint info, guint time, GtkWindow *window)
1678 {
1679 gchar **uris, **str;
1680 gchar *newseldata;
1681 gint n_uris, filetype, slen;
1682 GError *error = NULL;
1683
1684 if (info != TARGET_URI_LIST)
1685 return;
1686
1687 DB( g_print("\n[ui-mainwindow] drag_data_received\n") );
1688
1689 /* On MS-Windows, it looks like `selection_data->data' is not NULL terminated. */
1690 slen = gtk_selection_data_get_length(selection_data);
1691 newseldata = g_new (gchar, slen + 1);
1692 memcpy (newseldata, gtk_selection_data_get_data(selection_data), slen);
1693 newseldata[slen] = 0;
1694 //DB( g_print(" - seldata ='%s'\n", gtk_selection_data_get_data(selection_data) ) );
1695 //DB( g_print(" - newseldata ='%s'\n", newseldata ) );
1696
1697 uris = g_uri_list_extract_uris (newseldata);
1698 n_uris = g_strv_length(uris);
1699 DB( g_print(" - dragged %d files (len=%d)\n", n_uris, slen ) );
1700
1701 g_free(newseldata);
1702
1703 //single file: check for xhb
1704 if(n_uris == 1)
1705 {
1706 filetype = hb_filename_type_get_by_extension(*uris);
1707
1708 DB( g_print(" - filetype is homebank (%d)\n", filetype) );
1709
1710 if( filetype == FILETYPE_HOMEBANK )
1711 {
1712 gchar *path = g_filename_from_uri (*uris, NULL, &error);
1713
1714 if( path != NULL )
1715 {
1716 DB( g_print(" - path is '%s'\n", path) );
1717 hbfile_change_filepath(g_strdup(path));
1718 ui_mainwindow_open_internal(GTK_WIDGET(window), NULL);
1719 goto end_drop;
1720 }
1721 else
1722 {
1723 g_warning ("Could not convert uri to local path: %s", error->message);
1724 g_error_free (error);
1725 }
1726 g_free (path);
1727 }
1728 /* we no more manage error here
1729 ui_dialog_msg_infoerror(GTK_WINDOW(window), GTK_MESSAGE_ERROR,
1730 _("File error"),
1731 _("The file %s is not a valid HomeBank file."),
1732 path);
1733 */
1734 }
1735
1736 //collect known filetype to import
1737 DB( g_print(" - collect %d files\n", n_uris) );
1738
1739 gchar **paths = g_new (gchar *, n_uris + 1);
1740 slen = 0;
1741 for (str = uris; *str; str++)
1742 {
1743 filetype = hb_filename_type_get_by_extension(*str);
1744 if( filetype != FILETYPE_HOMEBANK && filetype != FILETYPE_UNKNOWN )
1745 {
1746 gchar *path = g_filename_from_uri (*str, NULL, NULL);
1747
1748 if( path != NULL )
1749 {
1750 DB( g_print(" - append %d '%s'\n", slen, path ) );
1751 paths[slen++] = path;
1752 }
1753 }
1754 }
1755 paths[slen] = NULL;
1756
1757 if( slen > 0 )
1758 {
1759 ui_import_assistant_new( paths );
1760 }
1761
1762
1763 end_drop:
1764 g_strfreev (uris);
1765 }
1766
1767
ui_mainwindow_create_recent_chooser_menu(struct hbfile_data * data)1768 static GtkWidget *ui_mainwindow_create_recent_chooser_menu (struct hbfile_data *data)
1769 {
1770 GtkWidget *recent_menu, *menuitem;
1771 GtkRecentFilter *filter;
1772
1773 recent_menu = gtk_recent_chooser_menu_new_for_manager (data->recent_manager);
1774 gtk_recent_chooser_set_local_only (GTK_RECENT_CHOOSER (recent_menu), FALSE);
1775 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (recent_menu), GTK_RECENT_SORT_MRU);
1776 //todo: add a user pref for this
1777 gtk_recent_chooser_set_limit(GTK_RECENT_CHOOSER (recent_menu), 10);
1778 gtk_recent_chooser_set_show_icons (GTK_RECENT_CHOOSER (recent_menu), FALSE);
1779 //gtk_recent_chooser_menu_set_show_numbers (GTK_RECENT_CHOOSER_MENU (recent_menu), TRUE);
1780
1781 filter = gtk_recent_filter_new ();
1782 //gtk_recent_filter_add_application (filter, g_get_application_name());
1783 gtk_recent_filter_add_pattern (filter, "*.[Xx][Hh][Bb]");
1784 gtk_recent_chooser_set_filter (GTK_RECENT_CHOOSER (recent_menu), filter);
1785
1786 gtk_menu_shell_append (GTK_MENU_SHELL (recent_menu), gtk_separator_menu_item_new());
1787 menuitem = hbtk_menu_add_menuitem(recent_menu, _("Clear") );
1788
1789 g_signal_connect (recent_menu, "item-activated", G_CALLBACK (ui_mainwindow_recent_chooser_item_activated_cb), data);
1790 g_signal_connect (menuitem, "activate", G_CALLBACK (ui_mainwindow_cb_recent_chooser_clear), (gpointer)data);
1791
1792 return recent_menu;
1793 }
1794
1795
1796 static GtkWidget *
ui_mainwindow_menubar_create(struct hbfile_data * data)1797 ui_mainwindow_menubar_create(struct hbfile_data *data)
1798 {
1799 GtkWidget *menubar;
1800 GtkWidget *menu, *submenu;
1801 GtkWidget *menuitem;
1802 GtkAccelGroup *accel_group = NULL;
1803
1804 menubar = gtk_menu_bar_new ();
1805
1806 accel_group = gtk_accel_group_new();
1807 gtk_window_add_accel_group(GTK_WINDOW(data->window), accel_group);
1808
1809 menu = hbtk_menubar_add_menu(menubar, _("_File"), &data->ME_menufile);
1810
1811 data->MI_new = menuitem = hbtk_menu_add_menuitem(menu, _("_New"));
1812 gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_KEY_n, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
1813 data->MI_open = menuitem = hbtk_menu_add_menuitem(menu, _("_Open..."));
1814 gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_KEY_o, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
1815 menuitem = hbtk_menu_add_menuitem(menu, _("Open _Recent"));
1816 submenu = ui_mainwindow_create_recent_chooser_menu (data);
1817 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
1818
1819 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
1820 data->MI_save = menuitem = hbtk_menu_add_menuitem(menu, _("_Save"));
1821 gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_KEY_s, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
1822 data->MI_saveas = menuitem = hbtk_menu_add_menuitem(menu, _("Save _As..."));
1823 gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_KEY_s, GDK_SHIFT_MASK|GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
1824 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
1825 data->MI_import = hbtk_menu_add_menuitem(menu, _("Import..."));
1826 data->MI_exportqif = hbtk_menu_add_menuitem(menu, _("Export as QIF..."));
1827 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
1828 data->MI_revert = hbtk_menu_add_menuitem(menu, _("Revert"));
1829 data->MI_openbak = hbtk_menu_add_menuitem(menu, _("Restore backup"));
1830 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
1831 data->MI_properties = hbtk_menu_add_menuitem(menu, _("Properties..."));
1832 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
1833 data->MI_close = menuitem = hbtk_menu_add_menuitem(menu, _("_Close"));
1834 gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_KEY_w, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
1835 data->MI_quit = menuitem = hbtk_menu_add_menuitem(menu, _("_Quit"));
1836 gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_KEY_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
1837
1838 menu = hbtk_menubar_add_menu(menubar, _("_Edit"), &data->ME_menuedit);
1839
1840 data->MI_prefs = hbtk_menu_add_menuitem(menu, _("Preferences..."));
1841
1842 menu = hbtk_menubar_add_menu(menubar, _("_View"), &data->ME_menuview);
1843
1844 data->MI_showtbar = menuitem = gtk_check_menu_item_new_with_mnemonic(_("_Toolbar"));
1845 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1846 data->MI_showspend = menuitem = gtk_check_menu_item_new_with_mnemonic(_("_Top spending"));
1847 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1848 data->MI_showbotlist = menuitem = gtk_check_menu_item_new_with_mnemonic(_("_Bottom Lists"));
1849 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1850 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
1851 data->MI_eurominor = menuitem = gtk_check_menu_item_new_with_mnemonic(_("Euro minor"));
1852 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1853 gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_KEY_m, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
1854
1855 menu = hbtk_menubar_add_menu(menubar, _("_Manage"), &data->ME_menuman);
1856
1857 data->MI_manacc = hbtk_menu_add_menuitem(menu, _("Acc_ounts..."));
1858 data->MI_manpay = hbtk_menu_add_menuitem(menu, _("_Payees..."));
1859 data->MI_mancat = hbtk_menu_add_menuitem(menu, _("Categories..."));
1860 data->MI_mantpl = hbtk_menu_add_menuitem(menu, _("Scheduled/Template..."));
1861 data->MI_manbud = hbtk_menu_add_menuitem(menu, _("Budget..."));
1862 data->MI_manbudtable = hbtk_menu_add_menuitem(menu, _("Budget (table view)..."));
1863 data->MI_manasg = hbtk_menu_add_menuitem(menu, _("Assignments..."));
1864 data->MI_mancur = hbtk_menu_add_menuitem(menu, _("Currencies..."));
1865 data->MI_mantag = hbtk_menu_add_menuitem(menu, _("Tags..."));
1866
1867 menu = hbtk_menubar_add_menu(menubar, _("_Transactions"), &data->ME_menutxn);
1868
1869 data->MI_txnadd = hbtk_menu_add_menuitem(menu, _("Add..."));
1870 data->MI_txnshow = hbtk_menu_add_menuitem(menu, _("Show..."));
1871 data->MI_txnshowall = hbtk_menu_add_menuitem(menu, _("Show all...") );
1872 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
1873 data->MI_scheduler = hbtk_menu_add_menuitem(menu, _("Set scheduler..."));
1874 data->MI_addscheduled = hbtk_menu_add_menuitem(menu, _("Post scheduled"));
1875
1876 menu = hbtk_menubar_add_menu(menubar, _("_Reports"), &data->ME_menurep);
1877
1878 data->MI_repstat = hbtk_menu_add_menuitem(menu, _("_Statistics..."));
1879 data->MI_reptime = hbtk_menu_add_menuitem(menu, _("_Trend Time...") );
1880 data->MI_repbal = hbtk_menu_add_menuitem(menu, _("_Balance...") );
1881 data->MI_repbudg = hbtk_menu_add_menuitem(menu, _("B_udget..."));
1882 data->MI_repvehi = hbtk_menu_add_menuitem(menu, _("_Vehicle cost..."));
1883
1884 menu = hbtk_menubar_add_menu(menubar, _("_Tools"), &data->ME_menutool);
1885
1886 data->MI_welcome = hbtk_menu_add_menuitem(menu, _("Show welcome dialog..."));
1887 data->MI_filestats = hbtk_menu_add_menuitem(menu, _("File statistics...") );
1888 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
1889 data->MI_anonymise = hbtk_menu_add_menuitem(menu, _("Anonymize..."));
1890
1891 menu = hbtk_menubar_add_menu(menubar, _("_Help"), &data->ME_menuhelp);
1892
1893 data->MI_contents = menuitem = hbtk_menu_add_menuitem(menu, _("_Contents") );
1894 gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_KEY_F1, 0, GTK_ACCEL_VISIBLE);
1895 data->MI_online = hbtk_menu_add_menuitem(menu, _("Get Help Online...") );
1896 //donate also here ?
1897 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
1898 data->MI_updates = hbtk_menu_add_menuitem(menu, _("Check for updates...") );
1899 data->MI_relnote = hbtk_menu_add_menuitem(menu, _("Release Notes") );
1900 data->MI_problem = hbtk_menu_add_menuitem(menu, _("Report a Problem...") );
1901 data->MI_translate = hbtk_menu_add_menuitem(menu, _("Translate this Application...") );
1902 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
1903 data->MI_about = hbtk_menu_add_menuitem(menu, _("_About") );
1904
1905 return menubar;
1906 }
1907
1908
1909 static GtkWidget *
ui_mainwindow_toolbar_create(struct hbfile_data * data)1910 ui_mainwindow_toolbar_create(struct hbfile_data *data)
1911 {
1912 GtkWidget *toolbar, *button, *menu;
1913
1914 toolbar = gtk_toolbar_new();
1915
1916 data->BT_new = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_FILE_NEW, N_("New"), _("Create a new file"));
1917 data->BT_open = button = gtk_widget_new(GTK_TYPE_MENU_TOOL_BUTTON,
1918 "icon-name", ICONNAME_HB_FILE_OPEN,
1919 "label", _("Open"),
1920 "tooltip-text", _("Open a file"),
1921 NULL);
1922 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(button), 1);
1923 menu = ui_mainwindow_create_recent_chooser_menu(data);
1924 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (button), menu);
1925 gtk_menu_tool_button_set_arrow_tooltip_text (GTK_MENU_TOOL_BUTTON (button), _("Open a recently used file"));
1926
1927 data->BT_save = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_FILE_SAVE, N_("Save"), _("Save the current file"));
1928
1929 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), gtk_separator_tool_item_new(), -1);
1930
1931 data->BT_manacc = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_ACCOUNT , _("Account"), _("Manage the accounts"));
1932 data->BT_manpay = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_PAYEE , _("Payee"), _("Manage the payees"));
1933 data->BT_mancat = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_CATEGORY, _("Category"), _("Manage the categories"));
1934 data->BT_mantpl = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_ARCHIVE , _("Scheduled/Template"), _("Manage the scheduled/template transactions"));
1935 data->BT_manbud = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_BUDGET , _("Budget"), _("Manage the budget"));
1936 data->BT_manasg = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_ASSIGN , _("Assignment"), _("Manage the automatic assignments"));
1937
1938 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), gtk_separator_tool_item_new(), -1);
1939
1940 data->BT_txnshow = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_OPE_SHOW, _("Show"), _("Shows selected account transactions"));
1941 data->BT_txnadd = button = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_OPE_ADD, _("Add"), _("Add transactions"));
1942 g_object_set(button, "is-important", TRUE, NULL);
1943
1944 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), gtk_separator_tool_item_new(), -1);
1945
1946 data->BT_repstat = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_REP_STATS , _("Statistics"), _("Open the Statistics report"));
1947 data->BT_reptime = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_REP_TIME , _("Trend time"), _("Open the Trend Time report"));
1948 data->BT_repbal = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_REP_BALANCE, _("Balance"), _("Open the Balance report"));
1949 data->BT_repbudg = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_REP_BUDGET, _("Budget"), _("Open the Budget report"));
1950 data->BT_repvehi = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_REP_CAR , _("Vehicle cost"), _("Open the Vehicle cost report"));
1951
1952 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), gtk_separator_tool_item_new(), -1);
1953
1954 data->BT_help = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_HELP , _("Help"), _("Get Help Online..."));
1955 data->BT_donate = hbtk_toolbar_add_toolbutton(GTK_TOOLBAR(toolbar), ICONNAME_HB_DONATE, _("Donate"), _("Donate to HomeBank project"));
1956
1957 return toolbar;
1958 }
1959
1960
1961
1962 /*
1963 ** the window creation
1964 */
create_hbfile_window(GtkWidget * do_widget)1965 GtkWidget *create_hbfile_window(GtkWidget *do_widget)
1966 {
1967 struct hbfile_data *data;
1968 struct WinGeometry *wg;
1969 GtkWidget *mainvbox, *vbox, *box, *vpaned, *hpaned, *sidebar, *stack;
1970 GtkWidget *widget, *page, *menubar, *toolbar;
1971 GtkWidget *window;
1972
1973 DB( g_print("\n[ui-mainwindow] create main window\n") );
1974
1975 data = g_malloc0(sizeof(struct hbfile_data));
1976 if(!data) return NULL;
1977
1978 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1979
1980 //store our window private data
1981 g_object_set_data(G_OBJECT(window), "inst_data", (gpointer)data);
1982 DB( g_print(" - new window=%p, inst_data=%p\n", window, data) );
1983
1984 // this is our mainwindow, so store it to GLOBALS data
1985 data->window = window;
1986 GLOBALS->mainwindow = window;
1987
1988 mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1989 gtk_container_add (GTK_CONTAINER (window), mainvbox);
1990
1991 //menu and toolbar
1992 data->recent_manager = gtk_recent_manager_get_default ();
1993
1994 box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
1995 gtk_box_pack_start (GTK_BOX (mainvbox), box, FALSE, FALSE, 0);
1996
1997 menubar = ui_mainwindow_menubar_create(data);
1998 gtk_box_pack_start (GTK_BOX (box), menubar, TRUE, TRUE, 0);
1999
2000 #if HB_UNSTABLE_SHOW == TRUE
2001 menubar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
2002 gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(menubar)), GTK_STYLE_CLASS_MENUBAR);
2003 gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, FALSE, 0);
2004
2005 widget = gtk_label_new("Release Candidate Version ");
2006 gimp_label_set_attributes (GTK_LABEL (widget),
2007 PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
2008 PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
2009 -1);
2010 gtk_box_pack_end (GTK_BOX (menubar), widget, FALSE, FALSE, 0);
2011 widget = gtk_image_new_from_icon_name (ICONNAME_WARNING, GTK_ICON_SIZE_BUTTON);
2012 gtk_box_pack_end (GTK_BOX (menubar), widget, FALSE, FALSE, 0);
2013 gtk_widget_set_tooltip_markup(GTK_WIDGET(menubar),
2014 "<b>Guidelines:</b>\n"
2015 "- use only for TESTING or find BUGs\n"
2016 "- use A COPY of your data files\n"
2017 "- BUGs or CRASH can still occur"
2018 );
2019 #endif
2020
2021 #if MYDEBUG == 1
2022 widget = make_label(NULL, 1.0, 0.5);
2023 gtk_widget_set_margin_end(widget, 12);
2024 data->dbgchange = widget;
2025 gtk_box_pack_end (GTK_BOX (box), widget, FALSE, FALSE, 0);
2026 #endif
2027
2028
2029 toolbar = ui_mainwindow_toolbar_create(data);
2030 data->toolbar = toolbar;
2031 gtk_box_pack_start (GTK_BOX (mainvbox), toolbar, FALSE, FALSE, 0);
2032
2033 /* Add the main area */
2034 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
2035 //gtk_container_set_border_width (GTK_CONTAINER(vbox), SPACING_MEDIUM);
2036 gtk_box_pack_start (GTK_BOX (mainvbox), vbox, TRUE, TRUE, 0);
2037
2038 vpaned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
2039 data->vpaned = vpaned;
2040 gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
2041
2042 hpaned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
2043 data->hpaned = hpaned;
2044 gtk_paned_pack1 (GTK_PANED(vpaned), hpaned, FALSE, FALSE);
2045
2046 widget = ui_hub_account_create(data);
2047 //gtk_widget_set_size_request (widget, 100, -1);
2048 gtk_paned_pack1 (GTK_PANED(hpaned), widget, FALSE, FALSE);
2049
2050 widget = ui_hub_spending_create(data);
2051 //gtk_widget_set_size_request (widget, -1, 100);
2052 gtk_paned_pack2 (GTK_PANED(hpaned), widget, TRUE, FALSE);
2053
2054 box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
2055 data->GR_upc = box;
2056 gtk_paned_pack2 (GTK_PANED(vpaned), box, TRUE, FALSE);
2057
2058 sidebar = gtk_stack_sidebar_new ();
2059 gtk_box_pack_start (GTK_BOX (box), sidebar, FALSE, FALSE, 0);
2060
2061 stack = gtk_stack_new ();
2062 //gtk_stack_set_transition_type (GTK_STACK (stack), GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN);
2063 gtk_stack_sidebar_set_stack (GTK_STACK_SIDEBAR (sidebar), GTK_STACK (stack));
2064 data->stack = stack;
2065 gtk_box_pack_start (GTK_BOX (box), stack, TRUE, TRUE, 0);
2066
2067 page = ui_hub_scheduled_create(data);
2068 gtk_stack_add_titled (GTK_STACK (stack), page, "sched", _("Scheduled"));
2069 //gtk_paned_pack2 (GTK_PANED(vpaned), widget, TRUE, FALSE);
2070
2071 page = ui_hub_transaction_create(data, HUB_TXN_TYPE_FUTURE);
2072 gtk_stack_add_titled (GTK_STACK (stack), page, "futur", _("Future"));
2073
2074 page = ui_hub_transaction_create(data, HUB_TXN_TYPE_REMIND);
2075 gtk_stack_add_titled (GTK_STACK (stack), page, "remin", _("Remind"));
2076
2077
2078 //setup, init and show window
2079 wg = &PREFS->wal_wg;
2080 if(wg->s == 0)
2081 {
2082 gtk_window_move(GTK_WINDOW(window), wg->l, wg->t);
2083 gtk_window_resize(GTK_WINDOW(window), wg->w, wg->h);
2084 }
2085 else
2086 gtk_window_maximize(GTK_WINDOW(window));
2087
2088 gtk_widget_show_all (window);
2089
2090 //#1662197/1660910 moved after resize/show
2091 DB( g_print(" - vpaned=%d hpaned=%d\n", PREFS->wal_vpaned, PREFS->wal_hpaned) );
2092
2093 if(PREFS->wal_hpaned > 0)
2094 gtk_paned_set_position(GTK_PANED(data->hpaned), PREFS->wal_hpaned);
2095 if(PREFS->wal_vpaned > 0)
2096 gtk_paned_set_position(GTK_PANED(data->vpaned), PREFS->wal_vpaned);
2097
2098 if( PREFS->pnl_list_tab != NULL )
2099 gtk_stack_set_visible_child_name (GTK_STACK(data->stack), PREFS->pnl_list_tab);
2100
2101
2102 //todo: move this elsewhere
2103 DB( g_print(" - setup stuff\n") );
2104
2105 data->filter = da_flt_malloc();
2106 filter_reset(data->filter);
2107 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data->CY_range), PREFS->date_range_wal);
2108
2109 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data->MI_showtbar), PREFS->wal_toolbar);
2110 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data->MI_showspend), PREFS->wal_spending);
2111 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data->MI_showbotlist), PREFS->wal_upcoming);
2112
2113 /* Drag and drop support, set targets to NULL because we add the
2114 default uri_targets below */
2115
2116 /* support for opening a file by dragging onto the project window */
2117 gtk_drag_dest_set (GTK_WIDGET (window),
2118 GTK_DEST_DEFAULT_ALL,
2119 drop_types,
2120 G_N_ELEMENTS (drop_types),
2121 GDK_ACTION_COPY);
2122
2123 g_signal_connect (G_OBJECT (window), "drag-data-received",
2124 G_CALLBACK (ui_mainwindow_drag_data_received), window);
2125
2126 //connect all our signals
2127 DB( g_print(" - connect signals\n") );
2128
2129 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_acc)), "changed", G_CALLBACK (ui_mainwindow_selection), NULL);
2130 g_signal_connect (GTK_TREE_VIEW(data->LV_acc ), "row-activated", G_CALLBACK (ui_mainwindow_onRowActivated), GINT_TO_POINTER(2));
2131
2132 /* GtkWindow events */
2133 g_signal_connect (window, "delete-event", G_CALLBACK (ui_mainwindow_dispose), (gpointer)data);
2134 g_signal_connect (window, "destroy", G_CALLBACK (ui_mainwindow_destroy), NULL);
2135
2136 //menu signals
2137 g_signal_connect (data->MI_new , "activate", G_CALLBACK (ui_mainwindow_action_new), (gpointer)data);
2138 g_signal_connect (data->MI_open , "activate", G_CALLBACK (ui_mainwindow_action_open), (gpointer)data);
2139 g_signal_connect (data->MI_save , "activate", G_CALLBACK (ui_mainwindow_action_save), (gpointer)data);
2140 g_signal_connect (data->MI_saveas , "activate", G_CALLBACK (ui_mainwindow_action_saveas), (gpointer)data);
2141 g_signal_connect (data->MI_import , "activate", G_CALLBACK (ui_mainwindow_action_import), (gpointer)data);
2142 g_signal_connect (data->MI_exportqif , "activate", G_CALLBACK (ui_mainwindow_action_export), (gpointer)data);
2143 g_signal_connect (data->MI_revert , "activate", G_CALLBACK (ui_mainwindow_action_revert), (gpointer)data);
2144 g_signal_connect (data->MI_openbak , "activate", G_CALLBACK (ui_mainwindow_action_openbak), (gpointer)data);
2145 g_signal_connect (data->MI_properties , "activate", G_CALLBACK (ui_mainwindow_action_properties), (gpointer)data);
2146 g_signal_connect (data->MI_close , "activate", G_CALLBACK (ui_mainwindow_action_close), (gpointer)data);
2147 g_signal_connect (data->MI_quit , "activate", G_CALLBACK (ui_mainwindow_action_quit), (gpointer)data);
2148
2149 g_signal_connect (data->MI_prefs , "activate", G_CALLBACK (ui_mainwindow_action_preferences), (gpointer)data);
2150
2151 g_signal_connect (data->MI_showtbar , "toggled", G_CALLBACK (ui_mainwindow_action_toggle_toolbar), (gpointer)data);
2152 g_signal_connect (data->MI_showspend , "toggled", G_CALLBACK (ui_mainwindow_action_toggle_topspending), (gpointer)data);
2153 g_signal_connect (data->MI_showbotlist , "toggled", G_CALLBACK (ui_mainwindow_action_toggle_upcoming), (gpointer)data);
2154 g_signal_connect (data->MI_eurominor , "toggled", G_CALLBACK (ui_mainwindow_action_toggle_minor), (gpointer)data);
2155
2156 g_signal_connect (data->MI_manacc , "activate", G_CALLBACK (ui_mainwindow_action_defaccount), (gpointer)data);
2157 g_signal_connect (data->MI_manpay , "activate", G_CALLBACK (ui_mainwindow_action_defpayee), (gpointer)data);
2158 g_signal_connect (data->MI_mancat , "activate", G_CALLBACK (ui_mainwindow_action_defcategory), (gpointer)data);
2159 g_signal_connect (data->MI_mantpl , "activate", G_CALLBACK (ui_mainwindow_action_defarchive), (gpointer)data);
2160 g_signal_connect (data->MI_manbud , "activate", G_CALLBACK (ui_mainwindow_action_defbudget), (gpointer)data);
2161 g_signal_connect (data->MI_manbudtable , "activate", G_CALLBACK (ui_mainwindow_action_defbudgettable), (gpointer)data);
2162 g_signal_connect (data->MI_manasg , "activate", G_CALLBACK (ui_mainwindow_action_defassign), (gpointer)data);
2163 g_signal_connect (data->MI_mancur , "activate", G_CALLBACK (ui_mainwindow_action_defcurrency), (gpointer)data);
2164 g_signal_connect (data->MI_mantag , "activate", G_CALLBACK (ui_mainwindow_action_deftag), (gpointer)data);
2165
2166 g_signal_connect (data->MI_txnadd , "activate", G_CALLBACK (ui_mainwindow_action_addtransactions), (gpointer)data);
2167 g_signal_connect (data->MI_txnshow , "activate", G_CALLBACK (ui_mainwindow_action_showtransactions), (gpointer)data);
2168 g_signal_connect (data->MI_txnshowall , "activate", G_CALLBACK (ui_mainwindow_action_showalltransactions), (gpointer)data);
2169 g_signal_connect (data->MI_scheduler , "activate", G_CALLBACK (ui_mainwindow_action_properties), (gpointer)data);
2170 g_signal_connect (data->MI_addscheduled , "activate", G_CALLBACK (ui_mainwindow_action_checkscheduled), (gpointer)data);
2171
2172 g_signal_connect (data->MI_repstat , "activate", G_CALLBACK (ui_mainwindow_action_statistic), (gpointer)data);
2173 g_signal_connect (data->MI_reptime , "activate", G_CALLBACK (ui_mainwindow_action_trendtime), (gpointer)data);
2174 g_signal_connect (data->MI_repbal , "activate", G_CALLBACK (ui_mainwindow_action_balance), (gpointer)data);
2175 g_signal_connect (data->MI_repbudg , "activate", G_CALLBACK (ui_mainwindow_action_budget), (gpointer)data);
2176 g_signal_connect (data->MI_repvehi , "activate", G_CALLBACK (ui_mainwindow_action_vehiclecost), (gpointer)data);
2177
2178 g_signal_connect (data->MI_welcome , "activate", G_CALLBACK (ui_mainwindow_action_help_welcome), (gpointer)data);
2179 g_signal_connect (data->MI_filestats , "activate", G_CALLBACK (ui_mainwindow_action_file_statistics), (gpointer)data);
2180 g_signal_connect (data->MI_anonymise , "activate", G_CALLBACK (ui_mainwindow_action_anonymize), (gpointer)data);
2181
2182 g_signal_connect (data->MI_contents , "activate", G_CALLBACK (ui_mainwindow_action_help), (gpointer)data);
2183 g_signal_connect (data->MI_online , "activate", G_CALLBACK (ui_mainwindow_action_help_online), (gpointer)data);
2184 g_signal_connect (data->MI_updates , "activate", G_CALLBACK (ui_mainwindow_action_help_updates), (gpointer)data);
2185 g_signal_connect (data->MI_relnote , "activate", G_CALLBACK (ui_mainwindow_action_help_releasenotes), (gpointer)data);
2186 g_signal_connect (data->MI_problem , "activate", G_CALLBACK (ui_mainwindow_action_help_problem), (gpointer)data);
2187 g_signal_connect (data->MI_translate , "activate", G_CALLBACK (ui_mainwindow_action_help_translate), (gpointer)data);
2188 g_signal_connect (data->MI_about , "activate", G_CALLBACK (ui_mainwindow_action_about), (gpointer)data);
2189
2190
2191 //toolbar signals
2192 g_signal_connect (G_OBJECT (data->BT_new ), "clicked", G_CALLBACK (ui_mainwindow_action_new), (gpointer)data);
2193 g_signal_connect (G_OBJECT (data->BT_open ), "clicked", G_CALLBACK (ui_mainwindow_action_open), (gpointer)data);
2194 g_signal_connect (G_OBJECT (data->BT_save ), "clicked", G_CALLBACK (ui_mainwindow_action_save), (gpointer)data);
2195
2196 g_signal_connect (G_OBJECT (data->BT_manacc), "clicked", G_CALLBACK (ui_mainwindow_action_defaccount), (gpointer)data);
2197 g_signal_connect (G_OBJECT (data->BT_manpay), "clicked", G_CALLBACK (ui_mainwindow_action_defpayee), (gpointer)data);
2198 g_signal_connect (G_OBJECT (data->BT_mancat), "clicked", G_CALLBACK (ui_mainwindow_action_defcategory), (gpointer)data);
2199 g_signal_connect (G_OBJECT (data->BT_mantpl), "clicked", G_CALLBACK (ui_mainwindow_action_defarchive), (gpointer)data);
2200 g_signal_connect (G_OBJECT (data->BT_manbud), "clicked", G_CALLBACK (ui_mainwindow_action_defbudget), (gpointer)data);
2201 g_signal_connect (G_OBJECT (data->BT_manasg), "clicked", G_CALLBACK (ui_mainwindow_action_defassign), (gpointer)data);
2202
2203 g_signal_connect (G_OBJECT (data->BT_txnshow), "clicked", G_CALLBACK (ui_mainwindow_action_showtransactions), (gpointer)data);
2204 g_signal_connect (G_OBJECT (data->BT_txnadd), "clicked", G_CALLBACK (ui_mainwindow_action_addtransactions), (gpointer)data);
2205
2206 g_signal_connect (G_OBJECT (data->BT_repstat), "clicked", G_CALLBACK (ui_mainwindow_action_statistic), (gpointer)data);
2207 g_signal_connect (G_OBJECT (data->BT_reptime), "clicked", G_CALLBACK (ui_mainwindow_action_trendtime), (gpointer)data);
2208 g_signal_connect (G_OBJECT (data->BT_repbal ), "clicked", G_CALLBACK (ui_mainwindow_action_balance), (gpointer)data);
2209 g_signal_connect (G_OBJECT (data->BT_repbudg), "clicked", G_CALLBACK (ui_mainwindow_action_budget), (gpointer)data);
2210 g_signal_connect (G_OBJECT (data->BT_repvehi), "clicked", G_CALLBACK (ui_mainwindow_action_vehiclecost), (gpointer)data);
2211
2212 g_signal_connect (G_OBJECT (data->BT_help ), "clicked", G_CALLBACK (ui_mainwindow_action_help_online), (gpointer)data);
2213 g_signal_connect (G_OBJECT (data->BT_donate), "clicked", G_CALLBACK (ui_mainwindow_action_help_donate), (gpointer)data);
2214
2215 return window;
2216 }
2217
2218