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