1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2016 Maxime DOYEN
4 * This file is part of HomeBank.
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.
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.
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/>.
23 #include "dsp_mainwindow.h"
27 #include "list_account.h"
28 #include "list_upcoming.h"
29 #include "list_topspending.h"
31 #include "dsp_account.h"
32 #include "ui-assist-import.h"
33 #include "ui-assist-start.h"
34 #include "ui-account.h"
35 #include "ui-currency.h"
37 #include "ui-category.h"
38 #include "ui-archive.h"
39 #include "ui-assign.h"
40 #include "ui-budget.h"
42 #include "ui-hbfile.h"
43 #include "ui-transaction.h"
45 #include "rep_balance.h"
46 #include "rep_budget.h"
47 #include "rep_stats.h"
49 #include "rep_vehicle.h"
51 #include "gtk-chart.h"
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"
60 /****************************************************************************/
62 /****************************************************************************/
71 /* our global datas */
72 extern struct HomeBank
*GLOBALS
;
73 extern struct Preferences
*PREFS
;
74 extern gchar
*homebank_pixmaps_dir
;
77 /* our functions prototype */
78 static void ui_mainwindow_action_new(void);
79 static void ui_mainwindow_action_open(void);
80 static void ui_mainwindow_action_save(void);
81 static void ui_mainwindow_action_saveas(void);
82 static void ui_mainwindow_action_revert(void);
83 static void ui_mainwindow_action_properties(void);
84 static void ui_mainwindow_action_close(void);
85 static void ui_mainwindow_action_quit(void);
87 static void ui_mainwindow_action_defcurrency(void);
88 static void ui_mainwindow_action_defaccount(void);
89 static void ui_mainwindow_action_defpayee(void);
90 static void ui_mainwindow_action_defcategory(void);
91 static void ui_mainwindow_action_defarchive(void);
92 static void ui_mainwindow_action_defbudget(void);
93 static void ui_mainwindow_action_defassign(void);
94 static void ui_mainwindow_action_preferences(void);
96 static void ui_mainwindow_action_toggle_toolbar(GtkToggleAction
*action
);
97 static void ui_mainwindow_action_toggle_upcoming(GtkToggleAction
*action
);
98 static void ui_mainwindow_action_toggle_topspending(GtkToggleAction
*action
);
99 static void ui_mainwindow_action_toggle_minor(GtkToggleAction
*action
);
101 static void ui_mainwindow_action_showtransactions(void);
102 static void ui_mainwindow_action_addtransactions(void);
103 static void ui_mainwindow_action_checkscheduled(void);
105 static void ui_mainwindow_action_statistic(void);
106 static void ui_mainwindow_action_trendtime(void);
107 static void ui_mainwindow_action_budget(void);
108 static void ui_mainwindow_action_balance(void);
109 static void ui_mainwindow_action_vehiclecost(void);
111 static void ui_mainwindow_action_import(GtkAction
*action
);
112 static void ui_mainwindow_action_export(void);
113 static void ui_mainwindow_action_anonymize(void);
114 static void ui_mainwindow_action_file_statistics(void);
116 static void ui_mainwindow_action_pluginprefs(void);
118 static void ui_mainwindow_action_help(void);
119 void ui_mainwindow_action_help_welcome(void);
120 static void ui_mainwindow_action_help_online(void);
121 static void ui_mainwindow_action_help_translate(void);
122 static void ui_mainwindow_action_help_problem(void);
123 static void ui_mainwindow_action_about(void);
126 static GtkWidget
*ui_mainwindow_create_recent_chooser_menu (GtkRecentManager
*manager
);
128 static void ui_mainwindow_populate_topspending(GtkWidget
*widget
, gpointer user_data
);
130 void ui_mainwindow_open(GtkWidget
*widget
, gpointer user_data
);
132 void ui_mainwindow_save(GtkWidget
*widget
, gpointer user_data
);
133 void ui_mainwindow_revert(GtkWidget
*widget
, gpointer user_data
);
134 void ui_mainwindow_action(GtkWidget
*widget
, gpointer user_data
);
135 void ui_mainwindow_toggle_minor(GtkWidget
*widget
, gpointer user_data
);
136 void ui_mainwindow_clear(GtkWidget
*widget
, gpointer user_data
);
138 gboolean
ui_dialog_msg_savechanges(GtkWidget
*widget
, gpointer user_data
);
140 void ui_mainwindow_update(GtkWidget
*widget
, gpointer user_data
);
141 void ui_mainwindow_addtransactions(GtkWidget
*widget
, gpointer user_data
);
142 void ui_mainwindow_recent_add (struct hbfile_data
*data
, const gchar
*path
);
144 static void ui_mainwindow_scheduled_populate(GtkWidget
*widget
, gpointer user_data
);
145 void ui_mainwindow_scheduled_postall(GtkWidget
*widget
, gpointer user_data
);
147 void ui_mainwindow_recent_add (struct hbfile_data
*data
, const gchar
*path
);
149 static void ui_mainwindow_showprefs(gint page
);
151 extern gchar
*CYA_ACC_TYPE
[];
153 gchar
*CYA_CATSUBCAT
[] = {
160 static GtkActionEntry entries
[] = {
162 /* name, icon-name, label */
164 { "FileMenu" , NULL
, N_("_File"), NULL
, NULL
, NULL
},
165 { "ImportMenu" , NULL
, N_("_Import"), NULL
, NULL
, NULL
},
166 { "EditMenu" , NULL
, N_("_Edit"), NULL
, NULL
, NULL
},
167 { "ViewMenu" , NULL
, N_("_View"), NULL
, NULL
, NULL
},
168 { "ManageMenu" , NULL
, N_("_Manage"), NULL
, NULL
, NULL
},
169 { "TxnMenu" , NULL
, N_("_Transactions"), NULL
, NULL
, NULL
},
170 { "ReportMenu" , NULL
, N_("_Reports"), NULL
, NULL
, NULL
},
171 { "ToolsMenu" , NULL
, N_("_Tools"), NULL
, NULL
, NULL
},
172 { "PluginMenu" , NULL
, N_("_Plugins"), NULL
, NULL
, NULL
},
173 { "HelpMenu" , NULL
, N_("_Help"), NULL
, NULL
, NULL
},
175 // { "Import" , NULL, N_("Import") },
176 // { "Export" , NULL, N_("Export to") },
177 /* name, icon-name, label, accelerator, tooltip */
180 { "New" , ICONNAME_NEW
, N_("_New") , "<control>N", N_("Create a new file"), G_CALLBACK (ui_mainwindow_action_new
) },
181 { "Open" , ICONNAME_OPEN
, N_("_Open...") , "<control>O", N_("Open a file"), G_CALLBACK (ui_mainwindow_action_open
) },
182 { "Save" , ICONNAME_SAVE
, N_("_Save") , "<control>S", N_("Save the current file"), G_CALLBACK (ui_mainwindow_action_save
) },
183 { "SaveAs" , ICONNAME_SAVE_AS
, N_("Save _As...") , "<shift><control>S", N_("Save the current file with a different name"), G_CALLBACK (ui_mainwindow_action_saveas
) },
184 { "Revert" , ICONNAME_REVERT
, N_("Revert") , NULL
, N_("Revert to a saved version of this file"), G_CALLBACK (ui_mainwindow_action_revert
) },
186 { "Properties" , ICONNAME_PROPERTIES
, N_("Properties..."), NULL
, N_("Configure the file"), G_CALLBACK (ui_mainwindow_action_properties
) },
187 { "Close" , ICONNAME_CLOSE
, N_("_Close") , "<control>W", N_("Close the current file"), G_CALLBACK (ui_mainwindow_action_close
) },
188 { "Quit" , ICONNAME_QUIT
, N_("_Quit") , "<control>Q", N_("Quit HomeBank"), G_CALLBACK (ui_mainwindow_action_quit
) },
191 { "ImportQIF" , ICONNAME_HB_FILE_IMPORT
, N_("QIF file...") , NULL
, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import
) },
192 { "ImportOFX" , ICONNAME_HB_FILE_IMPORT
, N_("OFX/QFX file...") , NULL
, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import
) },
193 { "ImportCSV" , ICONNAME_HB_FILE_IMPORT
, N_("CSV file...") , NULL
, N_("Open the import assistant"), G_CALLBACK (ui_mainwindow_action_import
) },
195 { "ExportQIF" , ICONNAME_HB_FILE_EXPORT
, N_("Export QIF file...") , NULL
, N_("Export all account in a QIF file"), G_CALLBACK (ui_mainwindow_action_export
) },
198 { "Preferences", ICONNAME_PREFERENCES
, N_("Preferences..."), NULL
, N_("Configure HomeBank"), G_CALLBACK (ui_mainwindow_action_preferences
) },
201 { "Currency" , ICONNAME_HB_CURRENCY
, N_("Currencies...") , NULL
, N_("Configure the currencies"), G_CALLBACK (ui_mainwindow_action_defcurrency
) },
202 { "Account" , ICONNAME_HB_ACCOUNT
, N_("Acc_ounts...") , NULL
, N_("Configure the accounts"), G_CALLBACK (ui_mainwindow_action_defaccount
) },
203 { "Payee" , ICONNAME_HB_PAYEE
, N_("_Payees...") , NULL
, N_("Configure the payees"), G_CALLBACK (ui_mainwindow_action_defpayee
) },
204 { "Category" , ICONNAME_HB_CATEGORY
, N_("Categories...") , NULL
, N_("Configure the categories"), G_CALLBACK (ui_mainwindow_action_defcategory
) },
205 { "Archive" , ICONNAME_HB_ARCHIVE
, N_("Scheduled/Template...") , NULL
, N_("Configure the scheduled/template transactions"), G_CALLBACK (ui_mainwindow_action_defarchive
) },
206 { "Budget" , ICONNAME_HB_BUDGET
, N_("Budget...") , NULL
, N_("Configure the budget"), G_CALLBACK (ui_mainwindow_action_defbudget
) },
207 { "Assign" , ICONNAME_HB_ASSIGN
, N_("Assignments..."), NULL
, N_("Configure the automatic assignments"), G_CALLBACK (ui_mainwindow_action_defassign
) },
210 { "ShowOpe" , ICONNAME_HB_OPE_SHOW
, N_("Show...") , NULL
, N_("Shows selected account transactions"), G_CALLBACK (ui_mainwindow_action_showtransactions
) },
211 { "AddOpe" , ICONNAME_HB_OPE_ADD
, N_("Add...") , NULL
, N_("Add transactions"), G_CALLBACK (ui_mainwindow_action_addtransactions
) },
212 { "Scheduler" , NULL
, N_("Set scheduler...") , NULL
, N_("Configure the transaction scheduler"), G_CALLBACK (ui_mainwindow_action_properties
) },
213 { "AddScheduled", NULL
, N_("Post scheduled"), NULL
, N_("Post pending scheduled transactions"), G_CALLBACK (ui_mainwindow_action_checkscheduled
) },
216 { "RStatistics" , ICONNAME_HB_REP_STATS
, N_("_Statistics...") , NULL
, N_("Open the Statistics report"), G_CALLBACK (ui_mainwindow_action_statistic
) },
217 { "RTrendTime" , ICONNAME_HB_REP_TIME
, N_("_Trend Time...") , NULL
, N_("Open the Trend Time report"), G_CALLBACK (ui_mainwindow_action_trendtime
) },
218 { "RBudget" , ICONNAME_HB_REP_BUDGET
, N_("B_udget...") , NULL
, N_("Open the Budget report"), G_CALLBACK (ui_mainwindow_action_budget
) },
219 { "RBalance" , ICONNAME_HB_REP_BALANCE
, N_("Balance...") , NULL
, N_("Open the Balance report"), G_CALLBACK (ui_mainwindow_action_balance
) },
220 { "RVehiculeCost", ICONNAME_HB_REP_CAR
, N_("_Vehicle cost...") , NULL
, N_("Open the Vehicle cost report"), G_CALLBACK (ui_mainwindow_action_vehiclecost
) },
223 { "Welcome" , NULL
, N_("Show welcome dialog...") , NULL
, NULL
, G_CALLBACK (ui_mainwindow_action_help_welcome
) },
224 { "FileStats" , NULL
, N_("File statistics...") , NULL
, NULL
, G_CALLBACK (ui_mainwindow_action_file_statistics
) },
225 { "Anonymize" , NULL
, N_("Anonymize...") , NULL
, NULL
, G_CALLBACK (ui_mainwindow_action_anonymize
) },
228 { "PluginPreferences", "prf-plugins", N_("_Plugins..."), "<control>U", N_("Configure plugin preferences"), G_CALLBACK(ui_mainwindow_action_pluginprefs
) },
231 { "Contents" , ICONNAME_HELP
, N_("_Contents") , "F1", N_("Documentation about HomeBank"), G_CALLBACK (ui_mainwindow_action_help
) },
232 { "Online" , "lpi-help" , N_("Get Help Online...") , NULL
, N_("Connect to the LaunchPad website for online help"), G_CALLBACK (ui_mainwindow_action_help_online
) },
233 { "Translate" , "lpi-translate" , N_("Translate this Application..."), NULL
, N_("Connect to the LaunchPad website to help translate this application"), G_CALLBACK (ui_mainwindow_action_help_translate
) },
234 { "Problem" , "lpi-bug" , N_("Report a Problem...") , NULL
, N_("Connect to the LaunchPad website to help fix problems"), G_CALLBACK (ui_mainwindow_action_help_problem
) },
236 { "About" , ICONNAME_ABOUT
, N_("_About") , NULL
, N_("About HomeBank") ,G_CALLBACK (ui_mainwindow_action_about
) },
239 static guint n_entries
= G_N_ELEMENTS (entries
);
242 static GtkToggleActionEntry toggle_entries
[] = {
243 /* name , icon-name, label, accelerator, tooltip, callback, is_active */
244 { "Toolbar" , NULL
, N_("_Toolbar") , NULL
, NULL
, G_CALLBACK (ui_mainwindow_action_toggle_toolbar
), TRUE
},
245 { "Spending" , NULL
, N_("_Top spending") , NULL
, NULL
, G_CALLBACK (ui_mainwindow_action_toggle_topspending
), TRUE
},
246 { "Upcoming" , NULL
, N_("_Scheduled list") , NULL
, NULL
, G_CALLBACK (ui_mainwindow_action_toggle_upcoming
), TRUE
},
247 { "AsMinor" , NULL
, N_("Euro minor"), "<control>M", NULL
, G_CALLBACK (ui_mainwindow_action_toggle_minor
), FALSE
},
250 static guint n_toggle_entries
= G_N_ELEMENTS (toggle_entries
);
253 static const gchar
*ui_info
=
256 " <menubar name='MenuBar'>"
257 " <menu action='FileMenu'>"
258 " <menuitem action='New'/>"
259 " <menuitem action='Open'/>"
261 " <menuitem action='Save'/>"
262 " <menuitem action='SaveAs'/>"
263 " <menuitem action='Revert'/>"
265 " <menuitem action='Properties'/>"
267 " <menu action='ImportMenu'>"
268 " <menuitem action='ImportQIF'/>"
269 " <menuitem action='ImportOFX'/>"
270 " <menuitem action='ImportCSV'/>"
272 " <menuitem action='ExportQIF'/>"
274 // print to come here
276 " <menuitem action='Close'/>"
277 " <menuitem action='Quit'/>"
279 " <menu action='EditMenu'>"
280 " <menuitem action='Preferences'/>"
282 " <menu action='ViewMenu'>"
283 " <menuitem action='Toolbar'/>"
285 " <menuitem action='Spending'/>"
286 " <menuitem action='Upcoming'/>"
288 " <menuitem action='AsMinor'/>"
290 " <menu action='ManageMenu'>"
291 " <menuitem action='Account'/>"
292 " <menuitem action='Payee'/>"
293 " <menuitem action='Category'/>"
294 " <menuitem action='Archive'/>"
295 " <menuitem action='Budget'/>"
296 " <menuitem action='Assign'/>"
297 " <menuitem action='Currency'/>"
299 " <menu action='TxnMenu'>"
300 " <menuitem action='ShowOpe'/>"
301 " <menuitem action='AddOpe'/>"
303 " <menuitem action='Scheduler'/>"
304 " <menuitem action='AddScheduled'/>"
306 " <menu action='ReportMenu'>"
307 " <menuitem action='RStatistics'/>"
308 " <menuitem action='RTrendTime'/>"
309 " <menuitem action='RBalance'/>"
310 " <menuitem action='RBudget'/>"
311 " <menuitem action='RVehiculeCost'/>"
313 " <menu action='ToolsMenu'>"
314 " <menuitem action='Welcome'/>"
315 " <menuitem action='FileStats'/>"
317 " <menuitem action='Anonymize'/>"
319 " <menu action='PluginMenu'>"
321 " <menuitem action='PluginPreferences'/>"
324 " <menu action='HelpMenu'>"
325 " <menuitem action='Contents'/>"
327 " <menuitem action='Online'/>"
328 " <menuitem action='Translate'/>"
329 " <menuitem action='Problem'/>"
331 " <menuitem action='About'/>"
335 " <toolbar name='ToolBar'>"
336 " <toolitem action='New'/>"
337 // here Open + recent is coded
338 " <toolitem action='Save'/>"
340 " <toolitem action='Account'/>"
341 " <toolitem action='Payee'/>"
342 " <toolitem action='Category'/>"
343 " <toolitem action='Archive'/>"
344 " <toolitem action='Budget'/>"
345 " <toolitem action='Assign'/>"
346 " <toolitem action='Currency'/>"
348 " <toolitem action='ShowOpe'/>"
349 " <toolitem action='AddOpe'/>"
351 " <toolitem action='RStatistics'/>"
352 " <toolitem action='RTrendTime'/>"
353 " <toolitem action='RBalance'/>"
354 " <toolitem action='RBudget'/>"
355 " <toolitem action='RVehiculeCost'/>"
369 void ui_mainwindow_revert(GtkWidget
*widget
, gpointer user_data
)
371 //struct hbfile_data *data;
377 DB( g_print("\n[ui-mainwindow] revert\n") );
379 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
381 basename
= g_path_get_basename(GLOBALS
->xhb_filepath
);
382 title
= g_strdup_printf (
383 _("Revert unsaved changes to file '%s'?"), basename
);
386 _("- Changes made to the file will be permanently lost\n"
387 "- File will be reloaded from the last save (.xhb~)");
389 result
= ui_dialog_msg_confirm_alert(
390 GTK_WINDOW(GLOBALS
->mainwindow
),
399 if( result
== GTK_RESPONSE_OK
)
401 DB( g_print(" - should revert\n") );
403 hbfile_change_filepath(hb_util_filename_new_with_extension(GLOBALS
->xhb_filepath
, "xhb~"));
404 ui_mainwindow_open_internal(widget
, NULL
);
405 hbfile_change_filepath(hb_util_filename_new_with_extension(GLOBALS
->xhb_filepath
, "xhb"));
412 activate_url (GtkAboutDialog
*about
,
416 DB( g_print("activate url %s\n", link
) );
418 homebank_util_url_show (link
);
421 static void hbfile_about(void)
428 static const gchar
*artists
[] = {
433 static const gchar
*authors
[] = {
434 "Lead developer:\n" \
436 "\nContributors:\n" \
437 "Charles MCGARVEY (Plugin system, Perl support)\n" \
438 "Ga\xc3\xabtan LORIDANT (Maths formulas for charts)\n",
443 const gchar *documenters[] = {
449 static const gchar
*copyright
= "Copyright \xc2\xa9 1995-2016 - Maxime DOYEN";
453 version
= g_strdup_printf (PACKAGE_VERSION
"\n<small>Running against GTK+ %d.%d.%d</small>",
454 gtk_get_major_version (),
455 gtk_get_minor_version (),
456 gtk_get_micro_version ());
458 dialog
= gtk_about_dialog_new();
460 gtk_window_set_transient_for (GTK_WINDOW(dialog
), GTK_WINDOW(GLOBALS
->mainwindow
));
461 gtk_window_set_modal(GTK_WINDOW(dialog
), TRUE
);
463 gtk_about_dialog_set_program_name (GTK_ABOUT_DIALOG(dialog
), g_get_application_name ());
464 gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog
), version
);
465 gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog
), copyright
);
466 gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog
), _("Free, easy, personal accounting for everyone"));
467 gtk_about_dialog_set_license_type (GTK_ABOUT_DIALOG(dialog
), GTK_LICENSE_GPL_2_0
);
469 //gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(dialog), );
470 gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog
), "http://homebank.free.fr");
471 gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(dialog
), "Visit the HomeBank website");
473 gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(dialog
), "homebank");
475 pathfilename
= g_build_filename(homebank_app_get_images_dir(), "splash.png", NULL
);
476 pixbuf
= gdk_pixbuf_new_from_file(pathfilename
, NULL
);
477 g_free(pathfilename
);
481 gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog
), pixbuf
);
482 g_object_unref (pixbuf
);
485 gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(dialog
), authors
);
486 gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(dialog
), artists
);
487 //gtk_about_dialog_set_documenters(GTK_ABOUT_DIALOG(dialog), );
488 //gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(dialog), );
490 g_signal_connect (dialog
, "activate-link", G_CALLBACK (activate_url
), NULL
);
492 gtk_dialog_run (GTK_DIALOG (dialog
));
494 gtk_widget_destroy (dialog
);
501 /* hbfile action functions -------------------- */
502 static void ui_mainwindow_action_new(void)
504 GtkWidget
*widget
= GLOBALS
->mainwindow
;
506 if( ui_dialog_msg_savechanges(widget
,NULL
) == TRUE
)
508 //clear all, and init GLOBALS->xhb_filepath to default
509 ui_mainwindow_clear(widget
, GINT_TO_POINTER(TRUE
)); // GPOINTER_TO_INT(
510 ui_mainwindow_update(widget
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
+UF_REFRESHALL
));
512 ui_start_assistant();
513 ui_mainwindow_populate_accounts(GLOBALS
->mainwindow
, NULL
);
514 ui_mainwindow_scheduled_populate(GLOBALS
->mainwindow
, NULL
);
515 ui_mainwindow_populate_topspending(GLOBALS
->mainwindow
, NULL
);
519 static void ui_mainwindow_action_open(void)
521 ui_mainwindow_open(GLOBALS
->mainwindow
, NULL
);
524 static void ui_mainwindow_action_save(void)
526 ui_mainwindow_save(GLOBALS
->mainwindow
, GINT_TO_POINTER(FALSE
));
529 static void ui_mainwindow_action_saveas(void)
531 ui_mainwindow_save(GLOBALS
->mainwindow
, GINT_TO_POINTER(TRUE
));
534 static void ui_mainwindow_action_revert(void)
536 ui_mainwindow_revert(GLOBALS
->mainwindow
, NULL
);
539 static void ui_mainwindow_action_close(void)
541 GtkWidget
*widget
= GLOBALS
->mainwindow
;
543 if( ui_dialog_msg_savechanges(widget
,NULL
) == TRUE
)
545 //clear all, and init GLOBALS->xhb_filepath to default
546 ui_mainwindow_clear(widget
, GINT_TO_POINTER(TRUE
));
547 ui_mainwindow_update(widget
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
+UF_BALANCE
+UF_REFRESHALL
));
553 static void ui_mainwindow_action_quit(void)
557 //gtk_widget_destroy(GLOBALS->mainwindow);
559 g_signal_emit_by_name(GLOBALS
->mainwindow
, "delete-event", NULL
, &result
);
564 static void ui_mainwindow_action_file_statistics(void)
566 ui_dialog_file_statistics();
570 static void ui_mainwindow_action_pluginprefs(void)
572 ui_mainwindow_showprefs(PREF_PLUGINS
);
576 static void ui_mainwindow_action_properties(void)
578 create_defhbfile_dialog();
579 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
+UF_REFRESHALL
));
582 static void ui_mainwindow_action_anonymize(void)
588 title
= _("Are you sure you want to anonymize the file?");
591 _("Proceeding will anonymize any text, \n"
592 "like 'account x', 'payee y', 'memo z', ...");
594 result
= ui_dialog_msg_confirm_alert(
595 GTK_WINDOW(GLOBALS
->mainwindow
),
601 if( result
== GTK_RESPONSE_CANCEL
)
605 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
+UF_REFRESHALL
));
609 static void ui_mainwindow_action_defcurrency(void)
611 ui_cur_manage_dialog();
612 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
+UF_REFRESHALL
));
616 static void ui_mainwindow_action_defaccount(void)
618 ui_acc_manage_dialog();
620 //our global list has changed, so update the treeview
621 //todo: optimize this, should not call compute balance here
622 account_compute_balances ();
623 ui_mainwindow_populate_accounts(GLOBALS
->mainwindow
, NULL
);
625 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
+UF_BALANCE
));
628 static void ui_mainwindow_action_defpayee(void)
630 ui_pay_manage_dialog();
631 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
));
634 static void ui_mainwindow_action_defcategory(void)
636 ui_cat_manage_dialog();
637 //todo:why refresh upcoming here??
638 //ui_mainwindow_populate_upcoming(GLOBALS->mainwindow, NULL);
639 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
));
643 static void ui_mainwindow_defarchive(Archive
*arc
)
645 struct hbfile_data
*data
;
648 data
= g_object_get_data(G_OBJECT(GLOBALS
->mainwindow
), "inst_data");
650 // upcoming list have direct pointer to the arc (which may have changed)
651 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_upc
));
652 gtk_list_store_clear (GTK_LIST_STORE(model
));
654 ui_arc_manage_dialog(arc
);
656 ui_mainwindow_scheduled_populate(GLOBALS
->mainwindow
, NULL
);
658 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
));
662 static void ui_mainwindow_action_defarchive(void)
664 ui_mainwindow_defarchive(NULL
);
668 static void ui_mainwindow_action_defbudget(void)
670 ui_bud_manage_dialog();
671 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
));
675 static void ui_mainwindow_action_defassign(void)
678 ui_asg_manage_dialog();
680 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
));
684 static void ui_mainwindow_action_preferences(void)
686 ui_mainwindow_showprefs(PREF_GENERAL
);
689 static void ui_mainwindow_showprefs(gint page
)
691 struct hbfile_data
*data
= g_object_get_data(G_OBJECT(GLOBALS
->mainwindow
), "inst_data");
693 defpref_dialog_new(page
);
694 if(!PREFS
->euro_active
)
696 GtkToggleAction
*action
= (GtkToggleAction
*)gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ViewMenu/AsMinor");
698 gtk_toggle_action_set_active(action
, FALSE
);
699 ui_mainwindow_action_toggle_minor(action
);
701 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_VISUAL
+UF_REFRESHALL
));
706 static void ui_mainwindow_action_toggle_toolbar(GtkToggleAction
*action
)
708 //struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
710 PREFS
->wal_toolbar
= gtk_toggle_action_get_active(action
);
711 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_VISUAL
));
714 static void ui_mainwindow_action_toggle_upcoming(GtkToggleAction
*action
)
716 //struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
718 PREFS
->wal_upcoming
= gtk_toggle_action_get_active(action
);
719 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_VISUAL
));
722 static void ui_mainwindow_action_toggle_topspending(GtkToggleAction
*action
)
724 //struct hbfile_data *data = g_object_get_data(G_OBJECT(GLOBALS->mainwindow), "inst_data");
726 PREFS
->wal_spending
= gtk_toggle_action_get_active(action
);
727 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_VISUAL
));
730 static void ui_mainwindow_action_toggle_minor(GtkToggleAction
*action
)
732 struct hbfile_data
*data
= g_object_get_data(G_OBJECT(GLOBALS
->mainwindow
), "inst_data");
734 GLOBALS
->minor
= gtk_toggle_action_get_active(action
);
736 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_acc
));
737 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_upc
));
740 gtk_chart_show_minor(GTK_CHART(data
->RE_pie
), GLOBALS
->minor
);
741 hb_label_set_amount(GTK_LABEL(data
->TX_topamount
), data
->toptotal
, GLOBALS
->kcur
, GLOBALS
->minor
);
745 static void ui_mainwindow_action_showtransactions(void)
747 struct hbfile_data
*data
= g_object_get_data(G_OBJECT(GLOBALS
->mainwindow
), "inst_data");
753 if( data
->acc
->window
== NULL
)
755 window
= register_panel_window_new(data
->acc
->key
, data
->acc
);
756 register_panel_window_init(window
, NULL
);
760 if(GTK_IS_WINDOW(data
->acc
->window
))
761 gtk_window_present(data
->acc
->window
);
768 static void ui_mainwindow_action_addtransactions(void)
770 ui_mainwindow_addtransactions(GLOBALS
->mainwindow
, NULL
);
773 static void ui_mainwindow_action_checkscheduled(void)
775 ui_mainwindow_scheduled_postall(GLOBALS
->mainwindow
, GINT_TO_POINTER(TRUE
));
778 static void ui_mainwindow_action_statistic(void)
780 ui_repdist_window_new();
783 static void ui_mainwindow_action_trendtime(void)
785 struct hbfile_data
*data
= g_object_get_data(G_OBJECT(GLOBALS
->mainwindow
), "inst_data");
787 ui_reptime_window_new(data
->acc
!= NULL
? data
->acc
->key
: 0);
790 static void ui_mainwindow_action_budget(void)
792 repbudget_window_new();
795 static void ui_mainwindow_action_balance(void)
797 struct hbfile_data
*data
= g_object_get_data(G_OBJECT(GLOBALS
->mainwindow
), "inst_data");
799 repbalance_window_new(data
->acc
!= NULL
? data
->acc
->key
: 0);
802 static void ui_mainwindow_action_vehiclecost(void)
804 repcost_window_new();
807 static void ui_mainwindow_action_import(GtkAction
*action
)
810 gint filetype
= FILETYPE_UNKNOW
;
812 name
= gtk_action_get_name(action
);
814 if( g_str_has_suffix (name
, "QIF"))
815 filetype
= FILETYPE_QIF
;
817 if( g_str_has_suffix (name
, "OFX"))
818 filetype
= FILETYPE_OFX
;
820 if( g_str_has_suffix (name
, "CSV"))
821 filetype
= FILETYPE_CSV_HB
;
823 DB( g_print("action %s type=%d\n", name
, filetype
) );
825 ui_import_assistant_new(filetype
);
830 static void ui_mainwindow_action_about(void)
837 static void ui_mainwindow_action_export(void)
841 if( ui_file_chooser_qif(NULL
, &filename
) == TRUE
)
843 hb_export_qif_account_all(filename
);
848 static void ui_mainwindow_action_help(void)
852 link
= g_build_filename("file:///", homebank_app_get_help_dir(), HOMEBANK_URL_HELP
, NULL
);
853 homebank_util_url_show (link
);
859 //todo: move this to a ui-assist-welcome.c
861 static void ui_mainwindow_action_help_welcome1 (GtkButton
*button
, gpointer user_data
)
863 gtk_dialog_response (GTK_DIALOG(user_data
), 1);
866 static void ui_mainwindow_action_help_welcome2 (GtkButton
*button
, gpointer user_data
)
868 gtk_dialog_response (GTK_DIALOG(user_data
), 2);
871 static void ui_mainwindow_action_help_welcome3 (GtkButton
*button
, gpointer user_data
)
873 gtk_dialog_response (GTK_DIALOG(user_data
), 3);
876 static void ui_mainwindow_action_help_welcome4 (GtkButton
*button
, gpointer user_data
)
878 gtk_dialog_response (GTK_DIALOG(user_data
), 4);
881 static void ui_mainwindow_action_help_welcome5 (GtkButton
*button
, gpointer user_data
)
883 gtk_dialog_response (GTK_DIALOG(user_data
), 5);
886 void ui_mainwindow_action_help_welcome(void)
888 GtkWidget
*dialog
, *content_area
;
889 GtkWidget
*mainvbox
, *widget
, *label
;
891 dialog
= gtk_dialog_new_with_buttons (_("Welcome to HomeBank"),
892 GTK_WINDOW(GLOBALS
->mainwindow
),
898 content_area
= gtk_dialog_get_content_area(GTK_DIALOG (dialog
));
900 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
901 gtk_box_pack_start (GTK_BOX (content_area
), mainvbox
, FALSE
, FALSE
, 0);
902 gtk_container_set_border_width (GTK_CONTAINER(mainvbox
), SPACING_MEDIUM
);
904 label
= make_label (_("HomeBank"), 0, 0);
905 gimp_label_set_attributes(GTK_LABEL(label
), PANGO_ATTR_WEIGHT
, PANGO_WEIGHT_BOLD
, -1);
906 gtk_box_pack_start (GTK_BOX (mainvbox
), label
, FALSE
, FALSE
, 0);
908 label
= make_label (_("Free, easy, personal accounting for everyone"), 0, 0);
909 gtk_box_pack_start (GTK_BOX (mainvbox
), label
, FALSE
, FALSE
, 0);
911 widget
= gtk_separator_new(GTK_ORIENTATION_HORIZONTAL
);
912 gtk_box_pack_start (GTK_BOX (content_area
), widget
, FALSE
, FALSE
, 0);
914 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, SPACING_MEDIUM
);
915 gtk_box_pack_start (GTK_BOX (content_area
), mainvbox
, TRUE
, TRUE
, 0);
916 gtk_container_set_border_width (GTK_CONTAINER(mainvbox
), SPACING_MEDIUM
);
918 label
= make_label (_("What do you want to do:"), 0, 0);
919 gimp_label_set_attributes(GTK_LABEL(label
), PANGO_ATTR_WEIGHT
, PANGO_WEIGHT_BOLD
, -1);
920 gtk_box_pack_start (GTK_BOX (mainvbox
), label
, FALSE
, FALSE
, 0);
922 widget
= gtk_button_new_with_mnemonic(_("Read HomeBank _Manual"));
923 gtk_box_pack_start (GTK_BOX (mainvbox
), widget
, FALSE
, FALSE
, 0);
924 g_signal_connect (widget
, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome1
), dialog
);
926 widget
= gtk_button_new_with_mnemonic(_("Configure _preferences"));
927 gtk_box_pack_start (GTK_BOX (mainvbox
), widget
, FALSE
, FALSE
, 0);
928 g_signal_connect (widget
, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome2
), dialog
);
930 widget
= gtk_button_new_with_mnemonic(_("Create a _new file"));
931 gtk_box_pack_start (GTK_BOX (mainvbox
), widget
, FALSE
, FALSE
, 0);
932 g_signal_connect (widget
, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome3
), dialog
);
934 widget
= gtk_button_new_with_mnemonic(_("_Open an existing file"));
935 gtk_box_pack_start (GTK_BOX (mainvbox
), widget
, FALSE
, FALSE
, 0);
936 g_signal_connect (widget
, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome4
), dialog
);
938 widget
= gtk_button_new_with_mnemonic(_("Open the _example file"));
939 gtk_box_pack_start (GTK_BOX (mainvbox
), widget
, FALSE
, FALSE
, 0);
940 g_signal_connect (widget
, "clicked", G_CALLBACK (ui_mainwindow_action_help_welcome5
), dialog
);
942 //connect all our signals
943 g_signal_connect (dialog
, "destroy", G_CALLBACK (gtk_widget_destroyed
), &dialog
);
945 gtk_widget_show_all (dialog
);
948 gint result
= gtk_dialog_run (GTK_DIALOG (dialog
));
950 // cleanup and destroy
951 gtk_widget_destroy (dialog
);
953 // do appropriate action
957 ui_mainwindow_action_help();
960 ui_mainwindow_action_preferences();
963 ui_mainwindow_action_new();
966 ui_mainwindow_action_open();
969 hbfile_change_filepath(g_build_filename(homebank_app_get_datas_dir(), "example.xhb", NULL
));
970 ui_mainwindow_open_internal(GLOBALS
->mainwindow
, NULL
);
978 static void ui_mainwindow_action_help_online(void)
980 const gchar
*link
= HOMEBANK_URL_HELP_ONLINE
;
982 homebank_util_url_show (link
);
986 static void ui_mainwindow_action_help_translate(void)
988 const gchar
*link
= HOMEBANK_URL_HELP_TRANSLATE
;
990 homebank_util_url_show (link
);
994 static void ui_mainwindow_action_help_problem(void)
996 const gchar
*link
= HOMEBANK_URL_HELP_PROBLEM
;
998 homebank_util_url_show (link
);
1005 /* hbfile functions -------------------- */
1013 static void ui_mainwindow_selection(GtkTreeSelection
*treeselection
, gpointer user_data
)
1015 ui_mainwindow_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), GINT_TO_POINTER(UF_SENSITIVE
));
1019 static void ui_mainwindow_close_openbooks(void)
1023 DB( g_print("\n[ui-mainwindow] close openbooks\n") );
1025 lacc
= elt
= g_hash_table_get_values(GLOBALS
->h_acc
);
1028 Account
*item
= elt
->data
;
1032 gtk_widget_destroy(GTK_WIDGET(item
->window
));
1033 item
->window
= NULL
;
1036 elt
= g_list_next(elt
);
1047 void ui_mainwindow_clear(GtkWidget
*widget
, gpointer user_data
)
1049 struct hbfile_data
*data
;
1050 gboolean file_clear
= GPOINTER_TO_INT(user_data
);
1052 DB( g_print("\n[ui-mainwindow] clear\n") );
1054 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1056 // Close opened account window
1058 ui_mainwindow_close_openbooks();
1059 gtk_tree_store_clear(GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_acc
))));
1060 gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_upc
))));
1061 gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_top
))));
1063 hbfile_cleanup(file_clear
);
1064 hbfile_setup(file_clear
);
1070 ** add some transactions directly
1072 void ui_mainwindow_addtransactions(GtkWidget
*widget
, gpointer user_data
)
1074 struct hbfile_data
*data
;
1078 gint account
, count
;
1080 DB( g_print("\n[ui-mainwindow] add transactions\n") );
1082 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1084 /* init the transaction */
1085 date
= homebank_app_date_get_julian();
1086 //todo: maybe think about set a default account here
1088 if(data
->acc
!= NULL
)
1089 account
= data
->acc
->key
;
1091 window
= create_deftransaction_window(GTK_WINDOW(data
->window
), TRANSACTION_EDIT_ADD
, FALSE
);
1093 while(result
== GTK_RESPONSE_ADD
|| result
== GTK_RESPONSE_ADDKEEP
)
1097 /* fill in the transaction */
1098 if( result
== GTK_RESPONSE_ADD
)
1100 ope
= da_transaction_malloc();
1102 ope
->kacc
= account
;
1104 if( PREFS
->heritdate
== FALSE
) //fix: 318733
1105 ope
->date
= GLOBALS
->today
;
1108 // normally we can't be in addkeep without initialized ope with add
1110 deftransaction_set_transaction(window
, ope
);
1112 result
= gtk_dialog_run (GTK_DIALOG (window
));
1114 DB( g_print(" - dialog result is %d\n", result
) );
1116 if(result
== GTK_RESPONSE_ADD
|| result
== GTK_RESPONSE_ADDKEEP
|| result
== GTK_RESPONSE_ACCEPT
)
1118 deftransaction_get(window
, NULL
);
1119 transaction_add(ope
, NULL
, ope
->kacc
);
1121 DB( g_print(" - added 1 transaction to %d\n", ope
->kacc
) );
1123 ui_mainwindow_populate_accounts(GLOBALS
->mainwindow
, NULL
);
1126 //todo: still usefull ? store last date
1130 if( result
== GTK_RESPONSE_ADD
)
1132 da_transaction_free(ope
);
1139 deftransaction_dispose(window
, NULL
);
1140 gtk_widget_destroy (window
);
1142 /* todo optimize this */
1145 GLOBALS
->changes_count
+= count
;
1146 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
+UF_BALANCE
+UF_REFRESHALL
));
1156 static gint
tmptop_compare_func(struct tmptop
*tt1
, struct tmptop
*tt2
)
1158 return tt1
->value
> tt2
->value
? 1 : -1;
1162 static void ui_mainwindow_populate_topspending(GtkWidget
*widget
, gpointer user_data
)
1164 struct hbfile_data
*data
;
1165 GtkTreeModel
*model
;
1169 guint n_result
, i
, n_items
;
1171 gdouble total
, other
;
1174 #define MAX_TOPSPENDING 5
1176 DB( g_print("\n[ui-mainwindow] populate_topspending\n") );
1178 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1180 type
= radio_get_active(GTK_CONTAINER(data
->RA_type
));
1181 range
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_range
));
1183 DB( g_print(" - type=%d, range=%d\n", type
, range
) );
1184 DB( g_print(" - pref range=%d\n", PREFS
->date_range_wal
) );
1186 if(range
== FLT_RANGE_OTHER
)
1189 filter_preset_daterange_set(data
->filter
, range
, 0);
1192 n_result
= da_cat_get_max_key() + 1;
1195 DB( g_print(" - max key is %d\n", n_result
) );
1197 /* allocate some memory */
1198 garray
= g_array_sized_new(FALSE
, FALSE
, sizeof(struct tmptop
), n_result
);
1202 struct tmptop zero
= { .key
=0, .value
=0.0 };
1205 //DB( g_print(" - array length=%d\n", garray->len) );
1207 for(i
=0 ; i
<n_result
; i
++)
1209 g_array_append_vals(garray
, &zero
, 1);
1210 //g_array_insert_vals(garray, i, &zero, 1);
1212 //struct tmptop *tt = &g_array_index (garray, struct tmptop, i);
1213 //DB( g_print("%4d, %4d %f\n", i, tt->key, tt->value) );
1216 //DB( g_print("\n - end array length=%d\n", garray->len) );
1218 //todo: not ideal, has ot force to get_acc for each txn below
1219 txn_queue
= hbfile_transaction_get_partial(data
->filter
->mindate
, data
->filter
->maxdate
);
1221 /* compute the results */
1222 list
= g_queue_peek_head_link(txn_queue
);
1223 while (list
!= NULL
)
1225 Transaction
*ope
= list
->data
;
1227 //DB( g_print(" - eval txn: '%s', cat=%d ==> flt-test=%d\n", ope->wording, ope->kcat, filter_test(data->filter, ope)) );
1229 if( !(ope
->paymode
== PAYMODE_INTXFER
) )
1234 //todo: optimize here
1235 trn_amount
= ope
->amount
;
1236 acc
= da_acc_get(ope
->kacc
);
1238 trn_amount
= hb_amount_base(ope
->amount
, acc
->kcur
);
1240 if( ope
->flags
& OF_SPLIT
)
1242 guint nbsplit
= da_splits_count(ope
->splits
);
1244 struct tmptop
*item
;
1246 for(i
=0;i
<nbsplit
;i
++)
1248 split
= ope
->splits
[i
];
1249 pos
= category_report_id(split
->kcat
, type
);
1251 trn_amount
= hb_amount_base(split
->amount
, acc
->kcur
);
1252 //trn_amount = split->amount;
1253 //#1297054 if( trn_amount < 0 ) {
1254 item
= &g_array_index (garray
, struct tmptop
, pos
);
1256 item
->value
+= trn_amount
;
1257 //DB( g_print(" - stored %.2f to item %d\n", trn_amount, pos) );
1263 struct tmptop
*item
;
1265 pos
= category_report_id(ope
->kcat
, type
);
1267 //#1297054 if( trn_amount < 0 ) {
1268 item
= &g_array_index (garray
, struct tmptop
, pos
);
1270 item
->value
+= trn_amount
;
1271 //DB( g_print(" - stored %.2f to item %d\n", trn_amount, pos) );
1278 list
= g_list_next(list
);
1281 g_queue_free (txn_queue
);
1283 // we need to sort this and limit before
1284 g_array_sort(garray
, (GCompareFunc
)tmptop_compare_func
);
1286 n_items
= MIN(garray
->len
,MAX_TOPSPENDING
);
1288 for(i
=0 ; i
<garray
->len
; i
++)
1290 struct tmptop
*item
;
1292 item
= &g_array_index (garray
, struct tmptop
, i
);
1295 total
+= item
->value
;
1298 other
+= item
->value
;
1300 DB( g_print(" - %d : k='%d' v='%f' t='%f'\n", i
, item
->key
, item
->value
, total
) );
1305 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_top
));
1306 gtk_list_store_clear (GTK_LIST_STORE(model
));
1307 g_object_ref(model
); /* Make sure the model stays with us after the tree view unrefs it */
1308 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_top
), NULL
); /* Detach model from view */
1310 /* insert into the treeview */
1311 for(i
=0 ; i
<MIN(garray
->len
,MAX_TOPSPENDING
) ; i
++)
1315 struct tmptop
*item
;
1318 item
= &g_array_index (garray
, struct tmptop
, i
);
1320 if(!item
->value
) continue;
1322 value
= hb_amount_round(item
->value
, 2);
1323 entry
= da_cat_get(item
->key
);
1324 if(entry
== NULL
) continue;
1326 name
= entry
->key
== 0 ? _("(no category)") : da_cat_get_fullname(entry
);
1329 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
1330 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
1332 LST_TOPSPEND_KEY
, 0,
1333 LST_TOPSPEND_NAME
, name
,
1334 LST_TOPSPEND_AMOUNT
, value
,
1335 //LST_TOPSPEND_RATE, (gint)(((ABS(value)*100)/ABS(total)) + 0.5),
1343 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
1344 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
1345 LST_TOPSPEND_ID
, n_items
,
1346 LST_TOPSPEND_KEY
, 0,
1347 LST_TOPSPEND_NAME
, _("Other"),
1348 LST_TOPSPEND_AMOUNT
, other
,
1349 //LST_TOPSPEND_RATE, (gint)(((ABS(other)*100)/ABS(total)) + 0.5),
1353 /* Re-attach model to view */
1354 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_top
), model
);
1355 g_object_unref(model
);
1357 data
->toptotal
= total
;
1358 hb_label_set_amount(GTK_LABEL(data
->TX_topamount
), total
, GLOBALS
->kcur
, GLOBALS
->minor
);
1360 gtk_chart_set_color_scheme(GTK_CHART(data
->RE_pie
), PREFS
->report_color_scheme
);
1361 gtk_chart_set_currency(GTK_CHART(data
->RE_pie
), GLOBALS
->kcur
);
1362 gtk_chart_set_datas(GTK_CHART(data
->RE_pie
), model
, LST_TOPSPEND_AMOUNT
, NULL
, NULL
);
1363 //gtk_chart_show_legend(GTK_CHART(data->RE_pie), FALSE);
1365 /* update info range text */
1369 daterange
= filter_daterange_text_get(data
->filter
);
1370 gtk_widget_set_tooltip_markup(GTK_WIDGET(data
->CY_range
), daterange
);
1375 /* free our memory */
1376 g_array_free (garray
, TRUE
);
1381 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
1383 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
1385 ui_mainwindow_scheduled_get_selected_item(GtkTreeView
*treeview
)
1387 GtkTreeSelection
*treeselection
;
1388 GtkTreeModel
*model
;
1391 treeselection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview
));
1392 if( gtk_tree_selection_get_selected(treeselection
, &model
, &iter
) )
1396 gtk_tree_model_get(GTK_TREE_MODEL(model
), &iter
, LST_DSPUPC_DATAS
, &arc
, -1);
1404 static void ui_mainwindow_scheduled_onRowActivated (GtkTreeView
*treeview
,
1406 GtkTreeViewColumn
*col
,
1409 //struct hbfile_data *data;
1412 DB( g_print ("\n[ui-mainwindow] A scheduled row has been double-clicked!\n") );
1414 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(treeview, GTK_TYPE_WINDOW)), "inst_data");
1416 arc
= ui_mainwindow_scheduled_get_selected_item(treeview
);
1417 ui_mainwindow_defarchive(arc
);
1421 static void ui_mainwindow_scheduled_do_post(Archive
*arc
, gboolean doedit
, gpointer user_data
)
1423 struct hbfile_data
*data
= user_data
;
1428 window
= create_deftransaction_window(GTK_WINDOW(data
->window
), TRANSACTION_EDIT_ADD
, TRUE
);
1430 /* fill in the transaction */
1431 txn
= da_transaction_malloc();
1432 da_transaction_init_from_template(txn
, arc
);
1433 txn
->date
= scheduled_get_postdate(arc
, arc
->nextdate
);
1435 deftransaction_set_transaction(window
, txn
);
1437 result
= gtk_dialog_run (GTK_DIALOG (window
));
1439 DB( g_print(" - dialog result is %d\n", result
) );
1441 if(result
== GTK_RESPONSE_ADD
|| result
== GTK_RESPONSE_ACCEPT
)
1443 deftransaction_get(window
, NULL
);
1444 transaction_add(txn
, NULL
, txn
->kacc
);
1445 GLOBALS
->changes_count
++;
1447 scheduled_date_advance(arc
);
1449 DB( g_print(" - added 1 transaction to %d\n", txn
->kacc
) );
1452 da_transaction_free(txn
);
1454 deftransaction_dispose(window
, NULL
);
1455 gtk_widget_destroy (window
);
1460 static void ui_mainwindow_scheduled_editpost_cb(GtkWidget
*widget
, gpointer user_data
)
1462 struct hbfile_data
*data
= user_data
;
1464 Archive
*arc
= ui_mainwindow_scheduled_get_selected_item(GTK_TREE_VIEW(data
->LV_upc
));
1468 ui_mainwindow_scheduled_do_post(arc
, TRUE
, data
);
1469 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
|UF_REFRESHALL
));
1474 static void ui_mainwindow_scheduled_post_cb(GtkWidget
*widget
, gpointer user_data
)
1476 struct hbfile_data
*data
= user_data
;
1478 Archive
*arc
= ui_mainwindow_scheduled_get_selected_item(GTK_TREE_VIEW(data
->LV_upc
));
1482 if( scheduled_is_postable(arc
) )
1484 Transaction
*txn
= da_transaction_malloc ();
1486 da_transaction_init_from_template(txn
, arc
);
1487 txn
->date
= scheduled_get_postdate(arc
, arc
->nextdate
);
1488 transaction_add(txn
, NULL
, 0);
1490 GLOBALS
->changes_count
++;
1491 scheduled_date_advance(arc
);
1493 da_transaction_free (txn
);
1497 ui_mainwindow_scheduled_do_post(arc
, FALSE
, data
);
1500 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
|UF_REFRESHALL
));
1505 static void ui_mainwindow_scheduled_skip_cb(GtkWidget
*widget
, gpointer user_data
)
1507 struct hbfile_data
*data
= user_data
;
1509 Archive
*arc
= ui_mainwindow_scheduled_get_selected_item(GTK_TREE_VIEW(data
->LV_upc
));
1510 if( (arc
!= NULL
) && (arc
->flags
& OF_AUTO
) )
1512 GLOBALS
->changes_count
++;
1513 scheduled_date_advance(arc
);
1515 ui_mainwindow_scheduled_populate(GLOBALS
->mainwindow
, NULL
);
1516 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
));
1522 static void ui_mainwindow_scheduled_update(GtkWidget
*widget
, gpointer user_data
)
1524 struct hbfile_data
*data
;
1527 DB( g_print("\n[ui-mainwindow] scheduled update\n") );
1529 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1531 //filter = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_sched_filter));
1533 Archive
*arc
= ui_mainwindow_scheduled_get_selected_item(GTK_TREE_VIEW(data
->LV_upc
));
1537 DB( g_print("archive is %s\n", arc
->wording
) );
1539 gtk_widget_set_sensitive(GTK_WIDGET(data
->BT_sched_skip
), TRUE
);
1540 gtk_widget_set_sensitive(GTK_WIDGET(data
->BT_sched_post
), TRUE
);
1541 gtk_widget_set_sensitive(GTK_WIDGET(data
->BT_sched_editpost
), TRUE
);
1545 gtk_widget_set_sensitive(GTK_WIDGET(data
->BT_sched_skip
), FALSE
);
1546 gtk_widget_set_sensitive(GTK_WIDGET(data
->BT_sched_post
), FALSE
);
1547 gtk_widget_set_sensitive(GTK_WIDGET(data
->BT_sched_editpost
), FALSE
);
1554 static void ui_mainwindow_scheduled_selection_cb(GtkTreeSelection
*treeselection
, gpointer user_data
)
1558 ui_mainwindow_scheduled_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), GINT_TO_POINTER(UF_SENSITIVE
));
1564 ** called after load, importamiga, on demand
1566 void ui_mainwindow_scheduled_postall(GtkWidget
*widget
, gpointer user_data
)
1568 //struct hbfile_data *data;
1570 gint usermode
= GPOINTER_TO_INT(user_data
);
1572 DB( g_print("\n[ui-mainwindow] check scheduled\n") );
1574 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1576 count
= scheduled_post_all_pending();
1579 if(usermode
== TRUE
)
1586 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_REFRESHALL
));
1590 txt
= _("No transaction to add");
1592 txt
= _("transaction added: %d");
1594 ui_dialog_msg_infoerror(GTK_WINDOW(GLOBALS
->mainwindow
), GTK_MESSAGE_INFO
,
1595 _("Check scheduled transactions result"),
1603 static void ui_mainwindow_scheduled_populate(GtkWidget
*widget
, gpointer user_data
)
1605 struct hbfile_data
*data
;
1606 GtkTreeModel
*model
;
1613 guint32 maxpostdate
;
1617 DB( g_print("\n[ui-mainwindow] scheduled populate list\n") );
1619 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1621 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_upc
));
1622 gtk_list_store_clear (GTK_LIST_STORE(model
));
1624 homebank_app_date_get_julian();
1626 maxpostdate
= scheduled_date_get_post_max();
1628 date
= g_date_new_julian (maxpostdate
);
1629 g_date_strftime (buffer
, 256-1, PREFS
->date_format
, date
);
1632 gtk_label_set_text(GTK_LABEL(data
->LB_maxpostdate
), buffer
);
1635 list
= g_list_first(GLOBALS
->arc_list
);
1636 while (list
!= NULL
)
1638 Archive
*arc
= list
->data
;
1641 guint nbdays
, nblate
;
1643 if((arc
->flags
& OF_AUTO
) ) //&& arc->kacc > 0)
1646 nbdays
= arc
->nextdate
- maxpostdate
;
1647 nblate
= scheduled_get_latepost_count(arc
, GLOBALS
->today
);
1649 DB( g_print(" - append '%s' : %d\n", arc
->wording
, nbdays
) );
1651 if(arc
->flags
& OF_INCOME
)
1662 /* insert normal txn */
1663 acc
= da_acc_get(arc
->kacc
);
1666 totinc
+= hb_amount_base(inc
, acc
->kcur
);
1667 totexp
+= hb_amount_base(exp
, acc
->kcur
);
1669 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
1670 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
1671 LST_DSPUPC_DATAS
, arc
,
1672 LST_DSPUPC_ACCOUNT
, acc
,
1673 LST_DSPUPC_WORDING
, arc
->wording
,
1674 LST_DSPUPC_EXPENSE
, exp
,
1675 LST_DSPUPC_INCOME
, inc
,
1676 LST_DSPUPC_REMAINING
, nbdays
,
1677 LST_DSPUPC_NB_LATE
, nblate
,
1680 /* insert internal xfer txn : 1378836 */
1681 if(arc
->paymode
== PAYMODE_INTXFER
)
1683 acc
= da_acc_get(arc
->kxferacc
);
1686 totinc
+= hb_amount_base(-inc
, acc
->kcur
);
1687 totexp
+= hb_amount_base(-exp
, acc
->kcur
);
1689 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
1690 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
1691 LST_DSPUPC_DATAS
, arc
,
1692 LST_DSPUPC_ACCOUNT
, acc
,
1693 LST_DSPUPC_WORDING
, arc
->wording
,
1694 LST_DSPUPC_EXPENSE
, -inc
,
1695 LST_DSPUPC_INCOME
, -exp
,
1696 LST_DSPUPC_REMAINING
, nbdays
,
1697 LST_DSPUPC_NB_LATE
, nblate
,
1702 list
= g_list_next(list
);
1708 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
1709 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
1710 LST_DSPUPC_DATAS
, NULL
,
1711 LST_DSPUPC_ACCOUNT
, NULL
,
1712 LST_DSPUPC_WORDING
, _("Total"),
1713 LST_DSPUPC_EXPENSE
, totexp
,
1714 LST_DSPUPC_INCOME
, totinc
,
1719 ui_mainwindow_scheduled_update(widget
, NULL
);
1729 void ui_mainwindow_open(GtkWidget
*widget
, gpointer user_data
)
1731 //struct hbfile_data *data;
1732 gchar
*filename
= NULL
;
1734 DB( g_print("\n[ui-mainwindow] open\n") );
1736 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1738 if( ui_dialog_msg_savechanges(widget
,NULL
) == TRUE
)
1740 if(ui_file_chooser_xhb(GTK_FILE_CHOOSER_ACTION_OPEN
, &filename
) == TRUE
)
1742 hbfile_change_filepath(filename
);
1744 ui_mainwindow_open_internal(widget
, NULL
);
1752 * open the file stored in GLOBALS->xhb_filepath
1754 void ui_mainwindow_open_internal(GtkWidget
*widget
, gpointer user_data
)
1756 struct hbfile_data
*data
;
1759 DB( g_print("\n[ui-mainwindow] open internal\n") );
1761 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1763 DB( g_print(" - filename: '%s'\n", GLOBALS
->xhb_filepath
) );
1765 if( GLOBALS
->xhb_filepath
!= NULL
)
1767 ui_mainwindow_clear(GLOBALS
->mainwindow
, GINT_TO_POINTER(FALSE
));
1768 GLOBALS
->hbfile_is_new
= FALSE
;
1770 r
= homebank_load_xml(GLOBALS
->xhb_filepath
);
1773 DB( g_print(" - file loaded ok : rcode=%d\n", r
) );
1775 hbfile_file_hasbackup(GLOBALS
->xhb_filepath
);
1777 if(PREFS
->appendscheduled
)
1778 scheduled_post_all_pending();
1780 if(PREFS
->do_update_currency
)
1781 ui_cur_manage_dialog_update_currencies(GTK_WINDOW(GLOBALS
->mainwindow
));
1783 homebank_lastopenedfiles_save();
1785 //todo: delete this after computing done at xml read
1786 account_compute_balances();
1788 ui_mainwindow_recent_add(data
, GLOBALS
->xhb_filepath
);
1792 gchar
*msg
= _("Unknow error");
1797 msg
= _("I/O error for file '%s'.");
1799 case XML_FILE_ERROR
:
1800 msg
= _("The file '%s' is not a valid HomeBank file.");
1802 case XML_VERSION_ERROR
:
1803 msg
= _("The file '%s' was saved with a higher version of HomeBank\nand cannot be loaded by the current version.");
1807 ui_dialog_msg_infoerror(GTK_WINDOW(data
->window
), GTK_MESSAGE_ERROR
,
1810 GLOBALS
->xhb_filepath
1813 ui_mainwindow_clear(GLOBALS
->mainwindow
, GINT_TO_POINTER(TRUE
));
1817 ui_mainwindow_populate_accounts(GLOBALS
->mainwindow
, NULL
);
1818 ui_mainwindow_scheduled_populate(GLOBALS
->mainwindow
, NULL
);
1819 ui_mainwindow_populate_topspending(GLOBALS
->mainwindow
, NULL
);
1820 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
+UF_VISUAL
));
1829 void ui_mainwindow_save(GtkWidget
*widget
, gpointer user_data
)
1831 struct hbfile_data
*data
;
1832 gboolean saveas
= GPOINTER_TO_INT(user_data
);
1833 gchar
*filename
= NULL
;
1836 DB( g_print("\n[ui-mainwindow] save\n") );
1838 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1840 if( GLOBALS
->hbfile_is_new
== TRUE
)
1845 if(ui_file_chooser_xhb(GTK_FILE_CHOOSER_ACTION_SAVE
, &filename
) == TRUE
)
1847 DB( g_print(" + should save as '%s'\n", filename
) );
1848 homebank_file_ensure_xhb(filename
);
1849 homebank_backup_current_file();
1850 r
= homebank_save_xml(GLOBALS
->xhb_filepath
);
1851 GLOBALS
->hbfile_is_new
= FALSE
;
1858 DB( g_print(" + should quick save %s\n", GLOBALS
->xhb_filepath
) );
1859 homebank_file_ensure_xhb(NULL
);
1860 homebank_backup_current_file();
1861 r
= homebank_save_xml(GLOBALS
->xhb_filepath
);
1867 GLOBALS
->changes_count
= 0;
1868 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
+UF_VISUAL
));
1872 gchar
*msg
= _("I/O error for file '%s'.");
1874 ui_dialog_msg_infoerror(GTK_WINDOW(data
->window
), GTK_MESSAGE_ERROR
,
1877 GLOBALS
->xhb_filepath
1886 void ui_mainwindow_populate_accounts(GtkWidget
*widget
, gpointer user_data
)
1888 struct hbfile_data
*data
;
1889 GtkTreeModel
*model
;
1890 GtkTreeIter iter1
, child_iter
;
1894 gdouble gtbank
, gttoday
, gtfuture
;
1896 DB( g_print("\n[ui-mainwindow] populate accounts\n") );
1898 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1900 /* here we create a count and a list of every account pointer by type */
1902 GPtrArray
*typeacc
[ACC_TYPE_MAXVALUE
] = {0};
1903 lacc
= elt
= g_hash_table_get_values(GLOBALS
->h_acc
);
1908 if( !(acc
->flags
& (AF_CLOSED
|AF_NOSUMMARY
)) )
1910 DB( g_print(" - insert %d:%s\n", acc
->key
, acc
->name
) );
1912 if(typeacc
[acc
->type
] == NULL
)
1913 typeacc
[acc
->type
] = g_ptr_array_sized_new(da_acc_length ());
1915 g_ptr_array_add(typeacc
[acc
->type
], (gpointer
)acc
);
1917 elt
= g_list_next(elt
);
1921 gtbank
= gttoday
= gtfuture
= 0;
1923 DB( g_print(" - populate listview\n") );
1926 /* then populate the listview */
1927 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_acc
));
1928 gtk_tree_store_clear (GTK_TREE_STORE(model
));
1931 for(i
=0;i
<ACC_TYPE_MAXVALUE
;i
++)
1933 GPtrArray
*gpa
= typeacc
[i
];
1934 gdouble tbank
, ttoday
, tfuture
;
1939 //1: Header: Bank, Cash, ...
1940 DB( g_print(" - append type '%s'\n", CYA_ACC_TYPE
[i
]) );
1942 gtk_tree_store_append (GTK_TREE_STORE(model
), &iter1
, NULL
);
1943 gtk_tree_store_set (GTK_TREE_STORE(model
), &iter1
,
1944 LST_DSPACC_DATATYPE
, DSPACC_TYPE_HEADER
,
1945 LST_DSPACC_NAME
, _(CYA_ACC_TYPE
[i
]),
1948 tbank
= ttoday
= tfuture
= 0;
1950 //2: Accounts for real
1951 for(j
=0;j
<gpa
->len
;j
++)
1953 acc
= g_ptr_array_index(gpa
, j
);
1955 //tbank += acc->bal_bank;
1956 //ttoday += acc->bal_today;
1957 //tfuture += acc->bal_future;
1958 tbank
+= hb_amount_base(acc
->bal_bank
, acc
->kcur
);
1959 ttoday
+= hb_amount_base(acc
->bal_today
, acc
->kcur
);
1960 tfuture
+= hb_amount_base(acc
->bal_future
, acc
->kcur
);
1962 DB( g_print(" - insert '%s' :: %.2f %.2f %.2f\n", acc
->name
, acc
->bal_bank
, acc
->bal_today
, acc
->bal_future
) );
1964 gtk_tree_store_append (GTK_TREE_STORE(model
), &child_iter
, &iter1
);
1965 gtk_tree_store_set (GTK_TREE_STORE(model
), &child_iter
,
1966 LST_DSPACC_DATAS
, acc
,
1967 LST_DSPACC_DATATYPE
, DSPACC_TYPE_NORMAL
,
1968 LST_DSPACC_BANK
, acc
->bal_bank
,
1969 LST_DSPACC_TODAY
, acc
->bal_today
,
1970 LST_DSPACC_FUTURE
, acc
->bal_future
,
1976 DB( g_print(" - type totals :: %.2f %.2f %.2f\n", tbank
, ttoday
, tfuture
) );
1978 // insert the total line
1979 gtk_tree_store_append (GTK_TREE_STORE(model
), &child_iter
, &iter1
);
1980 gtk_tree_store_set (GTK_TREE_STORE(model
), &child_iter
,
1981 LST_DSPACC_DATATYPE
, DSPACC_TYPE_SUBTOTAL
,
1982 LST_DSPACC_NAME
, _("Total"),
1983 LST_DSPACC_BANK
, tbank
,
1984 LST_DSPACC_TODAY
, ttoday
,
1985 LST_DSPACC_FUTURE
, tfuture
,
1989 /* set balance to header to display when collasped */
1990 gtk_tree_store_set (GTK_TREE_STORE(model
), &iter1
,
1991 LST_DSPACC_BANK
, tbank
,
1992 LST_DSPACC_TODAY
, ttoday
,
1993 LST_DSPACC_FUTURE
, tfuture
,
1996 /* add to grand total */
1999 gtfuture
+= tfuture
;
2005 DB( g_print(" - grand totals :: %.2f %.2f %.2f\n", gtbank
, gttoday
, gtfuture
) );
2010 gtk_tree_store_append (GTK_TREE_STORE(model
), &iter1
, NULL
);
2011 gtk_tree_store_set (GTK_TREE_STORE(model
), &iter1
,
2012 LST_DSPACC_DATATYPE
, DSPACC_TYPE_SUBTOTAL
,
2013 LST_DSPACC_NAME
, _("Grand total"),
2014 LST_DSPACC_BANK
, gtbank
,
2015 LST_DSPACC_TODAY
, gttoday
,
2016 LST_DSPACC_FUTURE
, gtfuture
,
2021 gtk_tree_view_expand_all(GTK_TREE_VIEW(data
->LV_acc
));
2023 DB( g_print(" - free ressources\n") );
2026 /* free all temp stuff */
2027 for(i
=0;i
<ACC_TYPE_MAXVALUE
;i
++)
2029 GPtrArray
*gpa
= typeacc
[i
];
2032 g_ptr_array_free (gpa
, TRUE
);
2039 void ui_mainwindow_update(GtkWidget
*widget
, gpointer user_data
)
2041 struct hbfile_data
*data
;
2044 DB( g_print("\n[ui-mainwindow] refresh_display\n") );
2046 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
2047 //data = INST_DATA(widget);
2049 flags
= GPOINTER_TO_INT(user_data
);
2051 /* set window title */
2052 if(flags
& UF_TITLE
)
2057 DB( g_print(" + 1: wintitle %x\n", (gint
)data
->wintitle
) );
2059 basename
= g_path_get_basename(GLOBALS
->xhb_filepath
);
2061 DB( g_print(" global changes: %d\n", GLOBALS
->changes_count
) );
2063 g_free(data
->wintitle
);
2065 changed
= (GLOBALS
->changes_count
> 0) ? "*" : "";
2067 data
->wintitle
= g_strdup_printf("%s%s - %s - " PROGNAME
, changed
, basename
, GLOBALS
->owner
);
2069 gtk_window_set_title (GTK_WINDOW (gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), data
->wintitle
);
2074 /* update disabled things */
2075 if(flags
& UF_SENSITIVE
)
2077 GtkTreeSelection
*selection
;
2078 GtkTreeModel
*model
;
2081 gboolean active
,sensitive
;
2083 DB( g_print(" + 2: disabled, opelist count\n") );
2085 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_acc
));
2087 active
= gtk_tree_selection_get_selected(selection
, &model
, &iter
);
2093 path
= gtk_tree_model_get_path(model
, &iter
);
2094 depth
= gtk_tree_path_get_depth(path
);
2098 DB( g_print(" depth is %d\n", depth
) );
2100 gtk_tree_model_get(GTK_TREE_MODEL(model
), &iter
, LST_DSPACC_DATAS
, &acc
, -1);
2109 //ensure data->acc will not be null
2110 data
->acc
= da_acc_get(1);
2114 // no change: disable save
2115 DB( g_print(" changes %d - new %d\n", GLOBALS
->changes_count
, GLOBALS
->hbfile_is_new
) );
2118 sensitive
= (GLOBALS
->changes_count
!= 0 ) ? TRUE
: FALSE
;
2119 //gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/FileMenu/SaveAs"), sensitive);
2120 //if(sensitive == TRUE && GLOBALS->hbfile_is_new == TRUE) sensitive = FALSE;
2121 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/FileMenu/Save"), sensitive
);
2122 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/FileMenu/Revert"), GLOBALS
->xhb_hasbak
);
2126 sensitive
= GLOBALS
->define_off
== 0 ? TRUE
: FALSE
;
2128 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ManageMenu/Account"), sensitive
);
2129 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ManageMenu/Payee"), sensitive
);
2130 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ManageMenu/Category"), sensitive
);
2131 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ManageMenu/Budget"), sensitive
);
2132 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/EditMenu/Preferences"), sensitive
);
2134 // empty account list: disable Import, Archives, Edit, Filter, Add, Statistics, Overdrawn, Car Cost
2135 sensitive
= da_acc_length() > 0 ? TRUE
: FALSE
;
2137 //gtk_action_set_sensitive(gtk_ui_manager_get_action(data-data->manager, "/MenuBar/FileMenu/Import"), sensitive);
2139 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/FileMenu/Close"), sensitive
);
2140 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ManageMenu/Archive"), sensitive
);
2141 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/TxnMenu/AddOpe"), sensitive
);
2142 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/TxnMenu/ShowOpe"), sensitive
);
2143 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ReportMenu/RStatistics"), sensitive
);
2144 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ReportMenu/RTrendTime"), sensitive
);
2145 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ReportMenu/RBudget"), sensitive
);
2146 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ReportMenu/RBalance"), sensitive
);
2147 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ReportMenu/RVehiculeCost"), sensitive
);
2149 // empty category list: disable Budget
2150 sensitive
= da_cat_length() > 1 ? TRUE
: FALSE
;
2151 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ManageMenu/Budget"), sensitive
);
2153 //#1501129 no need to disable, P & C can be created from assign dialog
2154 //sensitive = ((da_cat_length() > 1) || (da_pay_length() > 1)) ? TRUE : FALSE;
2155 //gtk_action_set_sensitive(gtk_ui_manager_get_action(data->manager, "/MenuBar/ManageMenu/Assign"), sensitive);
2157 // empty archive list: disable scheduled check
2158 sensitive
= g_list_length(GLOBALS
->arc_list
) > 0 ? TRUE
: FALSE
;
2160 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/TxnMenu/AddScheduled"), sensitive
);
2162 // no active account: disable Edit, Over
2163 sensitive
= (active
== TRUE
) ? TRUE
: FALSE
;
2164 if(data
->acc
&& data
->acc
->window
!= NULL
)
2167 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/TxnMenu/ShowOpe"), sensitive
);
2171 /* update toolbar, list */
2172 if(flags
& UF_VISUAL
)
2174 DB( g_print(" + 8: visual\n") );
2176 if(PREFS
->toolbar_style
== 0)
2177 gtk_toolbar_unset_style(GTK_TOOLBAR(data
->toolbar
));
2179 gtk_toolbar_set_style(GTK_TOOLBAR(data
->toolbar
), PREFS
->toolbar_style
-1);
2181 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (data
->LV_acc
), PREFS
->grid_lines
);
2182 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_acc
));
2184 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (data
->LV_upc
), PREFS
->grid_lines
);
2185 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_upc
));
2187 DB( g_print(" - show toolbar=%d\n", PREFS
->wal_toolbar
) );
2188 if(PREFS
->wal_toolbar
)
2189 gtk_widget_show(GTK_WIDGET(data
->toolbar
));
2191 gtk_widget_hide(GTK_WIDGET(data
->toolbar
));
2194 DB( g_print(" - show top_spending=%d\n", PREFS
->wal_spending
) );
2196 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->CY_range
), PREFS
->date_range_wal
);
2198 if(PREFS
->wal_spending
)
2199 gtk_widget_show(GTK_WIDGET(data
->GR_top
));
2201 gtk_widget_hide(GTK_WIDGET(data
->GR_top
));
2205 DB( g_print(" - show upcoming=%d\n", PREFS
->wal_upcoming
) );
2206 if(PREFS
->wal_upcoming
)
2207 gtk_widget_show(GTK_WIDGET(data
->GR_upc
));
2209 gtk_widget_hide(GTK_WIDGET(data
->GR_upc
));
2211 DB( g_print(" minor %d\n", PREFS
->euro_active
) );
2212 gtk_action_set_visible(gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ViewMenu/AsMinor"), PREFS
->euro_active
);
2215 /* update balances */
2216 if(flags
& UF_BALANCE
)
2219 DB( g_print(" + 4: balances\n") );
2221 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_acc
));
2223 //minor = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_minor));
2226 hb-label_set_colvalue(GTK_LABEL(data->TX_balance[0]), data->bank, minor);
2227 hb-label_set_colvalue(GTK_LABEL(data->TX_balance[1]), data->today, minor);
2228 hb-label_set_colvalue(GTK_LABEL(data->TX_balance[2]), data->future, minor);
2232 if(flags
& UF_REFRESHALL
)
2234 DB( g_print(" + 8: refreshall\n") );
2236 ui_mainwindow_populate_accounts(GLOBALS
->mainwindow
, NULL
);
2237 ui_mainwindow_populate_topspending(GLOBALS
->mainwindow
, NULL
);
2238 ui_mainwindow_scheduled_populate(GLOBALS
->mainwindow
, NULL
);
2247 ui_mainwindow_onRowActivated (GtkTreeView
*treeview
,
2249 GtkTreeViewColumn
*col
,
2252 GtkTreeModel
*model
;
2255 DB( g_print ("\n[ui-mainwindow] A row has been double-clicked!\n") );
2257 model
= gtk_tree_view_get_model(treeview
);
2259 if (gtk_tree_model_get_iter(model
, &iter
, path
))
2263 gtk_tree_model_get(model
, &iter
, LST_DSPACC_DATAS
, &acc
, -1);
2268 DB( g_print ("Double-clicked row contains name %s\n", acc
->name
) );
2270 ui_mainwindow_action_showtransactions();
2280 static gboolean
ui_mainwindow_dispose(GtkWidget
*widget
, GdkEvent
*event
, gpointer user_data
)
2282 struct hbfile_data
*data
= user_data
;
2283 struct WinGeometry
*wg
;
2284 gboolean retval
= FALSE
;
2286 GValue widget_value
= G_VALUE_INIT
;
2287 ext_hook("main_window_disposal", EXT_OBJECT(&widget_value
, widget
), NULL
);
2289 DB( g_print("\n[ui-mainwindow] dispose\n") );
2291 //store position and size
2292 wg
= &PREFS
->wal_wg
;
2293 gtk_window_get_position(GTK_WINDOW(widget
), &wg
->l
, &wg
->t
);
2294 gtk_window_get_size(GTK_WINDOW(widget
), &wg
->w
, &wg
->h
);
2295 GdkWindow
*gdk_window
= gtk_widget_get_window(GTK_WIDGET(widget
));
2296 GdkWindowState state
= gdk_window_get_state(gdk_window
);
2297 wg
->s
= (state
& GDK_WINDOW_STATE_MAXIMIZED
) ? 1 : 0;
2299 DB( g_print(" window: l=%d, t=%d, w=%d, h=%d s=%d, state=%d\n", wg
->l
, wg
->t
, wg
->w
, wg
->h
, wg
->s
, state
& GDK_WINDOW_STATE_MAXIMIZED
) );
2301 PREFS
->wal_vpaned
= gtk_paned_get_position(GTK_PANED(data
->vpaned
));
2302 PREFS
->wal_hpaned
= gtk_paned_get_position(GTK_PANED(data
->hpaned
));
2304 DB( g_print(" - vpaned=%d hpaned=%d\n", PREFS
->wal_vpaned
, PREFS
->wal_hpaned
) );
2307 if(ui_dialog_msg_savechanges(widget
, NULL
) == FALSE
)
2313 DB( g_print(" free wintitle %x\n", (gint
)data
->wintitle
) );
2315 gtk_widget_destroy(data
->LV_top
);
2317 g_free(data
->wintitle
);
2318 da_filter_free(data
->filter
);
2325 //delete-event TRUE abort/FALSE destroy
2330 static void ui_mainwindow_recent_chooser_item_activated_cb (GtkRecentChooser
*chooser
, struct hbfile_data
*data
)
2333 GError
*error
= NULL
;
2335 uri
= gtk_recent_chooser_get_current_uri (chooser
);
2337 path
= g_filename_from_uri (uri
, NULL
, NULL
);
2340 g_warning ("Could not convert uri \"%s\" to a local path: %s", uri
, error
->message
);
2341 g_error_free (error
);
2345 if( ui_dialog_msg_savechanges(data
->window
, NULL
) == TRUE
)
2352 gpw_recent_remove (gpw, path);
2356 hbfile_change_filepath(path
);
2357 ui_mainwindow_open_internal(data
->window
, NULL
);
2367 static void ui_mainwindow_window_screen_changed_cb (GtkWidget
*widget
,
2368 GdkScreen
*old_screen
,
2369 struct hbfile_data
*data
)
2372 DB( g_print("\n[ui-mainwindow] screen_changed_cb\n") );
2375 data
->recent_manager
= gtk_recent_manager_get_default ();
2377 gtk_menu_detach (GTK_MENU (data
->recent_menu
));
2378 g_object_unref (G_OBJECT (data
->recent_menu
));
2380 data
->recent_menu
= ui_mainwindow_create_recent_chooser_menu (data
->recent_manager
);
2382 g_signal_connect (data
->recent_menu
,
2384 G_CALLBACK (ui_mainwindow_recent_chooser_item_activated_cb
),
2387 //menu_item = gtk_ui_manager_get_widget (data->manager, "/MenuBar/FileMenu/OpenRecent");
2388 //gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), data->recent_menu);
2392 void ui_mainwindow_recent_add (struct hbfile_data
*data
, const gchar
*path
)
2394 GtkRecentData
*recent_data
;
2396 GError
*error
= NULL
;
2398 DB( g_print("\n[ui-mainwindow] recent_add\n") );
2400 DB( g_print(" - file has .xhb suffix = %d\n", g_str_has_suffix (path
, ".xhb") ) );
2402 if( g_str_has_suffix (path
, ".xhb") == FALSE
) //ignore reverted file
2405 uri
= g_filename_to_uri (path
, NULL
, &error
);
2408 g_warning ("Could not convert uri \"%s\" to a local path: %s", uri
, error
->message
);
2409 g_error_free (error
);
2413 recent_data
= g_slice_new (GtkRecentData
);
2415 recent_data
->display_name
= NULL
;
2416 recent_data
->description
= NULL
;
2417 recent_data
->mime_type
= "application/x-homebank";
2418 recent_data
->app_name
= (gchar
*) g_get_application_name ();
2419 recent_data
->app_exec
= g_strjoin (" ", g_get_prgname (), "%u", NULL
);
2420 recent_data
->groups
= NULL
;
2421 recent_data
->is_private
= FALSE
;
2423 if (!gtk_recent_manager_add_full (data
->recent_manager
,
2427 g_warning ("Unable to add '%s' to the list of recently used documents", uri
);
2431 g_free (recent_data
->app_exec
);
2432 g_slice_free (GtkRecentData
, recent_data
);
2445 static GtkTargetEntry drop_types
[] =
2447 {"text/uri-list", 0, TARGET_URI_LIST
}
2450 static void ui_mainwindow_drag_data_received (GtkWidget
*widget
,
2451 GdkDragContext
*context
,
2453 GtkSelectionData
*selection_data
,
2454 guint info
, guint time
, GtkWindow
*window
)
2456 gchar
**uris
, **str
;
2458 gint filetype
, slen
;
2460 if (info
!= TARGET_URI_LIST
)
2463 DB( g_print("\n[ui-mainwindow] drag_data_received\n") );
2465 /* On MS-Windows, it looks like `selection_data->data' is not NULL terminated. */
2466 slen
= gtk_selection_data_get_length(selection_data
);
2467 newseldata
= g_new (gchar
, slen
+ 1);
2468 memcpy (newseldata
, gtk_selection_data_get_data(selection_data
), slen
);
2469 newseldata
[slen
] = 0;
2471 uris
= g_uri_list_extract_uris (newseldata
);
2474 //for (str = uris; *str; str++)
2477 GError
*error
= NULL
;
2478 gchar
*path
= g_filename_from_uri (*str
, NULL
, &error
);
2482 filetype
= homebank_alienfile_recognize(path
);
2484 DB( g_print(" - dragged %s, type is %d\n", path
, filetype
) );
2486 if( filetype
== FILETYPE_HOMEBANK
)
2488 hbfile_change_filepath(g_strdup(path
));
2489 ui_mainwindow_open_internal(GTK_WIDGET(window
), NULL
);
2493 //todo: future here to implement import for other filetype
2495 ui_dialog_msg_infoerror(GTK_WINDOW(window
), GTK_MESSAGE_ERROR
,
2497 _("The file %s is not a valid HomeBank file."),
2507 g_warning ("Could not convert uri to local path: %s", error
->message
);
2509 g_error_free (error
);
2519 static GtkWidget
*ui_mainwindow_create_recent_chooser_menu (GtkRecentManager
*manager
)
2521 GtkWidget
*toolbar_recent_menu
;
2522 GtkRecentFilter
*filter
;
2524 toolbar_recent_menu
= gtk_recent_chooser_menu_new_for_manager (manager
);
2526 gtk_recent_chooser_set_local_only (GTK_RECENT_CHOOSER (toolbar_recent_menu
),
2528 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (toolbar_recent_menu
),
2529 GTK_RECENT_SORT_MRU
);
2530 //todo: add a user pref for this
2531 gtk_recent_chooser_set_limit(GTK_RECENT_CHOOSER (toolbar_recent_menu
),
2535 //gtk_recent_chooser_set_show_icons (GTK_RECENT_CHOOSER (toolbar_recent_menu), FALSE);
2537 //gtk_recent_chooser_menu_set_show_numbers (GTK_RECENT_CHOOSER_MENU (toolbar_recent_menu), TRUE);
2539 filter
= gtk_recent_filter_new ();
2540 //gtk_recent_filter_add_application (filter, g_get_application_name());
2541 gtk_recent_filter_add_pattern (filter
, "*.[Xx][Hh][Bb]");
2542 gtk_recent_chooser_set_filter (GTK_RECENT_CHOOSER (toolbar_recent_menu
), filter
);
2544 return toolbar_recent_menu
;
2548 static void ui_mainwindow_create_menu_bar_and_toolbar(struct hbfile_data
*data
, GtkWidget
*mainvbox
)
2550 GtkUIManager
*manager
;
2551 GtkActionGroup
*action_group
;
2553 GError
*error
= NULL
;
2555 manager
= gtk_ui_manager_new ();
2556 data
->manager
= manager
;
2558 gtk_window_add_accel_group (GTK_WINDOW (data
->window
),
2559 gtk_ui_manager_get_accel_group(manager
));
2561 action_group
= gtk_action_group_new ("MainWindow");
2562 gtk_action_group_set_translation_domain(action_group
, GETTEXT_PACKAGE
);
2564 gtk_action_group_add_actions (action_group
,
2569 gtk_action_group_add_toggle_actions (action_group
,
2574 gtk_ui_manager_insert_action_group (data
->manager
, action_group
, 0);
2575 g_object_unref (action_group
);
2576 data
->actions
= action_group
;
2578 /* set short labels to use in the toolbar */
2579 action
= gtk_action_group_get_action(action_group
, "Open");
2580 g_object_set(action
, "short_label", _("Open"), NULL
);
2582 //action = gtk_action_group_get_action(action_group, "Save");
2583 //g_object_set(action, "is_important", TRUE, NULL);
2585 action
= gtk_action_group_get_action(action_group
, "Account");
2586 g_object_set(action
, "short_label", _("Account"), NULL
);
2588 action
= gtk_action_group_get_action(action_group
, "Payee");
2589 g_object_set(action
, "short_label", _("Payee"), NULL
);
2591 action
= gtk_action_group_get_action(action_group
, "Category");
2592 g_object_set(action
, "short_label", _("Category"), NULL
);
2594 action
= gtk_action_group_get_action(action_group
, "Archive");
2595 //TRANSLATORS: an archive is stored transaction buffers (kind of bookmark to prefill manual insertion)
2596 g_object_set(action
, "short_label", _("Archive"), NULL
);
2598 action
= gtk_action_group_get_action(action_group
, "Budget");
2599 g_object_set(action
, "short_label", _("Budget"), NULL
);
2601 action
= gtk_action_group_get_action(action_group
, "ShowOpe");
2602 g_object_set(action
, "short_label", _("Show"), NULL
);
2604 action
= gtk_action_group_get_action(action_group
, "AddOpe");
2605 g_object_set(action
, "is_important", TRUE
, "short_label", _("Add"), NULL
);
2607 action
= gtk_action_group_get_action(action_group
, "RStatistics");
2608 g_object_set(action
, "short_label", _("Statistics"), NULL
);
2610 action
= gtk_action_group_get_action(action_group
, "RBudget");
2611 g_object_set(action
, "short_label", _("Budget"), NULL
);
2613 action
= gtk_action_group_get_action(action_group
, "RBalance");
2614 g_object_set(action
, "short_label", _("Balance"), NULL
);
2616 action
= gtk_action_group_get_action(action_group
, "RVehiculeCost");
2617 g_object_set(action
, "short_label", _("Vehicle cost"), NULL
);
2619 /* now load the UI definition */
2620 gtk_ui_manager_add_ui_from_string (data
->manager
, ui_info
, -1, &error
);
2623 g_message ("Building menus failed: %s", error
->message
);
2624 g_error_free (error
);
2627 //todo: this generate a warning
2628 data
->menubar
= gtk_ui_manager_get_widget (manager
, "/MenuBar");
2629 gtk_box_pack_start (GTK_BOX (mainvbox
),
2635 data
->toolbar
= gtk_ui_manager_get_widget (manager
, "/ToolBar");
2636 gtk_box_pack_start (GTK_BOX (mainvbox
),
2642 /* recent files menu */
2644 data
->recent_manager
= gtk_recent_manager_get_default ();
2646 data
->recent_menu
= ui_mainwindow_create_recent_chooser_menu (data
->recent_manager
);
2648 g_signal_connect (data
->recent_menu
,
2650 G_CALLBACK (ui_mainwindow_recent_chooser_item_activated_cb
),
2654 widget = gtk_ui_manager_get_widget (data->manager, "/MenuBar/FileMenu/OpenRecent");
2655 gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), data->recent_menu);
2659 /* add the custom Open button to the toolbar */
2660 GtkWidget
*image
= gtk_image_new_from_icon_name (ICONNAME_OPEN
, GTK_ICON_SIZE_BUTTON
);
2662 GtkToolItem
*open_button
= gtk_menu_tool_button_new(image
, _("_Open"));
2663 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (open_button
), data
->recent_menu
);
2665 gtk_tool_item_set_tooltip_text (open_button
, _("Open a file"));
2666 gtk_menu_tool_button_set_arrow_tooltip_text (GTK_MENU_TOOL_BUTTON (open_button
), _("Open a recently used file"));
2668 action
= gtk_action_group_get_action (data
->actions
, "Open");
2669 g_object_set (action
, "short_label", _("Open"), NULL
);
2670 //gtk_action_connect_proxy (action, GTK_WIDGET (open_button));
2671 gtk_activatable_set_related_action (GTK_ACTIVATABLE (open_button
), action
);
2673 gtk_toolbar_insert (GTK_TOOLBAR (data
->toolbar
), open_button
, 1);
2678 static GtkWidget
*ui_mainwindow_create_youraccounts(struct hbfile_data
*data
)
2680 GtkWidget
*mainvbox
, *label
, *widget
, *sw
;
2682 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
2684 label
= make_label_group(_("Your accounts"));
2685 gtk_widget_set_margin_top(GTK_WIDGET(label
), SPACING_SMALL
/2);
2686 gtk_widget_set_margin_bottom(GTK_WIDGET(label
), SPACING_SMALL
/2);
2687 gtk_widget_set_margin_start(GTK_WIDGET(label
), SPACING_SMALL
);
2688 gtk_widget_set_margin_end(GTK_WIDGET(label
), SPACING_SMALL
);
2689 gtk_box_pack_start (GTK_BOX (mainvbox
), label
, FALSE
, FALSE
, 0);
2691 sw
= gtk_scrolled_window_new (NULL
, NULL
);
2692 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw
), GTK_SHADOW_ETCHED_IN
);
2693 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
2694 //gtk_widget_set_margin_top(GTK_WIDGET(sw), 0);
2695 gtk_widget_set_margin_bottom(GTK_WIDGET(sw
), SPACING_SMALL
);
2696 gtk_widget_set_margin_start(GTK_WIDGET(sw
), 2*SPACING_SMALL
);
2697 gtk_widget_set_margin_end(GTK_WIDGET(sw
), SPACING_SMALL
);
2698 gtk_box_pack_start (GTK_BOX (mainvbox
), sw
, TRUE
, TRUE
, 0);
2700 widget
= (GtkWidget
*)create_list_account();
2701 data
->LV_acc
= widget
;
2702 gtk_container_add (GTK_CONTAINER (sw
), widget
);
2708 static GtkWidget
*ui_mainwindow_create_topspending(struct hbfile_data
*data
)
2710 GtkWidget
*mainvbox
, *hbox
, *vbox
;
2711 GtkWidget
*label
, *widget
;
2713 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
2714 data
->GR_top
= mainvbox
;
2716 label
= make_label_group(_("Where your money goes"));
2717 gtk_widget_set_margin_top(GTK_WIDGET(label
), SPACING_SMALL
/2);
2718 gtk_widget_set_margin_bottom(GTK_WIDGET(label
), SPACING_SMALL
/2);
2719 gtk_widget_set_margin_start(GTK_WIDGET(label
), SPACING_SMALL
);
2720 gtk_widget_set_margin_end(GTK_WIDGET(label
), SPACING_SMALL
);
2721 gtk_box_pack_start (GTK_BOX (mainvbox
), label
, FALSE
, FALSE
, 0);
2724 vbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, SPACING_SMALL
);
2725 //gtk_widget_set_margin_top(GTK_WIDGET(vbox), 0);
2726 gtk_widget_set_margin_bottom(GTK_WIDGET(vbox
), SPACING_SMALL
);
2727 gtk_widget_set_margin_start(GTK_WIDGET(vbox
), 2*SPACING_SMALL
);
2728 gtk_widget_set_margin_end(GTK_WIDGET(vbox
), SPACING_SMALL
);
2729 gtk_box_pack_start (GTK_BOX (mainvbox
), vbox
, TRUE
, TRUE
, 0);
2731 /* total + date range */
2732 hbox
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, SPACING_SMALL
);
2733 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
2735 label
= make_label(_("Top spending"), 0.0, 0.5);
2736 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
2738 label
= make_label(NULL
, 0.0, 0.5);
2739 data
->TX_topamount
= label
;
2740 gtk_box_pack_start (GTK_BOX (hbox
), label
, TRUE
, TRUE
, 0);
2742 data
->CY_range
= make_daterange(label
, FALSE
);
2743 gtk_box_pack_end (GTK_BOX (hbox
), data
->CY_range
, FALSE
, FALSE
, 0);
2745 widget
= make_radio(CYA_CATSUBCAT
, TRUE
, GTK_ORIENTATION_HORIZONTAL
);
2746 data
->RA_type
= widget
;
2747 gtk_box_pack_end (GTK_BOX (hbox
), widget
, FALSE
, FALSE
, 0);
2749 /* pie + listview */
2750 hbox
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, 0);
2751 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, TRUE
, TRUE
, 0);
2753 widget
= gtk_chart_new(CHART_TYPE_PIE
);
2754 data
->RE_pie
= widget
;
2755 gtk_chart_set_minor_prefs(GTK_CHART(widget
), PREFS
->euro_value
, PREFS
->minor_cur
.symbol
);
2756 gtk_box_pack_start (GTK_BOX (hbox
), widget
, TRUE
, TRUE
, 0);
2759 sw = gtk_scrolled_window_new (NULL, NULL);
2760 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
2761 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2762 gtk_box_pack_start (GTK_BOX (hbox), sw, FALSE, FALSE, 0);
2765 widget
= (GtkWidget
*)create_list_topspending();
2766 data
->LV_top
= widget
;
2768 gtk_chart_show_legend(GTK_CHART(data
->RE_pie
), TRUE
, TRUE
);
2770 // gtk_container_add (GTK_CONTAINER (sw), widget);
2776 static GtkWidget
*ui_mainwindow_scheduled_create(struct hbfile_data
*data
)
2778 GtkWidget
*mainvbox
, *hbox
, *vbox
, *bbox
, *sw
, *tbar
;
2779 GtkWidget
*label
, *widget
;
2780 GtkToolItem
*toolitem
;
2782 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
2783 data
->GR_upc
= mainvbox
;
2785 hbox
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, SPACING_SMALL
);
2786 gtk_box_pack_start (GTK_BOX (mainvbox
), hbox
, FALSE
, FALSE
, 0);
2788 label
= make_label_group(_("Scheduled transactions"));
2789 gtk_widget_set_margin_top(GTK_WIDGET(label
), SPACING_SMALL
/2);
2790 gtk_widget_set_margin_bottom(GTK_WIDGET(label
), SPACING_SMALL
/2);
2791 gtk_widget_set_margin_start(GTK_WIDGET(label
), SPACING_SMALL
);
2792 gtk_widget_set_margin_end(GTK_WIDGET(label
), SPACING_SMALL
);
2793 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
2795 label
= make_label(_("maximum post date"), 0.0, 0.7);
2796 gimp_label_set_attributes (GTK_LABEL (label
), PANGO_ATTR_SCALE
, PANGO_SCALE_SMALL
, -1);
2797 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
2799 label
= make_label(NULL
, 0.0, 0.7);
2800 data
->LB_maxpostdate
= label
;
2801 gimp_label_set_attributes (GTK_LABEL (label
), PANGO_ATTR_SCALE
, PANGO_SCALE_SMALL
, -1);
2802 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
2804 vbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
2805 //gtk_widget_set_margin_top(GTK_WIDGET(vbox), 0);
2806 gtk_widget_set_margin_bottom(GTK_WIDGET(vbox
), SPACING_SMALL
);
2807 gtk_widget_set_margin_start(GTK_WIDGET(vbox
), 2*SPACING_SMALL
);
2808 gtk_widget_set_margin_end(GTK_WIDGET(vbox
), SPACING_SMALL
);
2809 gtk_box_pack_start (GTK_BOX (mainvbox
), vbox
, TRUE
, TRUE
, 0);
2811 sw
= gtk_scrolled_window_new (NULL
, NULL
);
2812 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw
), GTK_SHADOW_ETCHED_IN
);
2813 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
2814 gtk_box_pack_start (GTK_BOX (vbox
), sw
, TRUE
, TRUE
, 0);
2816 widget
= (GtkWidget
*)create_list_upcoming();
2817 data
->LV_upc
= widget
;
2818 gtk_container_add (GTK_CONTAINER (sw
), widget
);
2820 tbar
= gtk_toolbar_new();
2821 gtk_toolbar_set_icon_size (GTK_TOOLBAR(tbar
), GTK_ICON_SIZE_MENU
);
2822 gtk_toolbar_set_style(GTK_TOOLBAR(tbar
), GTK_TOOLBAR_ICONS
);
2823 gtk_style_context_add_class (gtk_widget_get_style_context (tbar
), GTK_STYLE_CLASS_INLINE_TOOLBAR
);
2824 gtk_box_pack_start (GTK_BOX (vbox
), tbar
, FALSE
, FALSE
, 0);
2826 bbox
= gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL
);
2827 toolitem
= gtk_tool_item_new();
2828 gtk_container_add (GTK_CONTAINER(toolitem
), bbox
);
2829 gtk_toolbar_insert(GTK_TOOLBAR(tbar
), GTK_TOOL_ITEM(toolitem
), -1);
2831 widget
= gtk_button_new_with_label(_("Skip"));
2832 data
->BT_sched_skip
= widget
;
2833 gtk_box_pack_start (GTK_BOX (bbox
), widget
, FALSE
, FALSE
, 0);
2835 widget
= gtk_button_new_with_label(_("Edit & Post"));
2836 data
->BT_sched_editpost
= widget
;
2837 gtk_box_pack_start (GTK_BOX (bbox
), widget
, FALSE
, FALSE
, 0);
2839 //TRANSLATORS: Posting a scheduled transaction is the action to materialize it into its target account.
2840 //TRANSLATORS: Before that action the automated transaction occurrence is pending and not yet really existing.
2841 widget
= gtk_button_new_with_label (_("Post"));
2842 data
->BT_sched_post
= widget
;
2843 gtk_box_pack_start (GTK_BOX (bbox
), widget
, FALSE
, FALSE
, 0);
2846 /* image = gtk_image_new_from_icon_name (ICONNAME_HB_SCHED_SKIP, GTK_ICON_SIZE_MENU);
2847 toolitem = gtk_tool_button_new(image, NULL);
2848 data->BT_sched_skip = toolitem;
2849 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
2850 gtk_widget_set_tooltip_text(GTK_WIDGET(toolitem), _("Skip"));
2852 image = gtk_image_new_from_icon_name (ICONNAME_HB_SCHED_POST, GTK_ICON_SIZE_MENU);
2853 toolitem = gtk_tool_button_new(image, NULL);
2854 data->BT_sched_post = toolitem;
2855 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
2856 gtk_widget_set_tooltip_text(GTK_WIDGET(toolitem), _("Post"));
2864 ** the window creation
2866 GtkWidget
*create_hbfile_window(GtkWidget
*do_widget
)
2868 struct hbfile_data
*data
;
2869 struct WinGeometry
*wg
;
2870 GtkWidget
*mainvbox
, *vbox
, *vpaned
, *hpaned
;
2875 DB( g_print("\n[ui-mainwindow] create main window\n") );
2877 data
= g_malloc0(sizeof(struct hbfile_data
));
2878 if(!data
) return NULL
;
2880 window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
2882 //store our window private data
2883 g_object_set_data(G_OBJECT(window
), "inst_data", (gpointer
)data
);
2884 DB( g_print(" - new window=%x, inst_data=%0x\n", (gint
)window
, (gint
)data
) );
2886 // this is our mainwindow, so store it to GLOBALS data
2887 data
->window
= window
;
2888 GLOBALS
->mainwindow
= window
;
2890 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
2891 gtk_container_add (GTK_CONTAINER (window
), mainvbox
);
2893 ui_mainwindow_create_menu_bar_and_toolbar (data
, mainvbox
);
2895 #if HB_UNSTABLE == TRUE
2896 GtkWidget
*bar
, *label
;
2898 bar
= gtk_info_bar_new ();
2899 gtk_box_pack_start (GTK_BOX (mainvbox
), bar
, FALSE
, FALSE
, 0);
2900 gtk_info_bar_set_message_type (GTK_INFO_BAR (bar
), GTK_MESSAGE_WARNING
);
2901 label
= make_label(NULL
, 0.5, 0.5);
2902 gtk_label_set_markup (GTK_LABEL(label
), "Unstable Development Version");
2903 gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar
))), label
, FALSE
, FALSE
, 0);
2906 /* Add the main area */
2907 vbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
2908 //gtk_container_set_border_width (GTK_CONTAINER(vbox), SPACING_MEDIUM);
2909 gtk_box_pack_start (GTK_BOX (mainvbox
), vbox
, TRUE
, TRUE
, 0);
2911 vpaned
= gtk_paned_new(GTK_ORIENTATION_VERTICAL
);
2912 data
->vpaned
= vpaned
;
2913 gtk_box_pack_start (GTK_BOX (vbox
), vpaned
, TRUE
, TRUE
, 0);
2915 hpaned
= gtk_paned_new(GTK_ORIENTATION_HORIZONTAL
);
2916 data
->hpaned
= hpaned
;
2917 gtk_paned_pack1 (GTK_PANED(vpaned
), hpaned
, FALSE
, FALSE
);
2919 widget
= ui_mainwindow_scheduled_create(data
);
2920 gtk_paned_pack2 (GTK_PANED(vpaned
), widget
, FALSE
, FALSE
);
2922 widget
= ui_mainwindow_create_youraccounts(data
);
2923 gtk_paned_pack1 (GTK_PANED(hpaned
), widget
, FALSE
, FALSE
);
2925 widget
= ui_mainwindow_create_topspending(data
);
2926 gtk_paned_pack2 (GTK_PANED(hpaned
), widget
, FALSE
, FALSE
);
2929 DB( g_print(" - vpaned=%d hpaned=%d\n", PREFS
->wal_vpaned
, PREFS
->wal_hpaned
) );
2931 if(PREFS
->wal_hpaned
> 0)
2932 gtk_paned_set_position(GTK_PANED(data
->hpaned
), PREFS
->wal_hpaned
);
2933 if(PREFS
->wal_vpaned
> 0)
2934 gtk_paned_set_position(GTK_PANED(data
->vpaned
), PREFS
->wal_vpaned
);
2936 //setup, init and show window
2937 wg
= &PREFS
->wal_wg
;
2940 gtk_window_move(GTK_WINDOW(window
), wg
->l
, wg
->t
);
2941 gtk_window_resize(GTK_WINDOW(window
), wg
->w
, wg
->h
);
2944 gtk_window_maximize(GTK_WINDOW(window
));
2946 gtk_widget_show_all (window
);
2948 //todo: move this elsewhere
2949 DB( g_print(" - setup stuff\n") );
2951 data
->filter
= da_filter_malloc();
2952 filter_default_all_set(data
->filter
);
2953 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->CY_range
), PREFS
->date_range_wal
);
2957 action
= gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ViewMenu/Toolbar");
2958 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action
), PREFS
->wal_toolbar
);
2959 action
= gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ViewMenu/Spending");
2960 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action
), PREFS
->wal_spending
);
2961 action
= gtk_ui_manager_get_action(data
->manager
, "/MenuBar/ViewMenu/Upcoming");
2962 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action
), PREFS
->wal_upcoming
);
2964 /* Drag and drop support, set targets to NULL because we add the
2965 default uri_targets below */
2967 /* support for opening a file by dragging onto the project window */
2968 gtk_drag_dest_set (GTK_WIDGET (window
),
2969 GTK_DEST_DEFAULT_ALL
,
2971 G_N_ELEMENTS (drop_types
),
2974 g_signal_connect (G_OBJECT (window
), "drag-data-received",
2975 G_CALLBACK (ui_mainwindow_drag_data_received
), window
);
2979 //connect all our signals
2980 DB( g_print(" - connect signals\n") );
2983 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_acc
)), "changed", G_CALLBACK (ui_mainwindow_selection
), NULL
);
2984 g_signal_connect (GTK_TREE_VIEW(data
->LV_acc
), "row-activated", G_CALLBACK (ui_mainwindow_onRowActivated
), GINT_TO_POINTER(2));
2986 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_upc
)), "changed", G_CALLBACK (ui_mainwindow_scheduled_selection_cb
), NULL
);
2987 g_signal_connect (GTK_TREE_VIEW(data
->LV_upc
), "row-activated", G_CALLBACK (ui_mainwindow_scheduled_onRowActivated
), NULL
);
2988 g_signal_connect (G_OBJECT (data
->BT_sched_skip
), "clicked", G_CALLBACK (ui_mainwindow_scheduled_skip_cb
), data
);
2989 g_signal_connect (G_OBJECT (data
->BT_sched_editpost
), "clicked", G_CALLBACK (ui_mainwindow_scheduled_editpost_cb
), data
);
2990 g_signal_connect (G_OBJECT (data
->BT_sched_post
), "clicked", G_CALLBACK (ui_mainwindow_scheduled_post_cb
), data
);
2992 widget
= radio_get_nth_widget(GTK_CONTAINER(data
->RA_type
), 1);
2994 g_signal_connect (widget
, "toggled", G_CALLBACK (ui_mainwindow_populate_topspending
), &data
);
2996 g_signal_connect (data
->CY_range
, "changed", G_CALLBACK (ui_mainwindow_populate_topspending
), NULL
);
2999 /* GtkWindow events */
3000 g_signal_connect (window
, "delete-event", G_CALLBACK (ui_mainwindow_dispose
), (gpointer
)data
);
3003 g_signal_connect (window
, "screen-changed",
3004 G_CALLBACK (ui_mainwindow_window_screen_changed_cb
),
3008 //gtk_action_group_set_sensitive(data->actions, FALSE);