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