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