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