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