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