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