From 1ff77ccd23303d11e6cf86693c6e14eef7bd7e99 Mon Sep 17 00:00:00 2001 From: Dave Peticolas Date: Thu, 12 Apr 2001 23:03:42 +0000 Subject: [PATCH] Bill Gribble's gnome mdi patch. * Lots and lots of changes to support Gnome MDI. And I thought it would be an easy way to get that toolbar problem fixed. Short story is lots of function prototypes changed to reflect the notion that there is no longer a single top-level gnucash window or account tree. 41 files changed, which is too many for me to itemize :) * src/gnome/window-acct-tree.{c,h}: new file; the "account tree window" is the contents of the former main window. Now you can have as many of them open as you want. account trees and reports are the 2 kinds of "main window children" which MDI manages. * src/gnome/window-main-summarybar.{c,h}: new file. I moved the summary bar stuff out of the account tree because there's one summary bar per top-level window but possible many account trees per top-level window. * src/gnome/window-main.c: this is not what it used to be at all. the main gnucash ui element is now a 'GnomeMDI'. The only menus and toolbar items here are ones that are always visible in any top-level window. * src/scm/prefs/scm: acct tree prefs are treated differently (one options obj per acct tree) and are auto-saved and restored. * src/scm/report.scm: report options are auto saved and restored. * src/scm/html-style-sheet.scm: so are style sheets. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3953 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 31 + po/ChangeLog | 46 + src/AccWindow.h | 2 + src/FileDialog.c | 7 +- src/Makefile.am | 1 - src/file-history.h | 3 +- src/gnc-ui-util.c | 3 + src/gnc-ui.h | 32 +- src/gnome/Makefile.am | 5 + src/gnome/dialog-account.c | 10 +- src/gnome/dialog-column-view.c | 3 + src/gnome/dialog-filebox.c | 3 +- src/gnome/dialog-options.c | 6 - src/gnome/dialog-totd.c | 4 +- src/gnome/extensions.c | 30 +- src/gnome/extensions.h | 2 + src/gnome/file-history.c | 10 +- src/gnome/gnc-html.c | 48 +- src/gnome/gnc-html.h | 1 + src/gnome/query-user.c | 22 +- src/gnome/top-level.c | 60 +- src/gnome/top-level.h | 42 + src/gnome/window-acct-tree.c | 1088 +++++++++ src/gnome/window-acct-tree.h | 41 + src/gnome/window-main-summarybar.c | 495 ++++ .../window-main-summarybar.h} | 29 +- src/gnome/window-main.c | 2144 +++++------------ src/gnome/window-main.h | 44 +- src/gnome/window-reconcile.c | 1 - src/gnome/window-register.c | 1 - src/gnome/window-report.c | 511 ++-- src/gnome/window-report.h | 18 +- src/scm/bootstrap.scm.in | 5 + src/scm/extensions.scm | 20 +- src/scm/hooks.scm | 10 +- src/scm/html-style-sheet.scm | 61 +- src/scm/main.scm | 9 +- src/scm/options.scm | 6 +- src/scm/path.scm | 2 +- src/scm/prefs.scm | 155 +- src/scm/report.scm | 139 +- src/scm/report/account-summary.scm | 7 +- src/scm/report/average-balance.scm | 3 +- src/scm/report/budget-report.scm | 4 +- src/scm/report/hello-world.scm | 4 +- src/scm/report/transaction-report.scm | 3 +- src/scm/tip-of-the-day.scm | 18 +- 47 files changed, 3143 insertions(+), 2046 deletions(-) create mode 100644 src/gnome/top-level.h create mode 100644 src/gnome/window-acct-tree.c create mode 100644 src/gnome/window-acct-tree.h create mode 100644 src/gnome/window-main-summarybar.c rename src/{MainWindow.h => gnome/window-main-summarybar.h} (53%) diff --git a/ChangeLog b/ChangeLog index 0455855aa6..e91b99d5cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2001-04-12 Bill Gribble + + * Lots and lots of changes to support Gnome MDI. And I thought it + would be an easy way to get that toolbar problem fixed. Short + story is lots of function prototypes changed to reflect the notion + that there is no longer a single top-level gnucash window or + account tree. 41 files changed, which is too many for me to + itemize :) + + * src/gnome/window-acct-tree.{c,h}: new file; the "account tree + window" is the contents of the former main window. Now you can + have as many of them open as you want. account trees and reports + are the 2 kinds of "main window children" which MDI manages. + + * src/gnome/window-main-summarybar.{c,h}: new file. I moved the + summary bar stuff out of the account tree because there's one + summary bar per top-level window but possible many account trees + per top-level window. + + * src/gnome/window-main.c: this is not what it used to be at all. + the main gnucash ui element is now a 'GnomeMDI'. The only menus + and toolbar items here are ones that are always visible in any + top-level window. + + * src/scm/prefs/scm: acct tree prefs are treated differently (one + options obj per acct tree) and are auto-saved and restored. + + * src/scm/report.scm: report options are auto saved and restored. + + * src/scm/html-style-sheet.scm: so are style sheets. + 2001-04-12 Dave Peticolas * src/register/gnome/gnucash-item-list.c: same as below diff --git a/po/ChangeLog b/po/ChangeLog index 53df44ad11..a6e108cdf1 100644 --- a/po/ChangeLog +++ b/po/ChangeLog @@ -1,3 +1,49 @@ +2001-04-11 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.36. + +2001-04-11 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.36. + +2001-04-11 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.36. + +2001-04-09 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.36. + +2001-04-09 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.36. + +2001-04-09 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.36. + +2001-04-09 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.36. + +2001-04-09 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.36. + +2001-04-09 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.36. + +2001-04-09 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.36. + +2001-04-09 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.36. + * cat-id-tbl.c: Remove file. + * stamp-cat-id: Remove file. + 2001-03-14 Dave Peticolas * da.po: add Danish translation diff --git a/src/AccWindow.h b/src/AccWindow.h index 27f15dc0cb..7992189887 100644 --- a/src/AccWindow.h +++ b/src/AccWindow.h @@ -36,6 +36,8 @@ typedef struct _AccountWindow AccountWindow; AccountWindow * gnc_ui_new_account_window (AccountGroup *group); +AccountWindow * gnc_ui_new_account_window_with_default(AccountGroup *group, + Account * parent); AccountWindow * gnc_ui_edit_account_window (Account *account); Account * gnc_ui_new_accounts_from_name_window (const char *name); diff --git a/src/FileDialog.c b/src/FileDialog.c index 114c047fa1..2300f31b7b 100644 --- a/src/FileDialog.c +++ b/src/FileDialog.c @@ -244,8 +244,7 @@ gncFileNew (void) gboolean gncFileQuerySave (void) { - GNCBook *book = gncGetCurrentBook(); - gncUIWidget app = gnc_get_ui_data(); + GNCBook * book = gncGetCurrentBook(); /* If user wants to mess around before finishing business with * the old file, give em a chance to figure out what's up. @@ -258,8 +257,8 @@ gncFileQuerySave (void) const char *message = _("Changes have been made since the last " "Save. Save the data to file?"); - result = gnc_verify_cancel_dialog_parented (app, message, GNC_VERIFY_YES); - + result = gnc_verify_cancel_dialog (message, GNC_VERIFY_YES); + if (result == GNC_VERIFY_CANCEL) return FALSE; diff --git a/src/Makefile.am b/src/Makefile.am index 87c7b3302f..535d9b7a6a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -57,7 +57,6 @@ noinst_HEADERS = \ EuroUtils.h \ FileBox.h \ FileDialog.h \ - MainWindow.h \ MultiLedger.h \ RecnWindow.h \ RegWindow.h \ diff --git a/src/file-history.h b/src/file-history.h index 0251d0da48..b2b30b243b 100644 --- a/src/file-history.h +++ b/src/file-history.h @@ -23,10 +23,11 @@ #ifndef __HISTORY_H__ #define __HISTORY_H__ +#include #define MAX_HISTORY 4 void gnc_history_add_file (const char *filename); -void gnc_history_update_menu (void); +void gnc_history_update_menu (GnomeApp * app); const char * gnc_history_get_last (void); #endif diff --git a/src/gnc-ui-util.c b/src/gnc-ui-util.c index 0721b30882..4d26018a15 100644 --- a/src/gnc-ui-util.c +++ b/src/gnc-ui-util.c @@ -36,8 +36,10 @@ #include "FileDialog.h" #include "Group.h" #include "global-options.h" +#include "gnc-ui.h" #include "gnc-ui-util.h" #include "gnc-common.h" +#include "gnc-component-manager.h" #include "gnc-engine.h" #include "gnc-engine-util.h" #include "messages.h" @@ -1729,3 +1731,4 @@ gnc_set_auto_decimal_places( int places ) { auto_decimal_places = places; } + diff --git a/src/gnc-ui.h b/src/gnc-ui.h index ab27661f33..005d245032 100644 --- a/src/gnc-ui.h +++ b/src/gnc-ui.h @@ -46,10 +46,6 @@ #define HH_COMMODITY "xacc-commodity.html" -/* Return the main GnuCash window ***********************************/ -gncUIWidget gnc_get_ui_data(void); - - /* Dialog windows ***************************************************/ typedef enum @@ -61,18 +57,20 @@ typedef enum } GNCVerifyResult; GNCVerifyResult - gnc_verify_cancel_dialog_parented(gncUIWidget parent, - const char *message, - GNCVerifyResult default_result); +gnc_verify_cancel_dialog_parented(gncUIWidget parent, + const char *message, + GNCVerifyResult default_result); + +GNCVerifyResult gnc_verify_cancel_dialog(const char *message, + GNCVerifyResult default_result); gboolean gnc_verify_dialog_parented(gncUIWidget parent, const char *message, gboolean yes_is_default); -GNCVerifyResult - gnc_ok_cancel_dialog_parented(gncUIWidget parent, - const char *message, - GNCVerifyResult default_result); +GNCVerifyResult gnc_ok_cancel_dialog_parented(gncUIWidget parent, + const char *message, + GNCVerifyResult default_result); void gnc_warning_dialog_parented(gncUIWidget parent, const char *message); @@ -108,21 +106,15 @@ gboolean gnc_get_username_password (gncUIWidget parent, /* Managing the GUI Windows *****************************************/ -void gnc_ui_destroy_all_subwindows (void); - +void gnc_ui_shutdown (void); +void gnc_ui_destroy_all_subwindows (void); +gncUIWidget gnc_ui_get_toplevel(void); /* Changing the GUI Cursor ******************************************/ void gnc_set_busy_cursor(gncUIWidget w, gboolean update_now); void gnc_unset_busy_cursor(gncUIWidget w); - -/* Getting main window information **********************************/ - -Account * gnc_get_current_account(void); -GList * gnc_get_current_accounts(void); - - /* QIF Import Windows ***********************************************/ typedef struct _qifimportwindow QIFImportWindow; diff --git a/src/gnome/Makefile.am b/src/gnome/Makefile.am index 15ac7d4228..df613f6b8f 100644 --- a/src/gnome/Makefile.am +++ b/src/gnome/Makefile.am @@ -53,8 +53,10 @@ libgncgnome_a_SOURCES = \ query-user.c \ reconcile-list.c \ top-level.c \ + window-acct-tree.c \ window-help.c \ window-main.c \ + window-main-summarybar.c \ window-reconcile.c \ window-register.c \ window-report.c @@ -112,8 +114,11 @@ noinst_HEADERS = \ print-session.h \ query-user.h \ reconcile-list.h \ + top-level.h \ + window-acct-tree.h \ window-help.h \ window-main.h \ + window-main-summarybar.h \ window-reconcile.h \ window-register.h \ window-report.h diff --git a/src/gnome/dialog-account.c b/src/gnome/dialog-account.c index ea3e14b2c2..754a38ab49 100644 --- a/src/gnome/dialog-account.c +++ b/src/gnome/dialog-account.c @@ -28,7 +28,6 @@ #include "AccWindow.h" #include "FileDialog.h" -#include "MainWindow.h" #include "MultiLedger.h" #include "account-tree.h" #include "dialog-account.h" @@ -1820,7 +1819,14 @@ gnc_ui_new_account_window_internal (Account *base_account, AccountWindow * gnc_ui_new_account_window (AccountGroup *this_is_not_used) { - return gnc_ui_new_account_window_internal (gnc_get_current_account (), NULL); + /* FIXME get_current_account went away. */ + return gnc_ui_new_account_window_internal (NULL, NULL); +} + +AccountWindow * +gnc_ui_new_account_window_with_default(AccountGroup *this_is_not_used, + Account * parent) { + return gnc_ui_new_account_window_internal (parent, NULL); } diff --git a/src/gnome/dialog-column-view.c b/src/gnome/dialog-column-view.c index 3cf7d810be..54c0477e0f 100644 --- a/src/gnome/dialog-column-view.c +++ b/src/gnome/dialog-column-view.c @@ -206,7 +206,9 @@ gnc_column_view_edit_add_cb(GtkButton * button, gpointer user_data) { gnc_column_view_edit * r = gtk_object_get_data(GTK_OBJECT(user_data), "view_edit_struct"); SCM make_report = gh_eval_str("gnc:make-report"); + SCM find_report = gh_eval_str("gnc:find-report"); SCM add_child = gh_eval_str("gnc:report-add-child-by-id!"); + SCM add_parent = gh_eval_str("gnc:report-add-parent!"); SCM template_name; SCM set_value = gh_eval_str("gnc:option-set-value"); SCM new_report; @@ -221,6 +223,7 @@ gnc_column_view_edit_add_cb(GtkButton * button, gpointer user_data) { gh_int2scm(r->available_selected)); new_report = gh_call1(make_report, template_name); gh_call2(add_child, r->view, new_report); + gh_call2(add_parent, gh_call1(find_report, new_report), r->view); oldlength = gh_length(r->contents_list); diff --git a/src/gnome/dialog-filebox.c b/src/gnome/dialog-filebox.c index b73cd1b047..1a7c270661 100644 --- a/src/gnome/dialog-filebox.c +++ b/src/gnome/dialog-filebox.c @@ -32,7 +32,6 @@ #include "gnc-engine-util.h" #include "gnc-ui.h" - typedef struct _FileBoxInfo FileBoxInfo; struct _FileBoxInfo { @@ -94,7 +93,7 @@ fileBox (const char * title, const char * filter, const char *default_name) gtk_window_set_modal(GTK_WINDOW(fb_info.file_box), TRUE); gtk_window_set_transient_for(GTK_WINDOW(fb_info.file_box), - GTK_WINDOW(gnc_get_ui_data())); + GTK_WINDOW(gnc_ui_get_toplevel())); gtk_signal_connect(GTK_OBJECT(fb_info.file_box->ok_button), "clicked", GTK_SIGNAL_FUNC(store_filename), diff --git a/src/gnome/dialog-options.c b/src/gnome/dialog-options.c index a419421cf7..1e87af1d60 100644 --- a/src/gnome/dialog-options.c +++ b/src/gnome/dialog-options.c @@ -2103,12 +2103,6 @@ gnc_show_options_dialog(void) { options_dialog = gnc_options_dialog_new(TRUE); - /* - gnome_dialog_close_hides(GNOME_DIALOG(options_dialog), TRUE); - gnome_dialog_set_parent(GNOME_DIALOG(options_dialog), - GTK_WINDOW (gnc_get_ui_data())); - */ - gnc_build_options_dialog_contents(options_dialog, global_options); gnc_option_db_clean(global_options); diff --git a/src/gnome/dialog-totd.c b/src/gnome/dialog-totd.c index 80fb05b4b0..390552ff90 100644 --- a/src/gnome/dialog-totd.c +++ b/src/gnome/dialog-totd.c @@ -61,7 +61,7 @@ static void totd_close_cb(GtkWidget *widget, gpointer data); /** Implementations ***************************************************/ /************************************************************************\ - * gnc_ui_totd_dialog_crfeate_and_run * + * gnc_ui_totd_dialog_create_and_run * * display and run the "Tip of the Day" dialog * * * * Returns: nothing * @@ -92,8 +92,6 @@ gnc_ui_totd_dialog_create(void) GNOME_STOCK_BUTTON_CLOSE, NULL); - gnome_dialog_set_parent(GNOME_DIALOG(win), GTK_WINDOW(gnc_get_ui_data())); - gnome_dialog_set_default(GNOME_DIALOG(win), 2); gnome_dialog_close_hides(GNOME_DIALOG(win), FALSE); diff --git a/src/gnome/extensions.c b/src/gnome/extensions.c index 2cecb0c47f..5b06c0fba6 100644 --- a/src/gnome/extensions.c +++ b/src/gnome/extensions.c @@ -29,7 +29,6 @@ #include "gnc-engine-util.h" #include "gnc-ui.h" - typedef struct _ExtensionInfo ExtensionInfo; struct _ExtensionInfo { @@ -269,8 +268,9 @@ gnc_create_extension_info(SCM extension) ext_info->info[1].type = GNOME_APP_UI_ENDOFINFO; scm_protect_object(extension); - - extension_list = g_slist_prepend(extension_list, ext_info); + + /* need to append so we can run them in order */ + extension_list = g_slist_append(extension_list, ext_info); return ext_info; } @@ -295,24 +295,28 @@ gnc_add_extension(SCM extension) { GnomeApp *app; ExtensionInfo *ext_info; - char *path; - ext_info = gnc_create_extension_info(extension); if (ext_info == NULL) { PERR("bad extension"); return; } - - path = gnc_extension_path(ext_info); - - app = GNOME_APP(gnc_get_ui_data()); - gnome_app_insert_menus(app, path, ext_info->info); - gnome_app_install_menu_hints(app, ext_info->info); - - g_free(path); } +void +gnc_extensions_menu_setup(GnomeApp * app) { + GSList * l = NULL; + ExtensionInfo * info; + char * path; + + for(l=extension_list; l; l=l->next) { + info = l->data; + path = gnc_extension_path(info); + gnome_app_insert_menus(app, path, info->info); + gnome_app_install_menu_hints(app, info->info); + g_free(path); + } +} void gnc_extensions_shutdown(void) diff --git a/src/gnome/extensions.h b/src/gnome/extensions.h index 272f29772d..1e1ff2deb8 100644 --- a/src/gnome/extensions.h +++ b/src/gnome/extensions.h @@ -24,8 +24,10 @@ #define __EXTENSIONS_H__ #include +#include void gnc_add_extension(SCM extension); +void gnc_extensions_menu_setup(GnomeApp * app); void gnc_extensions_shutdown(void); #endif diff --git a/src/gnome/file-history.c b/src/gnome/file-history.c index ef44d86b8e..d41b54d2ec 100644 --- a/src/gnome/file-history.c +++ b/src/gnome/file-history.c @@ -29,7 +29,6 @@ #include "gnc-ui.h" #include "messages.h" - static GSList *history_list = NULL; static gint num_menu_entries = -1; @@ -155,10 +154,9 @@ gnc_history_get_last(void) } void -gnc_history_update_menu(void) +gnc_history_update_menu(GnomeApp * app) { GtkWidget *app_w; - GnomeApp *app; GnomeUIInfo *menu; GnomeDockItem *di; GtkWidget *menushell; @@ -170,12 +168,6 @@ gnc_history_update_menu(void) int i, n; int pos; - app_w = gnc_get_ui_data (); - if (!app_w) - return; - - app = GNOME_APP (app_w); - di = gnome_app_get_dock_item_by_name(app, GNOME_APP_MENUBAR_NAME); if (di == NULL) return; diff --git a/src/gnome/gnc-html.c b/src/gnome/gnc-html.c index b1875b3a1a..457878b8a2 100644 --- a/src/gnome/gnc-html.c +++ b/src/gnome/gnc-html.c @@ -60,6 +60,7 @@ #include "gnc-network.h" #include "query-user.h" #include "window-help.h" +#include "window-main.h" #include "window-report.h" #include "messages.h" @@ -196,6 +197,9 @@ gnc_html_parse_url(gnc_html * html, const gchar * url, } else if(!strcmp(protocol, "gnc-register")) { retval = URL_TYPE_REGISTER; + } + else if(!strcmp(protocol, "gnc-acct-tree")) { + retval = URL_TYPE_ACCTTREE; } else if(!strcmp(protocol, "gnc-report")) { retval = URL_TYPE_REPORT; @@ -218,14 +222,19 @@ gnc_html_parse_url(gnc_html * html, const gchar * url, retval = URL_TYPE_JUMP; } else { - retval = html->base_type; + if(html) { + retval = html->base_type; + } + else { + retval = URL_TYPE_FILE; + } } g_free(protocol); switch(retval) { case URL_TYPE_FILE: - if(!found_protocol && path && html->base_location) { + if(!found_protocol && path && html && html->base_location) { if(path[0] == '/') { *url_location = g_strdup(path); } @@ -247,7 +256,7 @@ gnc_html_parse_url(gnc_html * html, const gchar * url, case URL_TYPE_OTHER: default: - if(!found_protocol && path && html->base_location) { + if(!found_protocol && path && html && html->base_location) { if(path[0] == '/') { *url_location = g_strconcat(extract_machine_name(html->base_location), @@ -347,7 +356,7 @@ extract_base_name(URLType type, const gchar * path) { static char * url_type_names[] = { "file:", "", "http:", "ftp:", "https:", - "gnc-register:", "gnc-report:", "gnc-options:", "gnc-scm:", + "gnc-register:", "gnc-acct-tree:", "gnc-report:", "gnc-options:", "gnc-scm:", "gnc-help:", "gnc-xml:", "gnc-action:", "" }; @@ -590,6 +599,7 @@ gnc_html_load_to_stream(gnc_html * html, GtkHTMLStream * handle, break; case URL_TYPE_REGISTER: + case URL_TYPE_ACCTTREE: case URL_TYPE_OPTIONS: case URL_TYPE_SCHEME: case URL_TYPE_FTP: @@ -1088,23 +1098,26 @@ gnc_html_open_report(gnc_html * html, const gchar * location, const gchar * label, int newwin) { gnc_report_window * rwin; GtkHTMLStream * handle; + char * rebuilt_url; /* make a new window if necessary */ if(newwin) { - rwin = gnc_report_window_new(NULL); - html = gnc_report_window_get_html(rwin); + rebuilt_url = rebuild_url(URL_TYPE_REPORT, location, label); + gnc_main_window_open_report_url(rebuilt_url, FALSE); + g_free(rebuilt_url); + } + else { + gnc_html_history_append(html->history, + gnc_html_history_node_new(URL_TYPE_REPORT, + location, label)); + + g_free(html->base_location); + html->base_type = URL_TYPE_FILE; + html->base_location = NULL; + + handle = gtk_html_begin(GTK_HTML(html->html)); + gnc_html_load_to_stream(html, handle, URL_TYPE_REPORT, location, label); } - - gnc_html_history_append(html->history, - gnc_html_history_node_new(URL_TYPE_REPORT, - location, label)); - - g_free(html->base_location); - html->base_type = URL_TYPE_FILE; - html->base_location = NULL; - - handle = gtk_html_begin(GTK_HTML(html->html)); - gnc_html_load_to_stream(html, handle, URL_TYPE_REPORT, location, label); } @@ -1250,6 +1263,7 @@ gnc_html_show_url(gnc_html * html, URLType type, (gpointer)html); break; + URL_TYPE_ACCTTREE: default: break; } diff --git a/src/gnome/gnc-html.h b/src/gnome/gnc-html.h index a54ee9aba4..e3e776f45b 100644 --- a/src/gnome/gnc-html.h +++ b/src/gnome/gnc-html.h @@ -32,6 +32,7 @@ typedef enum { URL_TYPE_FILE, URL_TYPE_JUMP, URL_TYPE_HTTP, URL_TYPE_FTP, URL_TYPE_SECURE, URL_TYPE_REGISTER, /* for gnucash register popups */ + URL_TYPE_ACCTTREE, /* for account tree windows */ URL_TYPE_REPORT, /* for gnucash report popups */ URL_TYPE_OPTIONS, /* for editing report options */ URL_TYPE_SCHEME, /* for scheme code evaluation */ diff --git a/src/gnome/query-user.c b/src/gnome/query-user.c index b70c90f45d..cd6bad80c7 100644 --- a/src/gnome/query-user.c +++ b/src/gnome/query-user.c @@ -100,6 +100,16 @@ gnc_ok_cancel_dialog_parented(gncUIWidget parent, const char *message, * default - the button that will be the default * * Return: the result the user selected * \********************************************************************/ + +GNCVerifyResult +gnc_verify_cancel_dialog(const char * message, GNCVerifyResult default_res) +{ + gnc_verify_cancel_dialog_parented(gnc_ui_get_toplevel(), message, + default_res); +} + + + GNCVerifyResult gnc_verify_cancel_dialog_parented(GtkWidget *parent, const char *message, GNCVerifyResult default_result) @@ -164,7 +174,7 @@ gnc_verify_cancel_dialog_parented(GtkWidget *parent, const char *message, gboolean gnc_verify_dialog(const char *message, gboolean yes_is_default) { - return gnc_verify_dialog_parented(gnc_get_ui_data(), + return gnc_verify_dialog_parented(gnc_ui_get_toplevel(), message, yes_is_default); } @@ -196,8 +206,8 @@ gnc_verify_dialog_parented(gncUIWidget parent, const char *message, gnome_dialog_set_parent(GNOME_DIALOG(verify_box), GTK_WINDOW(parent)); else gnome_dialog_set_parent(GNOME_DIALOG(verify_box), - GTK_WINDOW(gnc_get_ui_data())); - + GTK_WINDOW(gnc_ui_get_toplevel())); + gnome_dialog_set_default(GNOME_DIALOG(verify_box), yes_is_default ? 0 : 1); return (gnome_dialog_run_and_close(GNOME_DIALOG(verify_box)) == 0); @@ -213,7 +223,7 @@ gnc_verify_dialog_parented(gncUIWidget parent, const char *message, void gnc_info_dialog(const char *message) { - gnc_info_dialog_parented(GTK_WINDOW(gnc_get_ui_data()), message); + gnc_info_dialog_parented(GTK_WINDOW(gnc_ui_get_toplevel()), message); } /********************************************************************\ @@ -244,7 +254,7 @@ gnc_info_dialog_parented(GtkWindow *parent, const char *message) void gnc_warning_dialog(const char *message) { - gnc_warning_dialog_parented(gnc_get_ui_data(), message); + gnc_warning_dialog_parented(gnc_ui_get_toplevel(), message); } /********************************************************************\ @@ -275,7 +285,7 @@ gnc_warning_dialog_parented(GtkWidget *parent, const char *message) void gnc_error_dialog(const char *message) { - gnc_error_dialog_parented(GTK_WINDOW(gnc_get_ui_data()), message); + gnc_error_dialog_parented(GTK_WINDOW(gnc_ui_get_toplevel()), message); } /********************************************************************\ diff --git a/src/gnome/top-level.c b/src/gnome/top-level.c index 1680319d31..2d91544372 100644 --- a/src/gnome/top-level.c +++ b/src/gnome/top-level.c @@ -35,7 +35,6 @@ #include "AccWindow.h" #include "FileBox.h" #include "FileDialog.h" -#include "MainWindow.h" #include "SplitLedger.h" #include "TransLog.h" #include "argv-list-converters.h" @@ -66,6 +65,7 @@ #include "splitreg.h" #include "window-help.h" #include "window-main.h" +#include "window-acct-tree.h" #include "window-report.h" #include "new-user-interface.h" #include "new-user-funs.h" @@ -101,7 +101,7 @@ static void gnc_configure_register_hint_font(void); /* This static indicates the debugging module that this .o belongs to. */ static short module = MOD_GUI; -static GtkWidget *app = NULL; +static GNCMainInfo * app = NULL; static int gnome_is_running = FALSE; static int gnome_is_initialized = FALSE; @@ -138,12 +138,19 @@ gnucash_ui_is_terminating(void) /* ============================================================== */ -gncUIWidget -gnc_get_ui_data(void) +GNCMainInfo * +gnc_ui_get_data(void) { return app; } +gncUIWidget +gnc_ui_get_toplevel(void) { + /* FIXME */ + return gnc_main_window_get_toplevel(app); +} + + static const char* gnc_scheme_remaining_var = "gnc:*command-line-remaining*"; static char** @@ -236,13 +243,11 @@ gnucash_ui_init(void) /* put up splash screen */ gnc_show_splash_screen (); - + /* make sure splash is up */ while (gtk_events_pending ()) gtk_main_iteration (); - app = gnome_app_new("GnuCash", "GnuCash"); - gnc_configure_date_format(); date_callback_id = gnc_register_option_change_callback(gnc_configure_date_format_cb, NULL, @@ -308,9 +313,17 @@ gnucash_ui_init(void) xaccRecnCellSetStringGetter(gnc_get_reconcile_str); /* gnc_default_ui_start */ - gnucash_style_init(); gnucash_color_init(); + + /* initialize gnome MDI and set up application window defaults */ + app = gnc_main_window_new(); + /* Run the ui startup hooks. */ + { + SCM run_danglers = gh_eval_str("gnc:hook-run-danglers"); + SCM hook = gh_eval_str("gnc:*ui-startup-hook*"); + gh_call1(run_danglers, hook); + } } LEAVE ("\n"); @@ -320,13 +333,14 @@ gnucash_ui_init(void) static gboolean hasstarted = FALSE; void -gnc_default_ui_start(void) -{ - if(!hasstarted) - { - mainWindow(); - hasstarted = TRUE; +gnc_default_ui_start(void) { + if(!hasstarted) { + if(!gnome_mdi_restore_state(app->mdi, "/GnuCash/MDI Session", + gnc_main_window_create_child)) { + gnc_main_window_open_accounts(FALSE); } + hasstarted = TRUE; + } } /* ============================================================== */ @@ -337,9 +351,9 @@ gnc_ui_shutdown (void) if (gnome_is_running && !gnome_is_terminating) { gnome_is_terminating = TRUE; - gnc_ui_destroy_all_subwindows(); - gnc_ui_mainWindow_save_size(); - gtk_widget_hide(app); + gnc_main_window_save(app); + gnc_main_window_destroy(app); + app = NULL; gtk_main_quit(); #ifdef USE_GUPPI gnc_html_guppi_shutdown(); @@ -367,7 +381,7 @@ gnc_ui_destroy (void) if (app != NULL) { - gtk_widget_destroy(app); + gnc_main_window_destroy(app); app = NULL; } @@ -385,20 +399,10 @@ gnc_ui_show_main_window(void) gnucash_ui_init(); gnc_default_ui_start(); - gtk_widget_show(app); - /* Get the main window on screen. */ while (gtk_events_pending()) gtk_main_iteration(); - /* Run the main window hooks. */ - { - SCM run_danglers = gh_eval_str("gnc:hook-run-danglers"); - SCM hook = gh_eval_str("gnc:*main-window-opened-hook*"); - SCM window = gw_wcp_assimilate_ptr(app, gh_eval_str("")); - gh_call2(run_danglers, hook, window); - } - return 0; } diff --git a/src/gnome/top-level.h b/src/gnome/top-level.h new file mode 100644 index 0000000000..ca96984247 --- /dev/null +++ b/src/gnome/top-level.h @@ -0,0 +1,42 @@ +/******************************************************************** + * top-level.h -- public gnucash UI functions * + * Copyright (C) 2001 Bill Gribble * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + ********************************************************************/ + +#ifndef __TOP_LEVEL_H__ +#define __TOP_LEVEL_H__ + +#include "window-main.h" + +int gnucash_ui_is_running(void); +int gnucash_ui_is_terminating(void); +int gnucash_ui_init(void); +int gnucash_ui_open_file(const char * name); +int gnucash_ui_select_file(void); + +GNCMainInfo * gnc_ui_get_data(void); +void gnc_default_ui_start(void); +void gnc_ui_shutdown(void); +void gnc_ui_destroy(void); +int gnc_ui_show_main_window(void); +int gnc_ui_start_event_loop(void); +int gnc_ui_main(void); + +#endif diff --git a/src/gnome/window-acct-tree.c b/src/gnome/window-acct-tree.c new file mode 100644 index 0000000000..0fa1981ebd --- /dev/null +++ b/src/gnome/window-acct-tree.c @@ -0,0 +1,1088 @@ +/******************************************************************** + * window-main.c -- the main window, and associated helpers * + * Copyright (C) 1998,1999 Jeremy Collins * + * Copyright (C) 1998,1999,2000 Linas Vepstas * + * Copyright (C) 2001 Bill Gribble * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + ********************************************************************/ + +#include "config.h" + +#include +#include +#include + +#include "AccWindow.h" +#include "RegWindow.h" +#include "FileBox.h" +#include "FileDialog.h" +#include "Scrub.h" + +#include "account-tree.h" +#include "dialog-account.h" +#include "dialog-transfer.h" +#include "dialog-utils.h" +#include "file-history.h" +#include "global-options.h" +#include "gnc-commodity.h" +#include "gnc-component-manager.h" +#include "gnc-engine-util.h" +#include "gnc-engine.h" +#include "gnc-ui.h" +#include "gnucash.h" +#include "gtkselect.h" +#include "messages.h" +#include "mainwindow-account-tree.h" +#include "option-util.h" +#include "top-level.h" +#include "window-acct-tree.h" +#include "window-help.h" +#include "window-main.h" +#include "window-reconcile.h" +#include "window-register.h" +#include "window-report.h" + +#include "io-gncxml-v2.h" +#include "gnc-book.h" + +/* FIXME get rid of these */ +#include "gnc.h" + +static short module = MOD_GUI; +#define WINDOW_ACCT_TREE_CM_CLASS "window-acct-tree" + + +/* acct tree window information structure */ +struct GNCAcctTreeWin_p +{ + GtkWidget * account_tree; + + SCM euro_change_callback_id; + SCM name_change_callback_id; + + GNCOptionDB * odb; + SCM options; + int options_id; + + GList * account_sensitives; +}; + + +/******************************************************************** + * ACCOUNT WINDOW FUNCTIONS + * creating/managing account-window mdi children + ********************************************************************/ + +/******************************************************************** + * acct_labeler + * fixme: we need to be able to dynamically select account tab names + ********************************************************************/ + +static GtkWidget * +gnc_acct_tree_view_labeler(GnomeMDIChild * child, GtkWidget * current, + gpointer user_data) { + GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child)); + GNCAcctTreeWin * win = mc->user_data; + char * name = NULL; + + if(win) { + name = gnc_option_db_lookup_string_option(win->odb, + "Account Tree", + "Name of account view", + NULL); + } + else { + name = strdup("Accounts"); + } + + if(current == NULL) { + return gtk_label_new(name); + } + else { + gtk_label_set_text(GTK_LABEL(current), name); + return current; + } +} + + +static void +gnc_acct_tree_view_destroy(GtkObject * obj, gpointer user_data) { + GNCMainChildInfo * mc = user_data; + GNCAcctTreeWin * w = mc->user_data; + + gnc_main_window_remove_child(gnc_ui_get_data(), mc); + gnc_acct_tree_window_destroy(w); + g_free(mc->toolbar_info); + g_free(mc->menu_info); + g_free(mc); +} + + +/******************************************************************** + * acct_tree_view_new + * create a new account view. + ********************************************************************/ + +static GtkWidget * +gnc_acct_tree_view_new(GnomeMDIChild * child, gpointer user_data) { + GNCMainInfo * maininfo = user_data; + GNCMainChildInfo * mc = g_new0(GNCMainChildInfo, 1); + GNCAcctTreeWin * win = gnc_acct_tree_window_new(child->name); + + mc->contents = gnc_acct_tree_window_get_widget(win); + mc->child = child; + mc->app = NULL; + mc->component_id = gnc_register_gui_component(WINDOW_ACCT_TREE_CM_CLASS, + NULL, NULL, mc); + mc->user_data = win; + + /* set the child name that will get used to save app state */ + mc->child->name = g_strdup_printf("gnc-acct-tree:id=%d", + win->options_id); + + gtk_object_set_user_data(GTK_OBJECT(child), mc); + gtk_signal_connect(GTK_OBJECT(child), "destroy", + gnc_acct_tree_view_destroy, mc); + + gnc_main_window_add_child(maininfo, mc); + + win->name_change_callback_id = + gnc_option_db_register_change_callback(win->odb, + gnc_main_window_child_refresh, + mc, + N_("Account Tree"), + N_("Name of account view")); + scm_protect_object(win->name_change_callback_id); + + gnc_acct_tree_window_create_menu(win, mc); + gnc_acct_tree_window_create_toolbar(win, mc); + gnc_main_window_create_child_toolbar(maininfo, mc); + + if(mc->menu_info) { + gnome_mdi_child_set_menu_template(child, mc->menu_info); + } + + return mc->contents; +} + + +/******************************************************************** + * gnc_acct_tree_window_create_child() + * return an MDI child that will create views of the specified tree + * (configstring is the acct tree URL) + ********************************************************************/ + +GnomeMDIChild * +gnc_acct_tree_window_create_child(const gchar * configstring) { + GNCMainInfo * maininfo = gnc_ui_get_data(); + GnomeMDIGenericChild * accountchild = + gnome_mdi_generic_child_new(configstring); + + gnome_mdi_generic_child_set_label_func(accountchild, + gnc_acct_tree_view_labeler, + maininfo); + gnome_mdi_generic_child_set_view_creator(accountchild, + gnc_acct_tree_view_new, + maininfo); + return GNOME_MDI_CHILD(accountchild); +} + + +/******************************************************************** + * gnc_main_window_open_accounts() + * open a top-level window with the account browser in it + ********************************************************************/ + +void +gnc_main_window_open_accounts(gint toplevel) { + GNCMainInfo * maininfo = gnc_ui_get_data(); + GnomeMDIChild * accountchild = gnc_acct_tree_window_create_child(NULL); + gnome_mdi_add_child(GNOME_MDI(maininfo->mdi), + GNOME_MDI_CHILD(accountchild)); + + if(toplevel) { + gnome_mdi_add_toplevel_view(GNOME_MDI(maininfo->mdi), + GNOME_MDI_CHILD(accountchild)); + } + else { + gnome_mdi_add_view(GNOME_MDI(maininfo->mdi), + GNOME_MDI_CHILD(accountchild)); + } +} + + +static void +gnc_acct_tree_window_toolbar_open_cb (GtkWidget *widget, gpointer data) +{ + RegWindow *regData; + GNCAcctTreeWin * win = data; + Account * account = gnc_acct_tree_window_get_current_account(win); + + if (account == NULL) + { + const char *message = _("To open an account, you must first\n" + "choose an account to open."); + gnc_error_dialog(message); + return; + } + + PINFO ("calling regWindowSimple(%p)\n", account); + + regData = regWindowSimple(account); + gnc_register_raise(regData); +} + +static void +gnc_acct_tree_window_toolbar_edit_cb (GtkWidget *widget, gpointer data) +{ + GNCAcctTreeWin * win = data; + Account * account = gnc_acct_tree_window_get_current_account(win); + + AccountWindow *edit_window_data; + + if (account != NULL) + { + edit_window_data = gnc_ui_edit_account_window(account); + gnc_ui_edit_account_window_raise(edit_window_data); + } + else + { + const char *message = _("To edit an account, you must first\n" + "choose an account to edit.\n"); + gnc_error_dialog(message); + } +} + +static void +gnc_acct_tree_window_toolbar_add_account_cb (GtkWidget *widget, gpointer data) +{ + GNCAcctTreeWin * win = data; + Account * account = gnc_acct_tree_window_get_current_account(win); + gnc_ui_new_account_window_with_default (NULL, account); +} + + +static void +gnc_acct_tree_window_toolbar_delete_account_cb (GtkWidget *widget, + gpointer data) +{ + GNCAcctTreeWin * win = data; + Account * account = gnc_acct_tree_window_get_current_account(win); + + if (account) + { + const char *format = _("Are you sure you want to delete the %s account?"); + char *message; + char *name; + + name = xaccAccountGetFullName(account, gnc_get_account_separator ()); + message = g_strdup_printf(format, name); + + if (gnc_verify_dialog(message, FALSE)) { + gnc_suspend_gui_refresh (); + + xaccAccountBeginEdit (account); + xaccAccountDestroy (account); + + gnc_resume_gui_refresh (); + } + g_free(name); + g_free(message); + } + else + { + const char *message = _("To delete an account, you must first\n" + "choose an account to delete.\n"); + gnc_error_dialog(message); + } +} + + +static void +gnc_acct_tree_window_menu_open_subs_cb(GtkWidget * widget, + GnomeMDIChild * child) { + GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child)); + GNCAcctTreeWin * win = mc->user_data; + Account * account = gnc_acct_tree_window_get_current_account(win); + RegWindow * regData; + + if (account == NULL) { + const char *message = _("To open an account, you must first\n" + "choose an account to open."); + gnc_error_dialog(message); + return; + } + else { + PINFO ("calling regWindowAccGroup(%p)\n", account); + + regData = regWindowAccGroup(account); + gnc_register_raise(regData); + } +} + + +static void +gnc_acct_tree_window_menu_edit_cb (GtkWidget * widget, + GnomeMDIChild * child) { + GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child)); + GNCAcctTreeWin * win = mc->user_data; + Account * account = gnc_acct_tree_window_get_current_account(win); + + AccountWindow *edit_window_data; + + if (account != NULL) + { + edit_window_data = gnc_ui_edit_account_window(account); + gnc_ui_edit_account_window_raise(edit_window_data); + } + else + { + const char *message = _("To edit an account, you must first\n" + "choose an account to edit.\n"); + gnc_error_dialog(message); + } +} + + +static void +gnc_acct_tree_window_menu_reconcile_cb(GtkWidget * widget, + GnomeMDIChild * child) { + GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child)); + GNCAcctTreeWin * win = mc->user_data; + Account * account = gnc_acct_tree_window_get_current_account(win); + RecnWindow * recnData; + + if (account != NULL) + { + recnData = recnWindow(gnc_ui_get_toplevel(), account); + gnc_ui_reconcile_window_raise(recnData); + } + else + { + const char *message = _("To reconcile an account, you must first\n" + "choose an account to reconcile."); + gnc_error_dialog(message); + } +} + +static void +gnc_acct_tree_window_menu_transfer_cb (GtkWidget * widget, + GnomeMDIChild * child) { + GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child)); + GNCAcctTreeWin * win = mc->user_data; + Account * account = gnc_acct_tree_window_get_current_account(win); + + gnc_xfer_dialog (gnc_ui_get_toplevel (), account); +} + +static void +gnc_acct_tree_window_menu_stock_split_cb (GtkWidget * widget, + GnomeMDIChild * child) { + GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child)); + GNCAcctTreeWin * win = mc->user_data; + Account * account = gnc_acct_tree_window_get_current_account(win); + + gnc_stock_split_dialog (account); +} + +static void +gnc_acct_tree_window_menu_add_account_cb (GtkWidget * widget, + GnomeMDIChild * child) { + GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child)); + GNCAcctTreeWin * win = mc->user_data; + Account * account = gnc_acct_tree_window_get_current_account(win); + gnc_ui_new_account_window_with_default (NULL, account); +} + +static void +gnc_acct_tree_window_menu_delete_account_cb (GtkWidget *widget, + GnomeMDIChild * child) { + GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child)); + GNCAcctTreeWin * win = mc->user_data; + Account * account = gnc_acct_tree_window_get_current_account(win); + + if (account) { + const char *format = _("Are you sure you want to delete the %s account?"); + char *message; + char *name; + + name = xaccAccountGetFullName(account, gnc_get_account_separator ()); + message = g_strdup_printf(format, name); + + if (gnc_verify_dialog(message, FALSE)) { + gnc_suspend_gui_refresh (); + + xaccAccountBeginEdit (account); + xaccAccountDestroy (account); + + gnc_resume_gui_refresh (); + } + g_free(name); + g_free(message); + } + else { + const char *message = _("To delete an account, you must first\n" + "choose an account to delete.\n"); + gnc_error_dialog(message); + } +} + +static void +gnc_acct_tree_window_menu_tax_info_cb (GtkWidget * widget, + GnomeMDIChild * child) { + GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child)); + GNCAcctTreeWin * win = mc->user_data; + Account * account = gnc_acct_tree_window_get_current_account(win); + gnc_tax_info_dialog(GTK_WIDGET(mc->app)); +} + +static void +gnc_acct_tree_window_menu_scrub_cb(GtkWidget * widget, + GnomeMDIChild * child) { + GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child)); + GNCAcctTreeWin * win = mc->user_data; + Account * account = gnc_acct_tree_window_get_current_account(win); + + if (account == NULL) + { + const char *message = _("You must select an account to scrub."); + gnc_error_dialog (message); + return; + } + + gnc_suspend_gui_refresh (); + + xaccAccountScrubOrphans (account); + xaccAccountScrubImbalance (account); + + gnc_resume_gui_refresh (); +} + +static void +gnc_acct_tree_window_menu_scrub_sub_cb(GtkWidget * widget, + GnomeMDIChild * child) { + GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child)); + GNCAcctTreeWin * win = mc->user_data; + Account * account = gnc_acct_tree_window_get_current_account(win); + + if (account == NULL) + { + const char *message = _("You must select an account to scrub."); + gnc_error_dialog(message); + return; + } + + gnc_suspend_gui_refresh (); + + xaccAccountTreeScrubOrphans (account); + xaccAccountTreeScrubImbalance (account); + + gnc_resume_gui_refresh (); +} + +static void +gnc_acct_tree_window_menu_scrub_all_cb(GtkWidget * widget, + GnomeMDIChild * child) { + AccountGroup *group = gncGetCurrentGroup (); + + gnc_suspend_gui_refresh (); + + xaccGroupScrubOrphans (group); + xaccGroupScrubImbalance (group); + + gnc_resume_gui_refresh (); +} + +static void +gnc_acct_tree_window_menu_open_cb (GtkWidget *widget, GnomeMDIChild * child) +{ + GNCMainChildInfo * mc = gtk_object_get_user_data(GTK_OBJECT(child)); + GNCAcctTreeWin * win = mc->user_data; + Account * account = gnc_acct_tree_window_get_current_account(win); + RegWindow * regData; + + if (account == NULL) { + const char *message = _("To open an account, you must first\n" + "choose an account to open."); + gnc_error_dialog(message); + return; + } + else { + PINFO ("calling regWindowSimple(%p)\n", account); + + regData = regWindowSimple(account); + gnc_register_raise(regData); + } +} + + +static void +gnc_acct_tree_window_destroy_cb (GtkObject *object, gpointer user_data) +{ + GNCAcctTreeWin *win = user_data; + gnc_acct_tree_window_destroy(win); +} + +static void +gnc_acct_tree_window_activate_cb(GNCMainWinAccountTree *tree, + Account *account, + gpointer user_data) +{ + GNCAcctTreeWin * win = user_data; + RegWindow *regData; + gboolean expand; + + expand = + gnc_option_db_lookup_boolean_option(win->odb, + "Account Tree", + "Double click expands parent accounts", + FALSE); + + if (expand) + { + AccountGroup *group; + + group = xaccAccountGetChildren(account); + if (xaccGroupGetNumAccounts(group) > 0) + { + gnc_mainwin_account_tree_toggle_account_expansion(tree, account); + return; + } + } + + regData = regWindowSimple(account); + gnc_register_raise(regData); +} + +static void +gnc_acct_tree_window_configure (GNCAcctTreeWin * info) { + + GNCMainWinAccountTree *tree; + AccountViewInfo new_avi; + GSList *list, *node; + + memset (&new_avi, 0, sizeof(new_avi)); + + tree = GNC_MAINWIN_ACCOUNT_TREE(info->account_tree); + + list = gnc_option_db_lookup_list_option(info->odb, + "Account Tree", + "Account types to display", + NULL); + + for (node = list; node != NULL; node = node->next) + { + if (safe_strcmp(node->data, "bank") == 0) + new_avi.include_type[BANK] = TRUE; + + else if (safe_strcmp(node->data, "cash") == 0) + new_avi.include_type[CASH] = TRUE; + + else if (safe_strcmp(node->data, "credit") == 0) + new_avi.include_type[CREDIT] = TRUE; + + else if (safe_strcmp(node->data, "asset") == 0) + new_avi.include_type[ASSET] = TRUE; + + else if (safe_strcmp(node->data, "liability") == 0) + new_avi.include_type[LIABILITY] = TRUE; + + else if (safe_strcmp(node->data, "stock") == 0) + new_avi.include_type[STOCK] = TRUE; + + else if (safe_strcmp(node->data, "mutual") == 0) + new_avi.include_type[MUTUAL] = TRUE; + + else if (safe_strcmp(node->data, "currency") == 0) + new_avi.include_type[CURRENCY] = TRUE; + + else if (safe_strcmp(node->data, "income") == 0) + new_avi.include_type[INCOME] = TRUE; + + else if (safe_strcmp(node->data, "expense") == 0) + new_avi.include_type[EXPENSE] = TRUE; + + else if (safe_strcmp(node->data, "equity") == 0) + new_avi.include_type[EQUITY] = TRUE; + } + + gnc_free_list_option_value (list); + + list = gnc_option_db_lookup_list_option(info->odb, + "Account Tree", + "Account fields to display", + NULL); + + for (node = list; node != NULL; node = node->next) + { + if (safe_strcmp(node->data, "type") == 0) + new_avi.show_field[ACCOUNT_TYPE] = TRUE; + + else if (safe_strcmp(node->data, "code") == 0) + new_avi.show_field[ACCOUNT_CODE] = TRUE; + + else if (safe_strcmp(node->data, "description") == 0) + new_avi.show_field[ACCOUNT_DESCRIPTION] = TRUE; + + else if (safe_strcmp(node->data, "notes") == 0) + new_avi.show_field[ACCOUNT_NOTES] = TRUE; + + else if (safe_strcmp(node->data, "currency") == 0) + new_avi.show_field[ACCOUNT_CURRENCY] = TRUE; + + else if (safe_strcmp(node->data, "security") == 0) + new_avi.show_field[ACCOUNT_SECURITY] = TRUE; + + else if (safe_strcmp(node->data, "balance") == 0) + { + new_avi.show_field[ACCOUNT_BALANCE] = TRUE; + if(gnc_lookup_boolean_option("International", + "Enable EURO support", FALSE)) + new_avi.show_field[ACCOUNT_BALANCE_EURO] = TRUE; + } + + else if (safe_strcmp(node->data, "total") == 0) + { + new_avi.show_field[ACCOUNT_TOTAL] = TRUE; + if(gnc_lookup_boolean_option("International", + "Enable EURO support", FALSE)) + new_avi.show_field[ACCOUNT_TOTAL_EURO] = TRUE; + } + } + + gnc_free_list_option_value (list); + + new_avi.show_field[ACCOUNT_NAME] = TRUE; + + gnc_mainwin_account_tree_set_view_info (tree, new_avi); +} + +static void +gnc_euro_change (gpointer data) +{ + gnc_acct_tree_window_configure (data); + gnc_gui_refresh_all (); +} + +static void gnc_acct_tree_window_toolbar_options_cb(GtkWidget * w, gpointer d); + +void +gnc_acct_tree_window_create_toolbar(GNCAcctTreeWin * win, + GNCMainChildInfo * child) { + GnomeUIInfo toolbar_template[] = + { + { GNOME_APP_UI_ITEM, + N_("Open"), + N_("Open the selected account"), + gnc_acct_tree_window_toolbar_open_cb, + win, + NULL, + GNOME_APP_PIXMAP_STOCK, + GNOME_STOCK_PIXMAP_JUMP_TO, + 0, 0, NULL + }, + { GNOME_APP_UI_ITEM, + N_("Edit"), + N_("Edit the selected account"), + gnc_acct_tree_window_toolbar_edit_cb, + win, + NULL, + GNOME_APP_PIXMAP_STOCK, + GNOME_STOCK_PIXMAP_PROPERTIES, + 0, 0, NULL + }, + GNOMEUIINFO_SEPARATOR, + { GNOME_APP_UI_ITEM, + N_("Options"), + N_("Edit the account view options"), + gnc_acct_tree_window_toolbar_options_cb, + win, + NULL, + GNOME_APP_PIXMAP_STOCK, + GNOME_STOCK_PIXMAP_PROPERTIES, + 0, 0, NULL + }, + GNOMEUIINFO_SEPARATOR, + { GNOME_APP_UI_ITEM, + N_("New"), + N_("Create a new account"), + gnc_acct_tree_window_toolbar_add_account_cb, + win, + NULL, + GNOME_APP_PIXMAP_STOCK, + GNOME_STOCK_PIXMAP_ADD, + 0, 0, NULL + }, + { GNOME_APP_UI_ITEM, + N_("Delete"), + N_("Delete selected account"), + gnc_acct_tree_window_toolbar_delete_account_cb, + win, + NULL, + GNOME_APP_PIXMAP_STOCK, + GNOME_STOCK_PIXMAP_REMOVE, + 0, 0, NULL + }, + GNOMEUIINFO_END + }; + + child->toolbar_info = + g_memdup(toolbar_template, sizeof(toolbar_template)); + child->toolbar_size = sizeof(toolbar_template) / sizeof(GnomeUIInfo); +} + +void +gnc_acct_tree_window_create_menu(GNCAcctTreeWin * main_info, + GNCMainChildInfo * child) { + GnomeUIInfo scrubmenu[] = + { + { + GNOME_APP_UI_ITEM, + N_("Scrub A_ccount"), + N_("Identify and fix problems in the account"), + gnc_acct_tree_window_menu_scrub_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("Scrub Su_baccounts"), + N_("Identify and fix problems in the account " + "and its subaccounts"), + gnc_acct_tree_window_menu_scrub_sub_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("Scrub A_ll"), + N_("Identify and fix problems in all the accounts"), + gnc_acct_tree_window_menu_scrub_all_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + GNOMEUIINFO_END + }; + GnomeUIInfo * dup_scrub = g_memdup(scrubmenu, sizeof(scrubmenu)); + + GnomeUIInfo accountsmenu[] = + { + { + GNOME_APP_UI_ITEM, + N_("_Open Account"), + N_("Open the selected account"), + gnc_acct_tree_window_menu_open_cb, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN, + 'o', GDK_CONTROL_MASK, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("Open S_ubaccounts"), + N_("Open the selected account and all its subaccounts"), + gnc_acct_tree_window_menu_open_subs_cb, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN, + 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("_Edit Account"), + N_("Edit the selected account"), + gnc_acct_tree_window_menu_edit_cb, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PROP, + 'e', GDK_CONTROL_MASK, NULL + }, + GNOMEUIINFO_SEPARATOR, + { + GNOME_APP_UI_ITEM, + N_("_Reconcile..."), + N_("Reconcile the selected account"), + gnc_acct_tree_window_menu_reconcile_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 'r', GDK_CONTROL_MASK, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("_Transfer..."), + N_("Transfer funds from one account to another"), + gnc_acct_tree_window_menu_transfer_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 't', GDK_CONTROL_MASK, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("Stock S_plit..."), + N_("Record a stock split or a stock merger"), + gnc_acct_tree_window_menu_stock_split_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + GNOMEUIINFO_SEPARATOR, + { + GNOME_APP_UI_ITEM, + N_("_New Account..."), + N_("Create a new account"), + gnc_acct_tree_window_menu_add_account_cb, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_ADD, + 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("_Delete Account"), + N_("Delete selected account"), + gnc_acct_tree_window_menu_delete_account_cb, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_REMOVE, + 0, 0, NULL + }, + GNOMEUIINFO_SEPARATOR, + GNOMEUIINFO_SUBTREE(N_("_Scrub"), dup_scrub), + GNOMEUIINFO_SEPARATOR, + { + GNOME_APP_UI_ITEM, + N_("Tax Information"), + N_("Setup tax information for all income and expense accounts"), + gnc_acct_tree_window_menu_tax_info_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + GNOMEUIINFO_END + }; + GnomeUIInfo * dup_accts = g_memdup(accountsmenu, sizeof(accountsmenu)); + + GnomeUIInfo menucontainer[] = + { + GNOMEUIINFO_SUBTREE(N_("_Account"), dup_accts), + GNOMEUIINFO_END + }; + + child->menu_info = + g_memdup(menucontainer, sizeof(menucontainer)); + +} + + +/******************************************************************** + * gnc_acct_tree_window_set_sensitives + * set account-related buttons/menus sensitivities + ********************************************************************/ + +static void +gnc_acct_tree_window_set_sensitives(GNCAcctTreeWin * win, + gboolean sensitive) { +#warning "b0rken set_sensitives in account" +} + +static void +gnc_acct_tree_window_select_cb(GNCMainWinAccountTree *tree, + Account *account, + GNCAcctTreeWin * win) { + gboolean sensitive; + + account = gnc_mainwin_account_tree_get_current_account(tree); + sensitive = (account != NULL); + + gnc_acct_tree_window_set_sensitives + (gtk_object_get_user_data(GTK_OBJECT(tree)), sensitive); +} + + +Account * +gnc_acct_tree_window_get_current_account(GNCAcctTreeWin * win) { + return gnc_mainwin_account_tree_get_current_account + (GNC_MAINWIN_ACCOUNT_TREE(win->account_tree)); +} + + +static void +gnc_acct_tree_window_options_new(GNCAcctTreeWin * win) { + SCM func = gh_eval_str("gnc:make-new-acct-tree-window"); + SCM opts_and_id = gh_call0(func); + + scm_unprotect_object(win->options); + win->options = gh_car(opts_and_id); + scm_protect_object(win->options); + win->options_id = gh_scm2int(gh_cdr(opts_and_id)); +} + +void +gnc_acct_tree_window_destroy(GNCAcctTreeWin * win) { + SCM free_tree = gh_eval_str("gnc:free-acct-tree-window"); + gnc_unregister_option_change_callback_id + (win->euro_change_callback_id); + + g_list_free(win->account_sensitives); + win->account_sensitives = NULL; + + gnc_option_db_destroy(win->odb); + + gh_call1(free_tree, gh_int2scm(win->options_id)); + + scm_unprotect_object(win->options); + g_free (win); +} + + +GNCAcctTreeWin * +gnc_acct_tree_window_new(const gchar * url) { + GNCAcctTreeWin * treewin = g_new0(GNCAcctTreeWin, 1); + SCM find_options = gh_eval_str("gnc:find-acct-tree-window-options"); + SCM temp; + int options_id; + URLType type; + char * location; + char * label; + + treewin->euro_change_callback_id = + gnc_register_option_change_callback(gnc_euro_change, treewin, + "International", + "Enable EURO support"); + treewin->account_tree = gnc_mainwin_account_tree_new(); + treewin->options = SCM_BOOL_F; + scm_protect_object(treewin->options); + + /* get the options and the window ID */ + if(!url) { + gnc_acct_tree_window_options_new(treewin); + } + else { + /* if an URL is specified, it should look like + * gnc-acct-tree:id=17 . We want to get the number out, + * then look up the options in the global DB. */ + type = gnc_html_parse_url(NULL, url, &location, &label); + if((type == URL_TYPE_ACCTTREE) && + location && (strlen(location) > 3) && + !strncmp("id=", location, 3)) { + sscanf(location+3, "%d", &options_id); + temp = gh_call1(find_options, gh_int2scm(options_id)); + + if(temp != SCM_BOOL_F) { + scm_unprotect_object(treewin->options); + treewin->options = temp; + scm_protect_object(treewin->options); + treewin->options_id = options_id; + } + else { + gnc_acct_tree_window_options_new(treewin); + } + } + else { + gnc_acct_tree_window_options_new(treewin); + } + } + + treewin->odb = gnc_option_db_new(treewin->options); + + gtk_signal_connect(GTK_OBJECT(treewin->account_tree), "activate_account", + GTK_SIGNAL_FUNC (gnc_acct_tree_window_activate_cb), + treewin); + + gtk_signal_connect(GTK_OBJECT(treewin->account_tree), "select_account", + GTK_SIGNAL_FUNC(gnc_acct_tree_window_select_cb), + treewin); + + gtk_signal_connect(GTK_OBJECT(treewin->account_tree), "unselect_account", + GTK_SIGNAL_FUNC(gnc_acct_tree_window_select_cb), + treewin); + + /* Show everything now that it is created */ + gtk_widget_show (treewin->account_tree); + + gnc_acct_tree_window_configure (treewin); + + /* gnc_refresh_main_window (); */ + gnc_account_tree_refresh + (GNC_MAINWIN_ACCOUNT_TREE (treewin->account_tree)->acc_tree); + + gnc_acct_tree_window_set_sensitives(treewin, FALSE); + + gtk_widget_grab_focus(treewin->account_tree); + return treewin; +} + +GtkWidget * +gnc_acct_tree_window_get_widget(GNCAcctTreeWin * win) { + return win->account_tree; +} + + +/******************************************************************** + * parameter editor handling + ********************************************************************/ + +struct acct_tree_params_data { + GNCOptionWin * win; + GNCOptionDB * db; + SCM scm_options; +}; + + +static void +gnc_options_dialog_apply_cb(GNCOptionWin * propertybox, + gpointer user_data) { + GNCAcctTreeWin * win = user_data; + if(!win) return; + + gnc_option_db_commit(win->odb); + gnc_acct_tree_window_configure(win); +} + +static void +gnc_options_dialog_help_cb(GNCOptionWin * propertybox, + gpointer user_data) { + gnome_ok_dialog("Set the account tree options you want using this dialog."); +} + +static void +gnc_options_dialog_close_cb(GNCOptionWin * propertybox, + gpointer user_data) { + struct acct_tree_params_data * win = user_data; + scm_unprotect_object(win->scm_options); + gnc_options_dialog_destroy(win->win); + g_free(win); +} + + +void +gnc_acct_tree_window_toolbar_options_cb(GtkWidget * widget, gpointer data) { + GNCAcctTreeWin * win = data; + + struct acct_tree_params_data * prm = + g_new0(struct acct_tree_params_data, 1); + + prm->scm_options = win->options; + prm->db = win->odb; + + prm->win = gnc_options_dialog_new(TRUE); + + scm_protect_object(prm->scm_options); + + gnc_build_options_dialog_contents(prm->win, prm->db); + gnc_options_dialog_set_apply_cb(prm->win, + gnc_options_dialog_apply_cb, + (gpointer)win); + gnc_options_dialog_set_help_cb(prm->win, + gnc_options_dialog_help_cb, + (gpointer)prm); + gnc_options_dialog_set_close_cb(prm->win, + gnc_options_dialog_close_cb, + (gpointer)prm); + +} + + + diff --git a/src/gnome/window-acct-tree.h b/src/gnome/window-acct-tree.h new file mode 100644 index 0000000000..bab5583f79 --- /dev/null +++ b/src/gnome/window-acct-tree.h @@ -0,0 +1,41 @@ +/******************************************************************** + * window-acct-tree.h -- public account-tree-window functions * + * Copyright (C) 1998,1999 Linas Vepstas * + * Copyright (C) 2001 Bill Gribble * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + ********************************************************************/ + +#ifndef __WINDOW_ACCT_TREE_H__ +#define __WINDOW_ACCT_TREE_H__ + +#include "mainwindow-account-tree.h" +#include "window-main.h" + +typedef struct GNCAcctTreeWin_p GNCAcctTreeWin; + +GNCAcctTreeWin * gnc_acct_tree_window_new(const gchar * url); +void gnc_acct_tree_window_destroy(GNCAcctTreeWin * win); +GtkWidget * gnc_acct_tree_window_get_widget(GNCAcctTreeWin * win); +void gnc_acct_tree_window_create_menu(GNCAcctTreeWin * win, + GNCMainChildInfo * child); +void gnc_acct_tree_window_create_toolbar(GNCAcctTreeWin * win, + GNCMainChildInfo * child); +Account * gnc_acct_tree_window_get_current_account(GNCAcctTreeWin * w); +GnomeMDIChild * gnc_acct_tree_window_create_child(const gchar * url); +void gnc_main_window_open_accounts(gint toplevel); +#endif diff --git a/src/gnome/window-main-summarybar.c b/src/gnome/window-main-summarybar.c new file mode 100644 index 0000000000..428a2dde5a --- /dev/null +++ b/src/gnome/window-main-summarybar.c @@ -0,0 +1,495 @@ +/******************************************************************** + * window-main-summarybar.c -- summary of financial info * + * Copyright (C) 1998,1999 Jeremy Collins * + * Copyright (C) 1998,1999,2000 Linas Vepstas * + * Copyright (C) 2001 Bill Gribble * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + ********************************************************************/ + +#include "config.h" + +#include +#include +#include + +#include "window-main.h" +#include "window-main-summarybar.h" +#include "dialog-utils.h" +#include "gnc-component-manager.h" +#include "gnc-engine-util.h" +#include "gnc-ui-util.h" +#include "gnc-ui.h" +#include "top-level.h" +#include "gtkselect.h" +#include "global-options.h" +#include "option-util.h" +#include "EuroUtils.h" +#include "FileDialog.h" +#include "Account.h" +#include "Group.h" + +typedef struct { + GtkWidget * hbox; + GtkWidget * totals_combo; + GList * totals_list; + int component_id; +} GNCMainSummary; + +#define WINDOW_SUMMARYBAR_CM_CLASS "summary-bar" + +/* An accumulator for a given currency. + * + * This is used during the update to the status bar to contain the + * accumulation for a single currency. These are placed in a GList and + * kept around for the duration of the calculation. There may, in fact + * be better ways to do this, but none occurred. */ + +typedef struct { + gnc_commodity * currency; + gnc_numeric assets; + gnc_numeric profits; +} GNCCurrencyAcc; + + +/* An item to appear in the selector box in the status bar. + * + * This is maintained for the duration, where there is one per + * currency, plus (eventually) one for the default currency + * accumulation (like the EURO). */ + +typedef struct { + char *namespace; + char *mnemonic; + GtkWidget *listitem; + GtkWidget *assets_label; + GtkWidget *profits_label; + gint touched : 1; +} GNCCurrencyItem; + + +/* Build a single currency item. + * + * This function handles the building of a single currency item for + * the selector. It looks like the old code in the update function, + * but now only handles a single currency. */ + +static GNCCurrencyItem * +gnc_ui_build_currency_item(gnc_commodity * currency) +{ + GtkWidget *label; + GtkWidget *topbox; + GtkWidget *hbox; + GtkWidget *listitem; + GNCCurrencyItem *item; + const char *mnemonic; + char *label_str; + + item = g_new0 (GNCCurrencyItem, 1); + + item->namespace = g_strdup (gnc_commodity_get_namespace (currency)); + item->mnemonic = g_strdup (gnc_commodity_get_mnemonic (currency)); + + listitem = gtk_list_item_new(); + item->listitem = listitem; + + topbox = gtk_hbox_new(FALSE, 2); + gtk_widget_show(topbox); + gtk_container_add(GTK_CONTAINER(listitem), topbox); + + mnemonic = gnc_commodity_get_mnemonic (currency); + + hbox = gtk_hbox_new(FALSE, 2); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(topbox), hbox, FALSE, FALSE, 5); + + label_str = g_strdup_printf ("%s (%s):", _("Net Assets"), mnemonic); + label = gtk_label_new(label_str); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + g_free (label_str); + + label = gtk_label_new(""); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_widget_show(label); + item->assets_label = label; + + hbox = gtk_hbox_new(FALSE, 2); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(topbox), hbox, FALSE, FALSE, 5); + + label_str = g_strdup_printf ("%s (%s):", _("Profits"), mnemonic); + label = gtk_label_new(label_str); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + g_free (label_str); + + label = gtk_label_new(""); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_widget_show(label); + gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 0); + item->profits_label = label; + + gtk_widget_show(item->listitem); + + return item; +} + +static void +gnc_ui_currency_item_destroy (GNCCurrencyItem *item) +{ + if (!item) return; + + g_free (item->namespace); + g_free (item->mnemonic); + + item->namespace = NULL; + item->mnemonic = NULL; + + g_free (item); +} + +/* Get a currency accumulator. + * + * This will search the given list, and if no accumulator is found, + * will allocate a fresh one. */ +static GNCCurrencyAcc * +gnc_ui_get_currency_accumulator(GList **list, gnc_commodity * currency) +{ + GList *current; + GNCCurrencyAcc *found; + + for (current = g_list_first(*list); current; + current = g_list_next(current)) { + found = current->data; + if (gnc_commodity_equiv(currency, found->currency)) { + return found; + } + } + + found = g_new0 (GNCCurrencyAcc, 1); + found->currency = currency; + found->assets = gnc_numeric_zero (); + found->profits = gnc_numeric_zero (); + *list = g_list_append (*list, found); + + return found; +} + +static gboolean +gnc_ui_currency_item_match (const GNCCurrencyItem *item, + const gnc_commodity *commodity) +{ + if (!item || !commodity) return FALSE; + + return + (safe_strcmp (item->namespace, + gnc_commodity_get_namespace (commodity)) == 0) && + (safe_strcmp (item->mnemonic, + gnc_commodity_get_mnemonic (commodity)) == 0); + +} + +/* Get a currency item. + * + * This will search the given list, and if no accumulator is found, will + * create a fresh one. + * + * It looks just like the function above, with some extra stuff to get + * the item into the list. */ + +static GNCCurrencyItem * +gnc_ui_get_currency_item (GList **list, + gnc_commodity * currency, + GtkWidget *holder) +{ + GList *current; + GNCCurrencyItem *found; + + for (current = g_list_first(*list); current; + current = g_list_next(current)) + { + found = current->data; + + if (gnc_ui_currency_item_match (found, currency)) + return found; + } + + found = gnc_ui_build_currency_item(currency); + *list = g_list_append(*list, found); + + current = g_list_append(NULL, found->listitem); + gtk_select_append_items(GTK_SELECT(holder), current); + + return found; +} + +static void +gnc_ui_accounts_recurse (AccountGroup *group, GList **currency_list, + gboolean euro) +{ + gnc_numeric amount; + AccountGroup *children; + GNCAccountType account_type; + gnc_commodity * account_currency; + gnc_commodity * default_currency; + gnc_commodity * euro_commodity; + GNCCurrencyAcc *currency_accum; + GNCCurrencyAcc *euro_accum = NULL; + GList *list; + GList *node; + + default_currency = + gnc_lookup_currency_option("International", + "Default Currency", + gnc_locale_default_currency ()); + + if (euro) + { + euro_commodity = gnc_get_euro (); + euro_accum = gnc_ui_get_currency_accumulator(currency_list, + euro_commodity); + } + else + euro_commodity = NULL; + + list = xaccGroupGetAccountList (group); + for (node = list; node; node = node->next) + { + Account *account = node->data; + + account_type = xaccAccountGetType(account); + account_currency = xaccAccountGetCurrency(account); + children = xaccAccountGetChildren(account); + currency_accum = gnc_ui_get_currency_accumulator(currency_list, + account_currency); + + switch (account_type) + { + case BANK: + case CASH: + case ASSET: + case STOCK: + case MUTUAL: + case CREDIT: + case LIABILITY: + amount = xaccAccountGetBalance(account); + currency_accum->assets = + gnc_numeric_add (currency_accum->assets, amount, + gnc_commodity_get_fraction (account_currency), + GNC_RND_ROUND); + + if (euro) + euro_accum->assets = + gnc_numeric_add (euro_accum->assets, + gnc_convert_to_euro(account_currency, amount), + gnc_commodity_get_fraction (euro_commodity), + GNC_RND_ROUND); + + if (children != NULL) + gnc_ui_accounts_recurse(children, currency_list, euro); + break; + case INCOME: + case EXPENSE: + amount = xaccAccountGetBalance(account); + currency_accum->profits = + gnc_numeric_sub (currency_accum->profits, amount, + gnc_commodity_get_fraction (account_currency), + GNC_RND_ROUND); + + if (euro) + gnc_numeric_sub (euro_accum->profits, + gnc_convert_to_euro(account_currency, amount), + gnc_commodity_get_fraction (euro_commodity), + GNC_RND_ROUND); + + if (children != NULL) + gnc_ui_accounts_recurse(children, currency_list, euro); + break; + case EQUITY: + /* no-op, see comments at top about summing assets */ + break; + case CURRENCY: + default: + break; + } + } +} + +/* The gnc_main_window_summary_refresh() subroutine redraws summary + * information. The statusbar includes two fields, titled 'profits' + * and 'assets'. The total assets equal the sum of all of the + * non-equity, non-income accounts. In theory, assets also equals the + * grand total value of the equity accounts, but that assumes that + * folks are using the equity account type correctly (which is not + * likely). Thus we show the sum of assets, rather than the sum of + * equities. + * + * The EURO gets special treatment. There can be one line with + * EUR amounts and a EUR (total) line which summs up all EURO + * member currencies. + * + * There should be a 'grand total', too, which sums up all accounts + * converted to one common currency. */ + +static void +gnc_main_window_summary_refresh (GNCMainSummary * summary) +{ + AccountGroup *group; + char asset_string[256]; + char profit_string[256]; + gnc_commodity * default_currency; + GNCCurrencyAcc *currency_accum; + GNCCurrencyItem *currency_item; + GList *currency_list; + GList *current; + gboolean euro; + + default_currency = + gnc_lookup_currency_option("International", + "Default Currency", + gnc_locale_default_currency ()); + + euro = gnc_lookup_boolean_option("International", + "Enable EURO support", + FALSE); + + currency_list = NULL; + + /* Make sure there's at least one accumulator in the list. */ + gnc_ui_get_currency_accumulator (¤cy_list, default_currency); + + group = gncGetCurrentGroup (); + gnc_ui_accounts_recurse(group, ¤cy_list, euro); + + for (current = g_list_first(summary->totals_list); current; + current = g_list_next(current)) { + currency_item = current->data; + currency_item->touched = 0; + } + + for (current = g_list_first(currency_list); current; + current = g_list_next(current)) { + currency_accum = current->data; + currency_item = gnc_ui_get_currency_item(&summary->totals_list, + currency_accum->currency, + summary->totals_combo); + currency_item->touched = 1; + + *asset_string= '\0'; + xaccSPrintAmount(asset_string, currency_accum->assets, + gnc_commodity_print_info(currency_accum->currency, TRUE)); + gtk_label_set_text(GTK_LABEL(currency_item->assets_label), asset_string); + gnc_set_label_color(currency_item->assets_label, currency_accum->assets); + + *profit_string= '\0'; + xaccSPrintAmount(profit_string, currency_accum->profits, + gnc_commodity_print_info(currency_accum->currency, TRUE)); + gtk_label_set_text(GTK_LABEL(currency_item->profits_label), profit_string); + gnc_set_label_color(currency_item->profits_label, currency_accum->profits); + + g_free(currency_accum); + current->data = NULL; + } + + g_list_free(currency_list); + currency_list = NULL; + + current = g_list_first(summary->totals_list); + while (current) { + GList *next = current->next; + + currency_item = current->data; + if (currency_item->touched == 0 && + !gnc_ui_currency_item_match(currency_item, default_currency)) { + currency_list = g_list_prepend(currency_list, currency_item->listitem); + summary->totals_list = g_list_remove_link(summary->totals_list, + current); + gnc_ui_currency_item_destroy(currency_item); + current->data = NULL; + g_list_free_1(current); + } + + current = next; + } + + if (currency_list) { + gtk_select_remove_items(GTK_SELECT(summary->totals_combo), + currency_list); + g_list_free(currency_list); + } +} + +static void +gnc_main_window_summary_destroy_cb(GtkObject * obj, gpointer data) { + GNCMainSummary * summary = data; + gnc_unregister_gui_component(summary->component_id); + g_list_free(summary->totals_list); + g_free(summary); +} + +static void +summarybar_refresh_handler(GHashTable * changes, gpointer user_data) { + GNCMainSummary * summary = user_data; + gnc_main_window_summary_refresh(summary); +} + +GtkWidget * +gnc_main_window_summary_new () { + GNCMainSummary * retval = g_new0(GNCMainSummary, 1); + GtkWidget * summarybar; + GNCCurrencyItem * def_item; + gnc_commodity * default_currency = + gnc_lookup_currency_option ("International", + "Default Currency", + gnc_locale_default_currency ()); + + retval->hbox = gtk_hbox_new (FALSE, 5); + retval->totals_combo = gtk_select_new (); + retval->totals_list = NULL; + retval->component_id = gnc_register_gui_component(WINDOW_SUMMARYBAR_CM_CLASS, + summarybar_refresh_handler, + retval, retval); + gnc_gui_component_watch_entity_type (retval->component_id, + GNC_ID_ACCOUNT, + GNC_EVENT_MODIFY | GNC_EVENT_DESTROY); + + def_item = gnc_ui_get_currency_item (&retval->totals_list, + default_currency, + retval->totals_combo); + + + gtk_container_set_border_width (GTK_CONTAINER (retval->hbox), 2); + gtk_select_select_child (GTK_SELECT(retval->totals_combo), + def_item->listitem); + gtk_box_pack_start (GTK_BOX(retval->hbox), retval->totals_combo, + FALSE, FALSE, 5); + gtk_widget_show (retval->totals_combo); + gtk_widget_show (retval->hbox); + + gtk_signal_connect(GTK_OBJECT(retval->hbox), "destroy", + gnc_main_window_summary_destroy_cb, retval); + + gnc_main_window_summary_refresh(retval); + + return retval->hbox; +} + diff --git a/src/MainWindow.h b/src/gnome/window-main-summarybar.h similarity index 53% rename from src/MainWindow.h rename to src/gnome/window-main-summarybar.h index 660613e25b..644080489b 100644 --- a/src/MainWindow.h +++ b/src/gnome/window-main-summarybar.h @@ -1,8 +1,7 @@ -/********************************************************************\ - * MainWindow.h -- the main window, and associated helper functions * - * and callback functions for GnuCash * - * Copyright (C) 1997 Robin D. Clark * - * Copyright (C) 2000 Dave Peticolas * +/******************************************************************** + * window-main-summarybar.h -- summary of finances in main window * + * Copyright (C) 1998,1999 Linas Vepstas * + * Copyright (C) 2001 Bill Gribble * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -15,20 +14,18 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License* - * along with this program; if not, write to the Free Software * - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * + * along with this program; if not, contact: * * * - * Author: Rob Clark * - * Internet: rclark@cs.hmc.edu * - * Address: 609 8th Street * - * Huntington Beach, CA 92648-4632 * -\********************************************************************/ + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + ********************************************************************/ -#ifndef __MAIN_WINDOW_H__ -#define __MAIN_WINDOW_H__ +#ifndef WINDOW_MAIN_SUMMARYBAR_H +#define WINDOW_MAIN_SUMMARYBAR_H -/** PROTOTYPES ******************************************************/ +#include -void mainWindow(); +GtkWidget * gnc_main_window_summary_new(void); #endif diff --git a/src/gnome/window-main.c b/src/gnome/window-main.c index d4b80fb896..4f3d060e03 100644 --- a/src/gnome/window-main.c +++ b/src/gnome/window-main.c @@ -1,9 +1,9 @@ -/********************************************************************\ - * window-main.c -- the main window, and associated helper functions* - * and callback functions for GnuCash * +/******************************************************************** + * window-main.c -- open/close/configure GNOME MDI main window * * Copyright (C) 1998,1999 Jeremy Collins * * Copyright (C) 1998,1999,2000 Linas Vepstas * * Copyright (C) 2001 Bill Gribble * + * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * @@ -20,7 +20,7 @@ * Free Software Foundation Voice: +1-617-542-5942 * * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * * Boston, MA 02111-1307, USA gnu@gnu.org * -\********************************************************************/ + ********************************************************************/ #include "config.h" @@ -28,14 +28,14 @@ #include #include -#include "AccWindow.h" -#include "EuroUtils.h" +#include "gnucash.h" +#include "gnc-ui.h" +#include "top-level.h" +#include "extensions.h" + #include "FileBox.h" #include "FileDialog.h" -#include "MainWindow.h" -#include "RegWindow.h" -#include "Scrub.h" -#include "account-tree.h" + #include "dialog-account.h" #include "dialog-fincalc.h" #include "dialog-find-transactions.h" @@ -43,777 +43,403 @@ #include "dialog-totd.h" #include "dialog-transfer.h" #include "dialog-utils.h" -#include "file-history.h" -#include "global-options.h" -#include "gnc-commodity.h" -#include "gnc-component-manager.h" -#include "gnc-engine-util.h" -#include "gnc-engine.h" -#include "gnc-ui.h" -#include "gnucash.h" -#include "gtkselect.h" -#include "messages.h" -#include "mainwindow-account-tree.h" + #include "window-help.h" #include "window-main.h" +#include "window-main-summarybar.h" +#include "window-acct-tree.h" #include "window-reconcile.h" #include "window-register.h" #include "window-report.h" -#include "io-gncxml-v2.h" -#include "gnc-book.h" - -/* FIXME get rid of these */ -#include "gnc.h" +#include "mainwindow-account-tree.h" +#include "gnc-component-manager.h" +#include "option-util.h" +#include "global-options.h" +#include "query-user.h" #define WINDOW_MAIN_CM_CLASS "window-main" -/* Main Window information structure */ -typedef struct _GNCMainInfo GNCMainInfo; -struct _GNCMainInfo -{ - GtkWidget *account_tree; - GtkWidget *totals_combo; - GtkWidget *notebook; - GList *totals_list; +static void gnc_main_window_create_menus(GNCMainInfo * maininfo); - SCM main_window_change_callback_id; - SCM euro_change_callback_id; - SCM toolbar_change_callback_id; - - GList *account_sensitives; - - gint component_id; -}; - -/* This static indicates the debugging module that this .o belongs to. */ -static short module = MOD_GUI; - -/* Codes for the file menu */ -enum { - FMB_NEW, - FMB_OPEN, - FMB_IMPORT, - FMB_SAVE, - FMB_SAVEAS, - FMB_QUIT, -}; - -/** Static function declarations ***************************************/ -static GNCMainInfo * gnc_get_main_info(void); - - -/* An accumulator for a given currency. - * - * This is used during the update to the status bar to contain the - * accumulation for a single currency. These are placed in a GList and - * kept around for the duration of the calculation. There may, in fact - * be better ways to do this, but none occurred. */ -struct _GNCCurrencyAcc { - gnc_commodity * currency; - gnc_numeric assets; - gnc_numeric profits; -}; -typedef struct _GNCCurrencyAcc GNCCurrencyAcc; - -/* An item to appear in the selector box in the status bar. - * - * This is maintained for the duration, where there is one per - * currency, plus (eventually) one for the default currency - * accumulation (like the EURO). */ -struct _GNCCurrencyItem { - char *namespace; - char *mnemonic; - GtkWidget *listitem; - GtkWidget *assets_label; - GtkWidget *profits_label; - gint touched : 1; -}; -typedef struct _GNCCurrencyItem GNCCurrencyItem; - -/* Build a single currency item. - * - * This function handles the building of a single currency item for the - * selector. It looks like the old code in the update function, but now - * only handles a single currency. - */ -static GNCCurrencyItem * -gnc_ui_build_currency_item(gnc_commodity * currency) -{ - GtkWidget *label; - GtkWidget *topbox; - GtkWidget *hbox; - GtkWidget *listitem; - GNCCurrencyItem *item; - const char *mnemonic; - char *label_str; - - item = g_new0 (GNCCurrencyItem, 1); - - item->namespace = g_strdup (gnc_commodity_get_namespace (currency)); - item->mnemonic = g_strdup (gnc_commodity_get_mnemonic (currency)); - - listitem = gtk_list_item_new(); - item->listitem = listitem; - - topbox = gtk_hbox_new(FALSE, 2); - gtk_widget_show(topbox); - gtk_container_add(GTK_CONTAINER(listitem), topbox); - - mnemonic = gnc_commodity_get_mnemonic (currency); - - hbox = gtk_hbox_new(FALSE, 2); - gtk_widget_show(hbox); - gtk_box_pack_start(GTK_BOX(topbox), hbox, FALSE, FALSE, 5); - - label_str = g_strdup_printf ("%s (%s):", _("Net Assets"), mnemonic); - label = gtk_label_new(label_str); - gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - g_free (label_str); - - label = gtk_label_new(""); - gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 0); - gtk_widget_show(label); - item->assets_label = label; - - hbox = gtk_hbox_new(FALSE, 2); - gtk_widget_show(hbox); - gtk_box_pack_start(GTK_BOX(topbox), hbox, FALSE, FALSE, 5); - - label_str = g_strdup_printf ("%s (%s):", _("Profits"), mnemonic); - label = gtk_label_new(label_str); - gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - g_free (label_str); - - label = gtk_label_new(""); - gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_widget_show(label); - gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 0); - item->profits_label = label; - - gtk_widget_show(item->listitem); - - return item; -} +/******************************************************************** + * gnc_main_window_destroy_cb() + * Shut down the Gnucash ui windows + ********************************************************************/ static void -gnc_ui_currency_item_destroy (GNCCurrencyItem *item) -{ - if (!item) return; - - g_free (item->namespace); - g_free (item->mnemonic); - - item->namespace = NULL; - item->mnemonic = NULL; - - g_free (item); +gnc_main_window_destroy_cb(GtkObject * w) { + gnc_ui_destroy(); } -/* Get a currency accumulator. - * - * This will search the given list, and if no accumulator is found, - * will allocate a fresh one. */ -static GNCCurrencyAcc * -gnc_ui_get_currency_accumulator(GList **list, gnc_commodity * currency) -{ - GList *current; - GNCCurrencyAcc *found; - for (current = g_list_first(*list); current; - current = g_list_next(current)) { - found = current->data; - if (gnc_commodity_equiv(currency, found->currency)) { - return found; +/******************************************************************** + * gnc_main_window_remove_view_cb() + * we only have one view per child, so destroy the child + ********************************************************************/ + +static gint +gnc_main_window_remove_view_cb(GnomeMDI * mdi, GnomeMDIChild * child, + gpointer data) { + GNCMainInfo * mainwin = data; + gtk_object_destroy(GTK_OBJECT(child)); + return TRUE; +} + +/******************************************************************** + * gnc_main_window_app_created_cb() + * called when a new top-level GnomeApp is created. + ********************************************************************/ + +static void +gnc_main_window_app_created_cb(GnomeMDI * mdi, GnomeApp * app, + gpointer data) { + GNCMainInfo * mainwin = data; + GtkWidget * summarybar; + GtkWidget * statusbar; + + /* add the summarybar */ + summarybar = gnc_main_window_summary_new(); + gnome_app_add_docked(GNOME_APP(app), summarybar, "Summary Bar", + GNOME_DOCK_ITEM_BEH_EXCLUSIVE, + GNOME_DOCK_TOP, 2, 0, 0); + + /* add the statusbar */ + statusbar = gnome_appbar_new(FALSE, TRUE, GNOME_PREFERENCES_USER); + gnome_app_set_statusbar(app, statusbar); + + /* set up extensions menu and hints */ + gnc_extensions_menu_setup(app); +} + + +/******************************************************************** + * gnc_main_window_child_changed_cb() + * called when the active child changes. Not sure what this means + * with top-level windows. focus, maybe? + ********************************************************************/ + +static void +gnc_main_window_child_changed_cb(GnomeMDI * mdi, GnomeMDIChild * oldchild, + gpointer data) { + GNCMainInfo * mainwin = data; + GNCMainChildInfo * childwin = + gtk_object_get_user_data(GTK_OBJECT(mdi->active_child)); + GNCMainChildInfo * oldchildwin; + GnomeUIInfo * hintinfo; + GnomeApp * new_app = gnome_mdi_get_app_from_view(childwin->contents); + + /* hide the old toolbar, if needed */ + if(oldchild) { + oldchildwin = gtk_object_get_user_data(GTK_OBJECT(oldchild)); + if(oldchildwin && oldchildwin->toolbar && + (oldchildwin->app == new_app)) { + gtk_widget_hide(GTK_WIDGET(oldchildwin->toolbar)->parent); + } + } + + /* show the new one */ + if(childwin && childwin->toolbar) { + if(childwin->app) { + gtk_widget_show(GTK_WIDGET(childwin->toolbar)->parent); + } + else { + childwin->app = new_app; + gnome_app_add_toolbar(GNOME_APP(childwin->app), + GTK_TOOLBAR(childwin->toolbar), + "Toolbar", GNOME_DOCK_ITEM_BEH_NORMAL, + GNOME_DOCK_TOP, 1, 0, 0); + gtk_toolbar_set_style(GTK_TOOLBAR(childwin->toolbar), + gnc_get_toolbar_style()); } } - found = g_new0 (GNCCurrencyAcc, 1); - found->currency = currency; - found->assets = gnc_numeric_zero (); - found->profits = gnc_numeric_zero (); - *list = g_list_append (*list, found); - - return found; -} - -static gboolean -gnc_ui_currency_item_match (const GNCCurrencyItem *item, - const gnc_commodity *commodity) -{ - if (!item || !commodity) return FALSE; - - return - (safe_strcmp (item->namespace, - gnc_commodity_get_namespace (commodity)) == 0) && - (safe_strcmp (item->mnemonic, - gnc_commodity_get_mnemonic (commodity)) == 0); - -} - -/* Get a currency item. - * - * This will search the given list, and if no accumulator is found, will - * create a fresh one. - * - * It looks just like the function above, with some extra stuff to get - * the item into the list. */ - -static GNCCurrencyItem * -gnc_ui_get_currency_item (GList **list, - gnc_commodity * currency, - GtkWidget *holder) -{ - GList *current; - GNCCurrencyItem *found; - - for (current = g_list_first(*list); current; - current = g_list_next(current)) - { - found = current->data; - - if (gnc_ui_currency_item_match (found, currency)) - return found; - } - - found = gnc_ui_build_currency_item(currency); - *list = g_list_append(*list, found); - - current = g_list_append(NULL, found->listitem); - gtk_select_append_items(GTK_SELECT(holder), current); - - return found; -} - -static void -gnc_ui_accounts_recurse (AccountGroup *group, GList **currency_list, - gboolean euro) -{ - gnc_numeric amount; - AccountGroup *children; - GNCAccountType account_type; - gnc_commodity * account_currency; - gnc_commodity * default_currency; - gnc_commodity * euro_commodity; - GNCCurrencyAcc *currency_accum; - GNCCurrencyAcc *euro_accum = NULL; - GList *list; - GList *node; - - default_currency = - gnc_lookup_currency_option("International", - "Default Currency", - gnc_locale_default_currency ()); - - if (euro) - { - euro_commodity = gnc_get_euro (); - euro_accum = gnc_ui_get_currency_accumulator(currency_list, - euro_commodity); - } - else - euro_commodity = NULL; - - list = xaccGroupGetAccountList (group); - for (node = list; node; node = node->next) - { - Account *account = node->data; - - account_type = xaccAccountGetType(account); - account_currency = xaccAccountGetCurrency(account); - children = xaccAccountGetChildren(account); - currency_accum = gnc_ui_get_currency_accumulator(currency_list, - account_currency); - - switch (account_type) - { - case BANK: - case CASH: - case ASSET: - case STOCK: - case MUTUAL: - case CREDIT: - case LIABILITY: - amount = xaccAccountGetBalance(account); - currency_accum->assets = - gnc_numeric_add (currency_accum->assets, amount, - gnc_commodity_get_fraction (account_currency), - GNC_RND_ROUND); - - if (euro) - euro_accum->assets = - gnc_numeric_add (euro_accum->assets, - gnc_convert_to_euro(account_currency, amount), - gnc_commodity_get_fraction (euro_commodity), - GNC_RND_ROUND); - - if (children != NULL) - gnc_ui_accounts_recurse(children, currency_list, euro); - break; - case INCOME: - case EXPENSE: - amount = xaccAccountGetBalance(account); - currency_accum->profits = - gnc_numeric_sub (currency_accum->profits, amount, - gnc_commodity_get_fraction (account_currency), - GNC_RND_ROUND); - - if (euro) - gnc_numeric_sub (euro_accum->profits, - gnc_convert_to_euro(account_currency, amount), - gnc_commodity_get_fraction (euro_commodity), - GNC_RND_ROUND); - - if (children != NULL) - gnc_ui_accounts_recurse(children, currency_list, euro); - break; - case EQUITY: - /* no-op, see comments at top about summing assets */ - break; - case CURRENCY: - default: - break; - } - } -} - -/* The gnc_ui_refresh_statusbar() subroutine redraws the summary - * information. The statusbar includes two fields, titled 'profits' - * and 'assets'. The total assets equal the sum of all of the - * non-equity, non-income accounts. In theory, assets also equals - * the grand total value of the equity accounts, but that assumes - * that folks are using the equity account type correctly (which is - * not likely). Thus we show the sum of assets, rather than the - * sum of equities. - * - * The EURO gets special treatment. There can be one line with - * EUR amounts and a EUR (total) line which summs up all EURO - * member currencies. - * - * There should be a 'grand total', too, which sums up all accounts - * converted to one common currency. */ -static void -gnc_ui_refresh_statusbar (void) -{ - GNCMainInfo *main_info; - AccountGroup *group; - char asset_string[256]; - char profit_string[256]; - gnc_commodity * default_currency; - GNCCurrencyAcc *currency_accum; - GNCCurrencyItem *currency_item; - GList *currency_list; - GList *current; - gboolean euro; - - default_currency = - gnc_lookup_currency_option("International", - "Default Currency", - gnc_locale_default_currency ()); - - euro = gnc_lookup_boolean_option("International", - "Enable EURO support", - FALSE); - - main_info = gnc_get_main_info(); - if (main_info == NULL) - return; - - currency_list = NULL; - - /* Make sure there's at least one accumulator in the list. */ - gnc_ui_get_currency_accumulator (¤cy_list, default_currency); - - group = gncGetCurrentGroup (); - gnc_ui_accounts_recurse(group, ¤cy_list, euro); - - for (current = g_list_first(main_info->totals_list); current; - current = g_list_next(current)) - { - currency_item = current->data; - currency_item->touched = 0; - } - - for (current = g_list_first(currency_list); current; - current = g_list_next(current)) - { - currency_accum = current->data; - currency_item = gnc_ui_get_currency_item(&main_info->totals_list, - currency_accum->currency, - main_info->totals_combo); - currency_item->touched = 1; - - *asset_string= '\0'; - xaccSPrintAmount(asset_string, currency_accum->assets, - gnc_commodity_print_info(currency_accum->currency, TRUE)); - gtk_label_set_text(GTK_LABEL(currency_item->assets_label), asset_string); - gnc_set_label_color(currency_item->assets_label, currency_accum->assets); - - *profit_string= '\0'; - xaccSPrintAmount(profit_string, currency_accum->profits, - gnc_commodity_print_info(currency_accum->currency, TRUE)); - gtk_label_set_text(GTK_LABEL(currency_item->profits_label), profit_string); - gnc_set_label_color(currency_item->profits_label, currency_accum->profits); - - g_free(currency_accum); - current->data = NULL; - } - - g_list_free(currency_list); - currency_list = NULL; - - current = g_list_first(main_info->totals_list); - while (current) - { - GList *next = current->next; - - currency_item = current->data; - if (currency_item->touched == 0 && - !gnc_ui_currency_item_match(currency_item, default_currency)) - { - currency_list = g_list_prepend(currency_list, currency_item->listitem); - main_info->totals_list = g_list_remove_link(main_info->totals_list, - current); - gnc_ui_currency_item_destroy(currency_item); - current->data = NULL; - g_list_free_1(current); - } - - current = next; - } - - if (currency_list) - { - gtk_select_remove_items(GTK_SELECT(main_info->totals_combo), - currency_list); - g_list_free(currency_list); - } -} - -static void -gnc_refresh_main_window_title (void) -{ - GtkWidget *main_window; - GNCBook *book; - const char *filename; - char *title; - - main_window = gnc_get_ui_data(); - if (main_window == NULL) - return; - - book = gncGetCurrentBook (); - - filename = gnc_book_get_url (book); - - if ((filename == NULL) || (*filename == '\0')) - filename = _("Untitled"); - - title = g_strconcat("GnuCash - ", filename, NULL); - - gtk_window_set_title(GTK_WINDOW(main_window), title); - - g_free(title); -} - -static void -gnc_refresh_main_window (void) -{ - gnc_ui_refresh_statusbar (); - gnc_history_update_menu (); - gnc_refresh_main_window_title (); -} - -static void -gnc_ui_find_transactions_cb (GtkWidget *widget, gpointer data) -{ - gnc_ui_find_transactions_dialog_create(NULL); -} - - -static void -gnc_ui_exit_cb (GtkWidget *widget, gpointer data) -{ - gnc_shutdown (0); -} - -static void -gnc_ui_about_cb (GtkWidget *widget, gpointer data) -{ - GtkWidget *about; - const gchar *message = _("The GnuCash personal finance manager.\n" - "The GNU way to manage your money!"); - const gchar *copyright = "(C) 1998-2001 Linas Vepstas"; - const gchar *authors[] = { - "Linas Vepstas ", - NULL - }; - - about = gnome_about_new ("GnuCash", VERSION, copyright, - authors, message, NULL); - gnome_dialog_set_parent (GNOME_DIALOG(about), - GTK_WINDOW(gnc_get_ui_data ())); - - gnome_dialog_run_and_close (GNOME_DIALOG(about)); -} - -static void -gnc_ui_totd_cb (GtkWidget *widget, gpointer data) -{ - gnc_ui_totd_dialog_create_and_run(); - return; -} + /* install menu hints if relevant */ + if(mdi->active_child) { -static void -gnc_ui_help_cb (GtkWidget *widget, gpointer data) -{ - helpWindow(NULL, NULL, HH_MAIN); -} - -static void -gnc_ui_add_account (GtkWidget *widget, gpointer data) -{ - gnc_ui_new_account_window (NULL); -} - -static void -gnc_ui_delete_account (Account *account) -{ - gnc_suspend_gui_refresh (); - - xaccAccountBeginEdit (account); - xaccAccountDestroy (account); - - gnc_resume_gui_refresh (); -} - -static void -gnc_ui_delete_account_cb (GtkWidget *widget, gpointer data) -{ - Account *account = gnc_get_current_account(); - - if (account) - { - const char *format = _("Are you sure you want to delete the %s account?"); - char *message; - char *name; - - name = xaccAccountGetFullName(account, gnc_get_account_separator ()); - message = g_strdup_printf(format, name); - - if (gnc_verify_dialog(message, FALSE)) - gnc_ui_delete_account(account); - - g_free(name); - g_free(message); - } - else - { - const char *message = _("To delete an account, you must first\n" - "choose an account to delete.\n"); - gnc_error_dialog(message); + hintinfo = gnome_mdi_get_menubar_info(new_app); + if(hintinfo) { + gnome_app_install_menu_hints(new_app, hintinfo); + } + + hintinfo = gnome_mdi_get_child_menu_info(new_app); + if(hintinfo) { + gnome_app_install_menu_hints(new_app, hintinfo); + } } } + +/******************************************************************** + * gnc_main_window_view_changed_cb() + * called when the view changes. + ********************************************************************/ + static void -gnc_tax_info_cb (GtkWidget *widget, gpointer data) -{ - gnc_tax_info_dialog (gnc_get_ui_data ()); +gnc_main_window_view_changed_cb(GnomeMDI * mdi, GnomeApp * app, + gpointer data) { + GNCMainInfo * mainwin = data; + /* don't do anything ATM */ } -static void -gnc_ui_mainWindow_toolbar_open (GtkWidget *widget, gpointer data) -{ - RegWindow *regData; - Account *account = gnc_get_current_account(); - if (account == NULL) - { - const char *message = _("To open an account, you must first\n" - "choose an account to open."); - gnc_error_dialog(message); - return; +/******************************************************************** + * gnc_main_window_configure_toolbar_cb + * called when the toolbar button style changes + ********************************************************************/ + +static void +gnc_main_window_configure_toolbar_cb (gpointer data) +{ + GNCMainInfo * mi = data; + GNCMainChildInfo * mc = NULL; + GtkToolbarStyle tbstyle = gnc_get_toolbar_style(); + GList * child; + + for(child = mi->children; child; child = child->next) { + mc = child->data; + if(mc && mc->toolbar) { + gtk_toolbar_set_style(GTK_TOOLBAR(mc->toolbar), tbstyle); + } } - - PINFO ("calling regWindowSimple(%p)\n", account); - - regData = regWindowSimple(account); - gnc_register_raise(regData); } -static void -gnc_ui_mainWindow_toolbar_open_subs(GtkWidget *widget, gpointer data) -{ - RegWindow *regData; - Account *account = gnc_get_current_account(); +/******************************************************************** + * gnc_main_window_create_child() + * open an MDI child given a config string (URL). This is used + ********************************************************************/ + +GnomeMDIChild * +gnc_main_window_create_child(const gchar * configstring) { + URLType type; + char * location; + char * label; - if (account == NULL) - { - const char *message = _("To open an account, you must first\n" - "choose an account to open."); - gnc_error_dialog(message); - return; - } - - PINFO ("calling regWindowAccGroup(%p)\n", account); - - regData = regWindowAccGroup(account); - gnc_register_raise(regData); -} - -static void -gnc_ui_mainWindow_toolbar_edit (GtkWidget *widget, gpointer data) -{ - Account *account = gnc_get_current_account(); - AccountWindow *edit_window_data; + type = gnc_html_parse_url(NULL, configstring, &location, &label); + g_free(location); + g_free(label); - if (account != NULL) - { - edit_window_data = gnc_ui_edit_account_window(account); - gnc_ui_edit_account_window_raise(edit_window_data); - } - else - { - const char *message = _("To edit an account, you must first\n" - "choose an account to edit.\n"); - gnc_error_dialog(message); + switch(type) { + case URL_TYPE_REPORT: + return gnc_report_window_create_child(configstring); + break; + + case URL_TYPE_ACCTTREE: + return gnc_acct_tree_window_create_child(configstring); + break; + + default: + return NULL; } } -static void -gnc_ui_mainWindow_reconcile(GtkWidget *widget, gpointer data) -{ - Account *account = gnc_get_current_account(); - RecnWindow *recnData; - if (account != NULL) - { - recnData = recnWindow(gnc_get_ui_data(), account); - gnc_ui_reconcile_window_raise(recnData); - } - else - { - const char *message = _("To reconcile an account, you must first\n" - "choose an account to reconcile."); - gnc_error_dialog(message); +/******************************************************************** + * gnc_main_window_new() + * initialize the Gnome MDI system + ********************************************************************/ + +GNCMainInfo * +gnc_main_window_new(void) { + GNCMainInfo * retval = g_new0(GNCMainInfo, 1); + + retval->mdi = GNOME_MDI(gnome_mdi_new("GnuCash", "GnuCash")); + retval->component_id = + gnc_register_gui_component (WINDOW_MAIN_CM_CLASS, NULL, NULL, + retval); + + /* these menu and toolbar options are the ones that are always + * available */ + gnc_main_window_create_menus(retval); + + /* set up the position where the child menus/toolbars will be + * inserted */ + gnome_mdi_set_child_menu_path(GNOME_MDI(retval->mdi), + "_File"); + + gnome_mdi_set_mode(retval->mdi, GNOME_MDI_NOTEBOOK); + + retval->toolbar_change_callback_id = + gnc_register_option_change_callback(gnc_main_window_configure_toolbar_cb, + retval, + "General", "Toolbar Buttons"); + + /* handle top-level signals */ + gtk_signal_connect(GTK_OBJECT(retval->mdi), "destroy", + GTK_SIGNAL_FUNC(gnc_main_window_destroy_cb), + retval); + gtk_signal_connect(GTK_OBJECT(retval->mdi), "remove_view", + GTK_SIGNAL_FUNC(gnc_main_window_remove_view_cb), + retval); + gtk_signal_connect(GTK_OBJECT(retval->mdi), "app_created", + GTK_SIGNAL_FUNC(gnc_main_window_app_created_cb), + retval); + gtk_signal_connect(GTK_OBJECT(retval->mdi), "child_changed", + GTK_SIGNAL_FUNC(gnc_main_window_child_changed_cb), + retval); + gtk_signal_connect(GTK_OBJECT(retval->mdi), "view_changed", + GTK_SIGNAL_FUNC(gnc_main_window_view_changed_cb), + retval); + + return retval; +} + +static char * +gnc_main_window_child_save_func(GnomeMDIChild * child, gpointer user_data) { + printf("child save func '%p': '%s'\n", child, child->name); + return g_strdup(child->name); +} + +/******************************************************************** + * gnc_main_window_add_child() + ********************************************************************/ + +void +gnc_main_window_add_child(GNCMainInfo * wind, GNCMainChildInfo * child) { + wind->children = g_list_append(wind->children, child); + + if(GNOME_IS_MDI_GENERIC_CHILD(child->child)) { + gnome_mdi_generic_child_set_config_func + (GNOME_MDI_GENERIC_CHILD(child->child), + gnc_main_window_child_save_func, NULL); } } -static void -gnc_ui_mainWindow_transfer (GtkWidget *widget, gpointer data) -{ - gnc_xfer_dialog (gnc_get_ui_data (), gnc_get_current_account ()); + +/******************************************************************** + * gnc_main_window_remove_child() + ********************************************************************/ + +void +gnc_main_window_remove_child(GNCMainInfo * wind, GNCMainChildInfo * child) { + wind->children = g_list_remove(wind->children, child); } -static void -gnc_ui_mainWindow_stock_split (GtkWidget *widget, gpointer data) -{ - gnc_stock_split_dialog (gnc_get_current_account ()); +/******************************************************************** + * gnc_main_window_destroy() + * free MDI toplevel resources + ********************************************************************/ + +void +gnc_main_window_destroy(GNCMainInfo * wind) { + g_free(wind); } -static void -gnc_ui_mainWindow_scrub(GtkWidget *widget, gpointer data) -{ - Account *account = gnc_get_current_account (); - if (account == NULL) - { - const char *message = _("You must select an account to scrub."); - gnc_error_dialog (message); - return; - } +/******************************************************************** + * gnc_main_window_save() + * save the status of the MDI session + ********************************************************************/ - gnc_suspend_gui_refresh (); - - xaccAccountScrubOrphans (account); - xaccAccountScrubImbalance (account); - - gnc_resume_gui_refresh (); +void +gnc_main_window_save(GNCMainInfo * wind) { + printf("entering gnome_mdi_save_state\n"); + gnome_mdi_save_state(GNOME_MDI(wind->mdi), + "/GnuCash/MDI Session"); + printf("left gnome_mdi_save_state\n"); } -static void -gnc_ui_mainWindow_scrub_sub(GtkWidget *widget, gpointer data) -{ - Account *account = gnc_get_current_account (); +/******************************************************************** + * gnc_main_window_child_refresh(GNCMainChildInfo * child) + * send an update event to the child + ********************************************************************/ - if (account == NULL) - { - const char *message = _("You must select an account to scrub."); - gnc_error_dialog(message); - return; - } - - gnc_suspend_gui_refresh (); - - xaccAccountTreeScrubOrphans (account); - xaccAccountTreeScrubImbalance (account); - - gnc_resume_gui_refresh (); +void +gnc_main_window_child_refresh(GNCMainChildInfo * child) { + gnome_mdi_update_child(gnc_ui_get_data()->mdi, child->child); } -static void -gnc_ui_mainWindow_scrub_all(GtkWidget *widget, gpointer data) -{ - AccountGroup *group = gncGetCurrentGroup (); - gnc_suspend_gui_refresh (); +/******************************************************************** + * gnc_main_window_get_toplevel() + * get the currently-active top-level widget + ********************************************************************/ - xaccGroupScrubOrphans (group); - xaccGroupScrubImbalance (group); - - gnc_resume_gui_refresh (); +GtkWidget * +gnc_main_window_get_toplevel(GNCMainInfo * wind) { + return GTK_WIDGET(gnome_mdi_get_active_window(GNOME_MDI(wind->mdi))); } + +/******************************************************************** + * menu/toolbar data structures and callbacks + * these are the "templates" that are installed in every toplevel + * MDI window + ********************************************************************/ + static void -gnc_ui_options_cb(GtkWidget *widget, gpointer data) -{ +gnc_main_window_options_cb(GtkWidget *widget, gpointer data) { gnc_show_options_dialog(); } static void -gnc_ui_filemenu_cb(GtkWidget *widget, gpointer menuItem) -{ - switch (GPOINTER_TO_INT(menuItem)) - { - case FMB_NEW: - gncFileNew(); - break; - case FMB_OPEN: - gncFileOpen(); - break; - case FMB_SAVE: - gncFileSave(); - gnc_refresh_main_window_title(); - break; - case FMB_SAVEAS: - gncFileSaveAs(); - gnc_refresh_main_window_title(); - break; - case FMB_IMPORT: - gncFileQIFImport(); - break; - case FMB_QUIT: - gnc_shutdown(0); - break; - default: - break; - } +gnc_main_window_file_new_file_cb(GtkWidget * widget) { + gncFileNew(); } static void -gnc_ui_mainWindow_fincalc_cb(GtkWidget *widget, gpointer data) -{ +gnc_main_window_file_new_window_cb(GtkWidget * widget, GnomeMDI * mdi) { + if(mdi->active_child) { + if(!strcmp(mdi->active_child->name, _("Accounts"))) { + gnc_main_window_open_accounts(TRUE); + } + else { + gnc_main_window_open_report_url(mdi->active_child->name, TRUE); + } + } +} + +static void +gnc_main_window_file_open_cb(GtkWidget * widget) { + gncFileOpen(); +} + +static void +gnc_main_window_file_save_cb(GtkWidget * widget) { + gncFileSave(); + /* gnc_refresh_main_window_title(); */ +} + +static void +gnc_main_window_file_save_as_cb(GtkWidget * widget) { + gncFileSaveAs(); + /* gnc_refresh_main_window_title(); */ +} + +static void +gnc_main_window_file_import_cb(GtkWidget * widget) { + gncFileQIFImport(); +} + +static void +gnc_main_window_file_shutdown_cb(GtkWidget * widget) { + gnc_shutdown(0); +} + +static void +gnc_main_window_file_close_cb(GtkWidget * widget, GnomeMDI * mdi) { + GNCMainChildInfo * inf; + + if(mdi->active_child) { + inf = gtk_object_get_user_data(GTK_OBJECT(mdi->active_child)); + if(inf->toolbar) { + gtk_widget_destroy(GTK_WIDGET(inf->toolbar)->parent); + inf->toolbar = NULL; + } + gnome_mdi_remove_child(mdi, mdi->active_child, FALSE); + } + else { + gnc_warning_dialog(_("Select \"Exit\" to exit GnuCash.")); + } +} + +static void +gnc_main_window_fincalc_cb(GtkWidget *widget, gpointer data) { gnc_ui_fincalc_dialog_create(); } static void -gnc_ui_mainWindow_gl_cb(GtkWidget *widget, gpointer data) -{ +gnc_main_window_gl_cb(GtkWidget *widget, gpointer data) { xaccLedgerDisplay *ld; RegWindow *regData; @@ -825,327 +451,249 @@ gnc_ui_mainWindow_gl_cb(GtkWidget *widget, gpointer data) } static void -gnc_ui_mainWindow_prices_cb(GtkWidget *widget, gpointer data) -{ +gnc_main_window_prices_cb(GtkWidget *widget, gpointer data) { gnc_prices_dialog (NULL); } + static void -gnc_ui_mainWindow_commodities_cb(GtkWidget *widget, gpointer data) +gnc_main_window_find_transactions_cb (GtkWidget *widget, gpointer data) { + gnc_ui_find_transactions_dialog_create(NULL); +} + +static void +gnc_main_window_about_cb (GtkWidget *widget, gpointer data) { + GtkWidget *about; + const gchar *message = _("The GnuCash personal finance manager.\n" + "The GNU way to manage your money!"); + const gchar *copyright = "(C) 1998-2001 Linas Vepstas"; + const gchar *authors[] = { + "Linas Vepstas ", + NULL + }; + + about = gnome_about_new ("GnuCash", VERSION, copyright, + authors, message, NULL); + gnome_dialog_set_parent (GNOME_DIALOG(about), + GTK_WINDOW(gnc_ui_get_toplevel())); + + gnome_dialog_run_and_close (GNOME_DIALOG(about)); +} + +static void +gnc_main_window_commodities_cb(GtkWidget *widget, gpointer data) { gnc_commodities_dialog (NULL); } -static gboolean -gnc_ui_mainWindow_delete_cb(GtkWidget *widget, - GdkEvent *event, - gpointer user_data) -{ - /* Don't allow deletes if we're in a modal dialog */ - if (gtk_main_level() == 1) - gnc_shutdown(0); - /* Don't delete the window, we'll handle things ourselves. */ - return TRUE; +static void +gnc_main_window_totd_cb (GtkWidget *widget, gpointer data) + +{ + gnc_ui_totd_dialog_create_and_run(); + return; } - -static gboolean -gnc_ui_mainWindow_destroy_event_cb(GtkWidget *widget, - GdkEvent *event, - gpointer user_data) +static void +gnc_main_window_help_cb (GtkWidget *widget, gpointer data) { - return FALSE; + helpWindow(NULL, NULL, HH_MAIN); } +static void +gnc_main_window_exit_cb (GtkWidget *widget, gpointer data) +{ + gnc_shutdown(0); +} + +static void +gnc_main_window_file_new_account_tree_cb(GtkWidget * w, GnomeMDI * mdi) { + gnc_main_window_open_accounts(FALSE); +} + +static void +gnc_main_window_create_menus(GNCMainInfo * maininfo) { + static GnomeUIInfo gnc_report_new_template[] = + { + GNOMEUIINFO_END + }; + + static GnomeUIInfo gnc_file_menu_template[] = + { + GNOMEUIINFO_MENU_NEW_ITEM(N_("New _File"), + N_("Create a new file"), + gnc_main_window_file_new_file_cb, NULL), + GNOMEUIINFO_MENU_OPEN_ITEM(gnc_main_window_file_open_cb, NULL), + GNOMEUIINFO_MENU_SAVE_ITEM(gnc_main_window_file_save_cb, NULL), + GNOMEUIINFO_MENU_SAVE_AS_ITEM(gnc_main_window_file_save_as_cb, NULL), + GNOMEUIINFO_SEPARATOR, + { + GNOME_APP_UI_ITEM, + N_("Import QIF..."), + N_("Import a Quicken QIF file"), + gnc_main_window_file_import_cb, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_CONVERT, + 'i', GDK_CONTROL_MASK, NULL + }, + GNOMEUIINFO_SEPARATOR, + { + GNOME_APP_UI_ITEM, + N_("New _Window"), + N_("Open a new top-level GnuCash window"), + gnc_main_window_file_new_window_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("New _Account Tree"), + N_("Open a new account tree view"), + gnc_main_window_file_new_account_tree_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL + }, + GNOMEUIINFO_SEPARATOR, + { + GNOME_APP_UI_ITEM, + N_("Close _Window"), + N_("Close this MDI window"), + gnc_main_window_file_close_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL + }, + GNOMEUIINFO_MENU_EXIT_ITEM(gnc_main_window_file_shutdown_cb, NULL), + GNOMEUIINFO_END + }; + + static GnomeUIInfo gnc_settings_menu_template[] = + { + { + GNOME_APP_UI_ITEM, + N_("_Preferences..."), + N_("Open the global preferences dialog"), + gnc_main_window_options_cb, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PREF, + 0, 0, NULL + }, + GNOMEUIINFO_END + }; + + static GnomeUIInfo gnc_tools_menu_template[] = + { + { + GNOME_APP_UI_ITEM, + N_("_General Ledger"), + N_("Open a general ledger window"), + gnc_main_window_gl_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("Commodity _Editor"), + N_("View and edit the commodities for stocks and mutual funds"), + gnc_main_window_commodities_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("_Price Editor"), + N_("View and edit the prices for stocks and mutual funds"), + gnc_main_window_prices_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("Financial _Calculator"), + N_("Use the financial calculator"), + gnc_main_window_fincalc_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { GNOME_APP_UI_ITEM, + N_("_Find Transactions"), + N_("Find transactions with a search"), + gnc_main_window_find_transactions_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + GNOMEUIINFO_END + }; + + static GnomeUIInfo gnc_help_menu_template[] = + { + { + GNOME_APP_UI_ITEM, + N_("_Manual"), + N_("Open the GnuCash Manual"), + gnc_main_window_help_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("_Tips Of The Day"), + N_("View the Tips of the Day"), + gnc_main_window_totd_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + + GNOMEUIINFO_MENU_ABOUT_ITEM(gnc_main_window_about_cb, NULL), + + GNOMEUIINFO_END + }; + + static GnomeUIInfo gnc_developer_menu_template[] = + { + GNOMEUIINFO_END + }; + + static GnomeUIInfo gnc_main_menu_template[] = + { + GNOMEUIINFO_MENU_FILE_TREE(gnc_file_menu_template), + GNOMEUIINFO_SUBTREE(N_("_Tools"), gnc_tools_menu_template), + GNOMEUIINFO_SUBTREE(N_("_Settings"), gnc_settings_menu_template), + GNOMEUIINFO_SUBTREE(N_("_Devel Options"), gnc_developer_menu_template), + GNOMEUIINFO_MENU_HELP_TREE(gnc_help_menu_template), + GNOMEUIINFO_END + }; + + gnome_mdi_set_menubar_template(GNOME_MDI(maininfo->mdi), + gnc_main_menu_template); +} + +/******************************************************************** + * create_child_toolbar + * add the "stock" components to the child's components and return a + * catenated toolbar. + ********************************************************************/ + void -gnc_ui_mainWindow_save_size(void) -{ - GtkWidget *app; - int width = 0; - int height = 0; - - app = gnc_get_ui_data(); - if (!app) - return; - - gdk_window_get_geometry(GTK_WIDGET(app)->window, NULL, NULL, - &width, &height, NULL); - - gnc_save_window_size("main_win", width, height); -} - -static void -gnc_ui_mainWindow_destroy_cb (GtkObject *object, gpointer user_data) -{ - GNCMainInfo *main_info = user_data; - - gnc_unregister_gui_component (main_info->component_id); - - gnc_unregister_option_change_callback_id - (main_info->main_window_change_callback_id); - - gnc_unregister_option_change_callback_id - (main_info->euro_change_callback_id); - - gnc_unregister_option_change_callback_id - (main_info->toolbar_change_callback_id); - - g_list_free(main_info->account_sensitives); - main_info->account_sensitives = NULL; - - g_free (main_info); -} - -GNCMainWinAccountTree * -gnc_get_current_account_tree (void) -{ - GNCMainInfo *main_info; - - main_info = gnc_get_main_info (); - if (main_info == NULL) - return NULL; - - return GNC_MAINWIN_ACCOUNT_TREE (main_info->account_tree); -} - -Account * -gnc_get_current_account (void) -{ - GNCMainWinAccountTree *list = gnc_get_current_account_tree(); - return gnc_mainwin_account_tree_get_current_account(list); -} - -GList * -gnc_get_current_accounts(void) -{ - GNCMainWinAccountTree *tree = gnc_get_current_account_tree(); - return gnc_mainwin_account_tree_get_current_accounts(tree); -} - -static void -gnc_account_tree_activate_cb(GNCMainWinAccountTree *tree, - Account *account, - gpointer user_data) -{ - RegWindow *regData; - gboolean expand; - - expand = gnc_lookup_boolean_option("Main Window", - "Double click expands parent accounts", - FALSE); - - if (expand) - { - AccountGroup *group; - - group = xaccAccountGetChildren(account); - if (xaccGroupGetNumAccounts(group) > 0) - { - gnc_mainwin_account_tree_toggle_account_expansion(tree, account); - return; - } - } - - regData = regWindowSimple(account); - gnc_register_raise(regData); -} - -static void -gnc_configure_account_tree (gpointer data) -{ - GNCMainInfo *info = data; - GNCMainWinAccountTree *tree; - AccountViewInfo new_avi; - GSList *list, *node; - - memset (&new_avi, 0, sizeof(new_avi)); - - tree = GNC_MAINWIN_ACCOUNT_TREE(info->account_tree); - - list = gnc_lookup_list_option("Main Window", - "Account types to display", - NULL); - - for (node = list; node != NULL; node = node->next) - { - if (safe_strcmp(node->data, "bank") == 0) - new_avi.include_type[BANK] = TRUE; - - else if (safe_strcmp(node->data, "cash") == 0) - new_avi.include_type[CASH] = TRUE; - - else if (safe_strcmp(node->data, "credit") == 0) - new_avi.include_type[CREDIT] = TRUE; - - else if (safe_strcmp(node->data, "asset") == 0) - new_avi.include_type[ASSET] = TRUE; - - else if (safe_strcmp(node->data, "liability") == 0) - new_avi.include_type[LIABILITY] = TRUE; - - else if (safe_strcmp(node->data, "stock") == 0) - new_avi.include_type[STOCK] = TRUE; - - else if (safe_strcmp(node->data, "mutual") == 0) - new_avi.include_type[MUTUAL] = TRUE; - - else if (safe_strcmp(node->data, "currency") == 0) - new_avi.include_type[CURRENCY] = TRUE; - - else if (safe_strcmp(node->data, "income") == 0) - new_avi.include_type[INCOME] = TRUE; - - else if (safe_strcmp(node->data, "expense") == 0) - new_avi.include_type[EXPENSE] = TRUE; - - else if (safe_strcmp(node->data, "equity") == 0) - new_avi.include_type[EQUITY] = TRUE; - } - - gnc_free_list_option_value (list); - - list = gnc_lookup_list_option("Main Window", - "Account fields to display", - NULL); - - for (node = list; node != NULL; node = node->next) - { - if (safe_strcmp(node->data, "type") == 0) - new_avi.show_field[ACCOUNT_TYPE] = TRUE; - - else if (safe_strcmp(node->data, "code") == 0) - new_avi.show_field[ACCOUNT_CODE] = TRUE; - - else if (safe_strcmp(node->data, "description") == 0) - new_avi.show_field[ACCOUNT_DESCRIPTION] = TRUE; - - else if (safe_strcmp(node->data, "notes") == 0) - new_avi.show_field[ACCOUNT_NOTES] = TRUE; - - else if (safe_strcmp(node->data, "currency") == 0) - new_avi.show_field[ACCOUNT_CURRENCY] = TRUE; - - else if (safe_strcmp(node->data, "security") == 0) - new_avi.show_field[ACCOUNT_SECURITY] = TRUE; - - else if (safe_strcmp(node->data, "balance") == 0) - { - new_avi.show_field[ACCOUNT_BALANCE] = TRUE; - if(gnc_lookup_boolean_option("International", - "Enable EURO support", FALSE)) - new_avi.show_field[ACCOUNT_BALANCE_EURO] = TRUE; - } - - else if (safe_strcmp(node->data, "total") == 0) - { - new_avi.show_field[ACCOUNT_TOTAL] = TRUE; - if(gnc_lookup_boolean_option("International", - "Enable EURO support", FALSE)) - new_avi.show_field[ACCOUNT_TOTAL_EURO] = TRUE; - } - } - - gnc_free_list_option_value (list); - - new_avi.show_field[ACCOUNT_NAME] = TRUE; - - gnc_mainwin_account_tree_set_view_info (tree, new_avi); -} - -static void -gnc_euro_change (gpointer data) -{ - gnc_ui_refresh_statusbar (); - gnc_configure_account_tree (data); - gnc_gui_refresh_all (); -} - -static void -gnc_main_create_toolbar(GnomeApp *app, GNCMainInfo *main_info) -{ - GList *list; - - static GnomeUIInfo toolbar[] = +gnc_main_window_create_child_toolbar(GNCMainInfo * mi, + GNCMainChildInfo * child) { + GnomeUIInfo pre_tb[] = { { GNOME_APP_UI_ITEM, N_("Save"), N_("Save the file to disk"), - gnc_ui_filemenu_cb, - GINT_TO_POINTER(FMB_SAVE), + gnc_main_window_file_save_cb, + NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_SAVE, 0, 0, NULL }, - { GNOME_APP_UI_ITEM, - N_("Import"), - N_("Import a Quicken QIF file"), - gnc_ui_filemenu_cb, - GINT_TO_POINTER(FMB_IMPORT), - NULL, - GNOME_APP_PIXMAP_STOCK, - GNOME_STOCK_PIXMAP_CONVERT, - 0, 0, NULL - }, - GNOMEUIINFO_SEPARATOR, - { GNOME_APP_UI_ITEM, - N_("Open"), - N_("Open the selected account"), - gnc_ui_mainWindow_toolbar_open, - NULL, - NULL, - GNOME_APP_PIXMAP_STOCK, - GNOME_STOCK_PIXMAP_JUMP_TO, - 0, 0, NULL - }, - { GNOME_APP_UI_ITEM, - N_("Edit"), - N_("Edit the selected account"), - gnc_ui_mainWindow_toolbar_edit, - NULL, - NULL, - GNOME_APP_PIXMAP_STOCK, - GNOME_STOCK_PIXMAP_PROPERTIES, - 0, 0, NULL - }, - GNOMEUIINFO_SEPARATOR, - { GNOME_APP_UI_ITEM, - N_("New"), - N_("Create a new account"), - gnc_ui_add_account, - NULL, - NULL, - GNOME_APP_PIXMAP_STOCK, - GNOME_STOCK_PIXMAP_ADD, - 0, 0, NULL - }, - { GNOME_APP_UI_ITEM, - N_("Delete"), - N_("Delete selected account"), - gnc_ui_delete_account_cb, - NULL, - NULL, - GNOME_APP_PIXMAP_STOCK, - GNOME_STOCK_PIXMAP_REMOVE, - 0, 0, NULL - }, - GNOMEUIINFO_SEPARATOR, - { GNOME_APP_UI_ITEM, - N_("Find"), - N_("Find transactions with a search"), - gnc_ui_find_transactions_cb, - NULL, - NULL, - GNOME_APP_PIXMAP_STOCK, - GNOME_STOCK_PIXMAP_SEARCH, - 0, 0, NULL - }, + GNOMEUIINFO_SEPARATOR + }; + + GnomeUIInfo post_tb[] = + { GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("Exit"), N_("Exit GnuCash"), - gnc_ui_exit_cb, + gnc_main_window_exit_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, @@ -1154,565 +702,31 @@ gnc_main_create_toolbar(GnomeApp *app, GNCMainInfo *main_info) }, GNOMEUIINFO_END }; - - gnome_app_create_toolbar(app, toolbar); - - list = main_info->account_sensitives; - - list = g_list_prepend(list, toolbar[3].widget); - list = g_list_prepend(list, toolbar[4].widget); - list = g_list_prepend(list, toolbar[7].widget); - - main_info->account_sensitives = list; -} - -static void -gnc_main_create_menus(GnomeApp *app, GtkWidget *account_tree, - GNCMainInfo *main_info) -{ - GList *list; - - static GnomeUIInfo filemenu[] = - { - GNOMEUIINFO_MENU_NEW_ITEM(N_("New File"), - N_("Create a new file"), - gnc_ui_filemenu_cb, - GINT_TO_POINTER(FMB_NEW)), - GNOMEUIINFO_MENU_OPEN_ITEM(gnc_ui_filemenu_cb, - GINT_TO_POINTER(FMB_OPEN)), - GNOMEUIINFO_MENU_SAVE_ITEM(gnc_ui_filemenu_cb, - GINT_TO_POINTER(FMB_SAVE)), - GNOMEUIINFO_MENU_SAVE_AS_ITEM(gnc_ui_filemenu_cb, - GINT_TO_POINTER(FMB_SAVEAS)), - GNOMEUIINFO_SEPARATOR, - { - GNOME_APP_UI_ITEM, - N_("Import QIF..."), - N_("Import a Quicken QIF file"), - gnc_ui_filemenu_cb, GINT_TO_POINTER(FMB_IMPORT), NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_CONVERT, - 'i', GDK_CONTROL_MASK, NULL - }, - GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_MENU_EXIT_ITEM(gnc_ui_filemenu_cb, - GINT_TO_POINTER(FMB_QUIT)), - GNOMEUIINFO_END - }; - - static GnomeUIInfo optionsmenu[] = - { - { - GNOME_APP_UI_ITEM, - N_("_Preferences..."), - N_("Open the global preferences dialog"), - gnc_ui_options_cb, NULL, NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PREF, - 0, 0, NULL - }, - GNOMEUIINFO_END - }; - - static GnomeUIInfo scrubmenu[] = - { - { - GNOME_APP_UI_ITEM, - N_("Scrub A_ccount"), - N_("Identify and fix problems in the account"), - gnc_ui_mainWindow_scrub, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("Scrub Su_baccounts"), - N_("Identify and fix problems in the account " - "and its subaccounts"), - gnc_ui_mainWindow_scrub_sub, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("Scrub A_ll"), - N_("Identify and fix problems in all the accounts"), - gnc_ui_mainWindow_scrub_all, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - GNOMEUIINFO_END - }; - - static GnomeUIInfo accountsmenu[] = - { - { - GNOME_APP_UI_ITEM, - N_("_Open Account"), - N_("Open the selected account"), - gnc_ui_mainWindow_toolbar_open, NULL, NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN, - 'o', GDK_CONTROL_MASK, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("Open S_ubaccounts"), - N_("Open the selected account and all its subaccounts"), - gnc_ui_mainWindow_toolbar_open_subs, NULL, NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN, - 0, 0, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("_Edit Account"), - N_("Edit the selected account"), - gnc_ui_mainWindow_toolbar_edit, NULL, NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PROP, - 'e', GDK_CONTROL_MASK, NULL - }, - GNOMEUIINFO_SEPARATOR, - { - GNOME_APP_UI_ITEM, - N_("_Reconcile..."), - N_("Reconcile the selected account"), - gnc_ui_mainWindow_reconcile, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 'r', GDK_CONTROL_MASK, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("_Transfer..."), - N_("Transfer funds from one account to another"), - gnc_ui_mainWindow_transfer, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 't', GDK_CONTROL_MASK, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("Stock S_plit..."), - N_("Record a stock split or a stock merger"), - gnc_ui_mainWindow_stock_split, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - GNOMEUIINFO_SEPARATOR, - { - GNOME_APP_UI_ITEM, - N_("_New Account..."), - N_("Create a new account"), - gnc_ui_add_account, NULL, NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_ADD, - 0, 0, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("_Delete Account"), - N_("Delete selected account"), - gnc_ui_delete_account_cb, NULL, NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_REMOVE, - 0, 0, NULL - }, - GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_SUBTREE(N_("_Scrub"), scrubmenu), - GNOMEUIINFO_SEPARATOR, - { - GNOME_APP_UI_ITEM, - N_("Tax Information"), - N_("Setup tax information for all income and expense accounts"), - gnc_tax_info_cb, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - GNOMEUIINFO_END - }; - - static GnomeUIInfo toolsmenu[] = - { - { - GNOME_APP_UI_ITEM, - N_("_General Ledger"), - N_("Open a general ledger window"), - gnc_ui_mainWindow_gl_cb, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("Commodity _Editor"), - N_("View and edit the commodities for stocks and mutual funds"), - gnc_ui_mainWindow_commodities_cb, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("_Price Editor"), - N_("View and edit the prices for stocks and mutual funds"), - gnc_ui_mainWindow_prices_cb, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("Financial _Calculator"), - N_("Use the financial calculator"), - gnc_ui_mainWindow_fincalc_cb, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - { GNOME_APP_UI_ITEM, - N_("_Find Transactions"), - N_("Find transactions with a search"), - gnc_ui_find_transactions_cb, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - GNOMEUIINFO_END - }; - - static GnomeUIInfo helpmenu[] = - { - { - GNOME_APP_UI_ITEM, - N_("_Manual"), - N_("Open the GnuCash Manual"), - gnc_ui_help_cb, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("_Tips Of The Day"), - N_("View the Tips of the Day"), - gnc_ui_totd_cb, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - - GNOMEUIINFO_MENU_ABOUT_ITEM(gnc_ui_about_cb, NULL), - - GNOMEUIINFO_END - }; - - static GnomeUIInfo developer_menu[] = - { - GNOMEUIINFO_END - }; - - static GnomeUIInfo mainmenu[] = - { - GNOMEUIINFO_MENU_FILE_TREE(filemenu), - GNOMEUIINFO_SUBTREE(N_("_Accounts"), accountsmenu), - GNOMEUIINFO_SUBTREE(N_("_Tools"), toolsmenu), - GNOMEUIINFO_MENU_SETTINGS_TREE(optionsmenu), - GNOMEUIINFO_SUBTREE(N_("_Devel Options"), developer_menu), - GNOMEUIINFO_MENU_HELP_TREE(helpmenu), - GNOMEUIINFO_END - }; - - gnome_app_create_menus(app, mainmenu); - gnome_app_install_menu_hints(app, mainmenu); - - list = main_info->account_sensitives; - - list = g_list_prepend(list, scrubmenu[0].widget); - list = g_list_prepend(list, scrubmenu[1].widget); - - list = g_list_prepend(list, accountsmenu[0].widget); - list = g_list_prepend(list, accountsmenu[1].widget); - list = g_list_prepend(list, accountsmenu[2].widget); - list = g_list_prepend(list, accountsmenu[4].widget); - list = g_list_prepend(list, accountsmenu[9].widget); - - gnc_mainwin_account_tree_attach_popup - (GNC_MAINWIN_ACCOUNT_TREE (account_tree), accountsmenu); - - list = g_list_prepend(list, scrubmenu[0].widget); - list = g_list_prepend(list, scrubmenu[1].widget); - - list = g_list_prepend(list, accountsmenu[0].widget); - list = g_list_prepend(list, accountsmenu[1].widget); - list = g_list_prepend(list, accountsmenu[2].widget); - list = g_list_prepend(list, accountsmenu[4].widget); - list = g_list_prepend(list, accountsmenu[9].widget); - - main_info->account_sensitives = list; - - gtk_widget_hide (mainmenu[4].widget); -} - -static GtkWidget * -gnc_main_create_summary_bar (GnomeApp *app, GNCMainInfo *main_info) -{ - GtkWidget *summarybar; - GtkWidget *combo_box; - gnc_commodity * default_currency; - GNCCurrencyItem *def_item; - - summarybar = gtk_hbox_new (FALSE, 5); - - gtk_container_set_border_width (GTK_CONTAINER (summarybar), 2); - - default_currency = - gnc_lookup_currency_option ("International", - "Default Currency", - gnc_locale_default_currency ()); - - combo_box = gtk_select_new (); - main_info->totals_combo = combo_box; - main_info->totals_list = NULL; - - def_item = gnc_ui_get_currency_item (&main_info->totals_list, - default_currency, - main_info->totals_combo); - - gtk_select_select_child (GTK_SELECT(combo_box), def_item->listitem); - gtk_box_pack_start (GTK_BOX(summarybar), combo_box, FALSE, FALSE, 5); - gtk_widget_show (combo_box); - - return summarybar; -} - -static GNCMainInfo * -gnc_get_main_info (void) -{ - GtkWidget *app = gnc_get_ui_data (); - - if (!app) - return NULL; - - return gtk_object_get_data (GTK_OBJECT (app), "gnc_main_info"); -} - -static void -gnc_configure_toolbar (gpointer data) -{ - GtkWidget *app_w = gnc_get_ui_data (); - GnomeApp *app; - GnomeDockItem *di; - GtkWidget *toolbar; - GtkToolbarStyle tbstyle; - - if (!app_w) - return; - - app = GNOME_APP (app_w); - - di = gnome_app_get_dock_item_by_name(app, GNOME_APP_TOOLBAR_NAME); - if (di == NULL) - return; - - toolbar = gnome_dock_item_get_child(di); - if (toolbar == NULL) - return; - - tbstyle = gnc_get_toolbar_style(); - - gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), tbstyle); -} - -static void -gnc_account_foreach_cb (gpointer widget, gpointer sensitive) -{ - gtk_widget_set_sensitive(GTK_WIDGET(widget), GPOINTER_TO_INT(sensitive)); -} - -static void -gnc_account_set_sensititives(GNCMainInfo *main_info, gboolean sensitive) -{ - if (main_info == NULL) - return; - - g_list_foreach(main_info->account_sensitives, - gnc_account_foreach_cb, - GINT_TO_POINTER(sensitive)); -} - -static void -gnc_account_cb(GNCMainWinAccountTree *tree, Account *account, gpointer data) -{ - gboolean sensitive; - - account = gnc_mainwin_account_tree_get_current_account(tree); - sensitive = account != NULL; - - gnc_account_set_sensititives(gnc_get_main_info(), sensitive); -} - -static void -refresh_handler (GHashTable *changes, gpointer user_data) -{ - gnc_refresh_main_window (); -} - -void -mainWindow (void) -{ - GNCMainInfo *main_info; - GtkWidget *app = gnc_get_ui_data(); - GtkWidget *summarybar; - GtkWidget *statusbar; - int width = 0; - int height = 0; - - gnc_get_window_size("main_win", &width, &height); - if (height == 0) - height = 400; - gtk_window_set_default_size(GTK_WINDOW(app), width, height); - - main_info = g_new0 (GNCMainInfo, 1); - gtk_object_set_data (GTK_OBJECT(app), "gnc_main_info", main_info); - - main_info->component_id = gnc_register_gui_component (WINDOW_MAIN_CM_CLASS, - refresh_handler, NULL, - main_info); - - gnc_gui_component_watch_entity_type (main_info->component_id, - GNC_ID_ACCOUNT, - GNC_EVENT_MODIFY | GNC_EVENT_DESTROY); - - main_info->main_window_change_callback_id = - gnc_register_option_change_callback(gnc_configure_account_tree, main_info, - "Main Window", NULL); - - main_info->euro_change_callback_id = - gnc_register_option_change_callback(gnc_euro_change, main_info, - "International", - "Enable EURO support"); - - summarybar = gnc_main_create_summary_bar (GNOME_APP(app), main_info); - if (summarybar) - { - GnomeDockItem *dock_item; - - gnome_app_add_docked (GNOME_APP(app), GTK_WIDGET(summarybar), - "Summary Bar", GNOME_DOCK_ITEM_BEH_EXCLUSIVE, - GNOME_DOCK_TOP, 2, 0, 0); - - dock_item = gnome_app_get_dock_item_by_name (GNOME_APP(app), - "Summary Bar"); - gnome_dock_item_set_shadow_type (dock_item, GTK_SHADOW_OUT); - } - - /* create statusbar and add it to the application. */ - statusbar = gnome_appbar_new(FALSE, /* no progress bar, maybe later? */ - TRUE, /* has status area */ - GNOME_PREFERENCES_USER /* recommended */); - - gnome_app_set_statusbar(GNOME_APP(app), GTK_WIDGET(statusbar)); - - - gnc_main_create_toolbar(GNOME_APP(app), main_info); - gnc_configure_toolbar(NULL); - main_info->toolbar_change_callback_id = - gnc_register_option_change_callback(gnc_configure_toolbar, NULL, - "General", "Toolbar Buttons"); - - /* create scrolled window */ - main_info->notebook = gtk_notebook_new(); - gtk_notebook_set_show_border(GTK_NOTEBOOK(main_info->notebook), TRUE); - gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_info->notebook), TRUE); - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_info->notebook), - GTK_POS_LEFT); - - main_info->account_tree = gnc_mainwin_account_tree_new(); - - gtk_notebook_append_page(GTK_NOTEBOOK(main_info->notebook), - main_info->account_tree, - gtk_label_new(_("Accounts"))); + GnomeUIInfo end = GNOMEUIINFO_END; + GnomeUIInfo * tbinfo; + GnomeUIInfo * cur; + GtkToolbar * tb = GTK_TOOLBAR(gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL, + GTK_TOOLBAR_BOTH)); + tbinfo = g_new0(GnomeUIInfo, + (sizeof(pre_tb) + sizeof(post_tb)) / sizeof(GnomeUIInfo) + + child->toolbar_size - 1); - /* gnome_app_set_contents(GNOME_APP(app), main_info->account_tree); */ - gnome_app_set_contents(GNOME_APP(app), main_info->notebook); + /* splice the pre, post, and child segments together */ + cur = tbinfo; + memcpy(cur, pre_tb, sizeof(pre_tb)); + cur += sizeof(pre_tb)/sizeof(GnomeUIInfo); + memcpy(cur, child->toolbar_info, + (child->toolbar_size - 1)*sizeof(GnomeUIInfo)); + cur += child->toolbar_size - 1; + memcpy(cur, post_tb, sizeof(post_tb)); - gnc_main_create_menus(GNOME_APP(app), main_info->account_tree, main_info); - - gtk_signal_connect(GTK_OBJECT(main_info->account_tree), "activate_account", - GTK_SIGNAL_FUNC (gnc_account_tree_activate_cb), NULL); - - gtk_signal_connect(GTK_OBJECT(main_info->account_tree), "select_account", - GTK_SIGNAL_FUNC(gnc_account_cb), NULL); - - gtk_signal_connect(GTK_OBJECT(main_info->account_tree), "unselect_account", - GTK_SIGNAL_FUNC(gnc_account_cb), NULL); - - - /* Attach delete and destroy signals to the main window */ - gtk_signal_connect (GTK_OBJECT (app), "delete_event", - GTK_SIGNAL_FUNC (gnc_ui_mainWindow_delete_cb), - NULL); - - gtk_signal_connect (GTK_OBJECT (app), "destroy_event", - GTK_SIGNAL_FUNC (gnc_ui_mainWindow_destroy_event_cb), - NULL); - - gtk_signal_connect (GTK_OBJECT (app), "destroy", - GTK_SIGNAL_FUNC (gnc_ui_mainWindow_destroy_cb), - main_info); - - /* Show everything now that it is created */ - gtk_widget_show (summarybar); - gtk_widget_show (statusbar); - gtk_widget_show_all (main_info->notebook); - gtk_widget_show (main_info->account_tree); - - gnc_configure_account_tree (main_info); - - gnc_refresh_main_window (); - gnc_account_tree_refresh - (GNC_MAINWIN_ACCOUNT_TREE (main_info->account_tree)->acc_tree); - - gnc_account_set_sensititives(main_info, FALSE); - - gtk_widget_grab_focus(main_info->account_tree); -} - -static void -component_handler (const char *class, gint component_id, gpointer iter_data) -{ - GNCMainInfo *info = iter_data; - - if (info->component_id == component_id) - return; - - gnc_close_gui_component (component_id); -} - -void -gnc_ui_destroy_all_subwindows (void) -{ - GNCMainInfo *info = gnc_get_main_info (); - - gnc_suspend_gui_refresh (); - - gnc_forall_gui_components (NULL, component_handler, info); - - gnc_resume_gui_refresh (); -} - -void -gnc_report_in_main_window (int report_id) { - GNCMainInfo * mainwin = gnc_get_main_info(); - GtkWidget * fr = gtk_frame_new(NULL); - gnc_report_window * reptwin = gnc_report_window_new(fr); - SCM get_report = gh_eval_str("gnc:find-report"); - SCM get_name = gh_eval_str("gnc:report-name"); - char * report_name; - gint page_num; + child->toolbar = GTK_WIDGET(tb); + child->toolbar_info = tbinfo; + child->toolbar_size = + (sizeof(pre_tb) + sizeof(post_tb)) / sizeof(GnomeUIInfo) + + child->toolbar_size; - gtk_frame_set_shadow_type(GTK_FRAME(fr), GTK_SHADOW_NONE); + gnome_app_fill_toolbar(tb, tbinfo, NULL); - report_name = gh_scm2newstr(gh_call1(get_name, - gh_call1(get_report, - gh_int2scm(report_id))), - NULL); - gtk_widget_show_all(fr); - gtk_notebook_append_page(GTK_NOTEBOOK(mainwin->notebook), - fr, gtk_label_new(report_name)); - - page_num = gtk_notebook_page_num(GTK_NOTEBOOK(mainwin->notebook), fr); - gtk_notebook_set_page(GTK_NOTEBOOK(mainwin->notebook), page_num); - - gnc_set_busy_cursor (NULL, TRUE); - gnc_report_window_show_report(reptwin, report_id); - gnc_unset_busy_cursor (NULL); } -/********************* END OF FILE **********************************/ diff --git a/src/gnome/window-main.h b/src/gnome/window-main.h index 05b2fbc982..8a4d7b7f74 100644 --- a/src/gnome/window-main.h +++ b/src/gnome/window-main.h @@ -1,6 +1,7 @@ -/*******************************************************************\ +/******************************************************************** * window-main.h -- public GNOME main window functions * * Copyright (C) 1998,1999 Linas Vepstas * + * Copyright (C) 2001 Bill Gribble * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -18,23 +19,46 @@ * Free Software Foundation Voice: +1-617-542-5942 * * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * * Boston, MA 02111-1307, USA gnu@gnu.org * -\********************************************************************/ + ********************************************************************/ #ifndef __WINDOW_MAIN_H__ #define __WINDOW_MAIN_H__ -#include "mainwindow-account-tree.h" +#include +#include -/** PROTOTYPES ******************************************************/ +typedef struct { + GnomeMDI * mdi; + int component_id; + SCM toolbar_change_callback_id; + GList * children; +} GNCMainInfo; -void mainWindow(void); +typedef struct { + GnomeMDIChild * child; + GtkWidget * contents; + GnomeApp * app; -GNCMainWinAccountTree * gnc_get_current_account_tree(void); + GtkWidget * toolbar; + GnomeUIInfo * toolbar_info; + int toolbar_size; + GnomeUIInfo * menu_info; -void gnc_ui_mainWindow_save_size(void); -void gnc_default_ui_start(void); -int gnucash_ui_init(void); + int component_id; + void * user_data; +} GNCMainChildInfo; -void gnc_report_in_main_window (int report_id); +GNCMainInfo * gnc_main_window_new(void); +void gnc_main_window_destroy(GNCMainInfo * wind); +void gnc_main_window_save(GNCMainInfo * wind); +GtkWidget * gnc_main_window_get_toplevel(GNCMainInfo * wind); +void gnc_main_window_create_child_toolbar(GNCMainInfo * mi, + GNCMainChildInfo * child); +void gnc_main_window_add_child(GNCMainInfo * main, + GNCMainChildInfo * child); +void gnc_main_window_remove_child(GNCMainInfo * main, + GNCMainChildInfo * child); +void gnc_main_window_child_refresh(GNCMainChildInfo * mc); +GnomeMDIChild * gnc_main_window_create_child(const gchar * configstring); #endif diff --git a/src/gnome/window-reconcile.c b/src/gnome/window-reconcile.c index 2a383345af..a478ad74e0 100644 --- a/src/gnome/window-reconcile.c +++ b/src/gnome/window-reconcile.c @@ -35,7 +35,6 @@ #include #include "AccWindow.h" -#include "MainWindow.h" #include "MultiLedger.h" #include "RegWindow.h" #include "Scrub.h" diff --git a/src/gnome/window-register.c b/src/gnome/window-register.c index 3609c63e3d..4d80e0993b 100644 --- a/src/gnome/window-register.c +++ b/src/gnome/window-register.c @@ -36,7 +36,6 @@ #include "AccWindow.h" #include "EuroUtils.h" #include "FileDialog.h" -#include "MainWindow.h" #include "MultiLedger.h" #include "RegWindow.h" #include "Scrub.h" diff --git a/src/gnome/window-report.c b/src/gnome/window-report.c index c6c77f693d..8e11e4edab 100644 --- a/src/gnome/window-report.c +++ b/src/gnome/window-report.c @@ -40,22 +40,24 @@ #include "gnc-html-history.h" #include "gnc-html.h" #include "gnc-ui.h" +#include "option-util.h" #include "query-user.h" +#include "top-level.h" +#include "window-main.h" #include "window-report.h" #define WINDOW_REPORT_CM_CLASS "window-report" struct _gnc_report_window { + GNCMainChildInfo * mc; GtkWidget * container; - gboolean top_level; - - GtkWidget * popup; - GtkWidget * back_widg; - GtkWidget * fwd_widg; SCM scm_report; SCM scm_options; SCM scm_options_edit; + SCM name_change_callback_id; + + GNCOptionDB * odb; /* used to get callbacks from parameter edit */ gnc_html * html; }; @@ -68,6 +70,158 @@ static gint last_width = 0; static gint last_height = 0; +/******************************************************************** + * REPORT WINDOW FUNCTIONS + * creating/managing report-window mdi children + ********************************************************************/ + +/******************************************************************** + * gnc_report_window_view_labeler + * label the window/tab/menu item with the report name + ********************************************************************/ + +static GtkWidget * +gnc_report_window_view_labeler(GnomeMDIChild * child, GtkWidget * current, + gpointer user_data) { + GNCMainChildInfo * rwin = gtk_object_get_user_data(GTK_OBJECT(child)); + gnc_report_window * report; + SCM get_name = gh_eval_str("gnc:report-name"); + char * name = NULL; + + if(rwin) { + report = rwin->user_data; + if(report->scm_report != SCM_BOOL_F) { + name = gh_scm2newstr(gh_call1(get_name, + report->scm_report), + NULL); + } + else { + name = strdup(_("(Report not found)")); + } + } + else { + name = strdup(_("Report")); + } + if(current == NULL) { + GtkWidget * label = gtk_label_new(name); + free(name); + return label; + } + else { + gtk_label_set_text(GTK_LABEL(current), name); + free(name); + return current; + } +} + +static void +gnc_report_window_view_destroy(GtkObject * obj, gpointer user_data) { + GNCMainChildInfo * mc = user_data; + gnc_report_window * w = mc->user_data; + gnc_main_window_remove_child(gnc_ui_get_data(), mc); + + g_free(mc->toolbar_info); + g_free(mc->menu_info); + g_free(mc); +} + +/******************************************************************** + * report_view_new + * create a new report view. + ********************************************************************/ + +static GtkWidget * +gnc_report_window_view_new(GnomeMDIChild * child, gpointer user_data) { + GNCMainInfo * maininfo = user_data; + GNCMainChildInfo * mc = g_new0(GNCMainChildInfo, 1); + gnc_report_window * win = gnc_report_window_new(mc); + URLType type; + char * url_location = NULL; + char * url_label = NULL; + + mc->contents = gnc_report_window_get_container(win); + mc->app = NULL; + mc->user_data = win; + mc->child = child; + + gnc_main_window_add_child(maininfo, mc); + + type = gnc_html_parse_url(gnc_report_window_get_html(win), + child->name, &url_location, &url_label); + + gnc_html_show_url(gnc_report_window_get_html(win), + type, url_location, url_label, 0); + + gtk_object_set_user_data(GTK_OBJECT(child), mc); + gtk_signal_connect(GTK_OBJECT(child), "destroy", + gnc_report_window_view_destroy, mc); + + gnc_report_window_create_menu(win, mc); + gnc_report_window_create_toolbar(win, mc); + gnc_main_window_create_child_toolbar(maininfo, mc); + + if(mc->menu_info) { + gnome_mdi_child_set_menu_template(child, mc->menu_info); + } + + g_free(url_location); + g_free(url_label); + return mc->contents; +} + + +/******************************************************************** + * gnc_report_window_create_child() + * return an MDI child that will create views of the specified report + * (configstring is the report URL) + ********************************************************************/ + +GnomeMDIChild * +gnc_report_window_create_child(const gchar * configstring) { + GnomeMDIGenericChild * reportchild = + gnome_mdi_generic_child_new(configstring); + GNCMainInfo * maininfo = gnc_ui_get_data(); + + gnome_mdi_generic_child_set_label_func(reportchild, + gnc_report_window_view_labeler, + maininfo); + gnome_mdi_generic_child_set_view_creator(reportchild, + gnc_report_window_view_new, + maininfo); + return GNOME_MDI_CHILD(reportchild); +} + + +/******************************************************************** + * gnc_main_window_open_report() + * open an report in a top level window from an ID number + ********************************************************************/ + +void +gnc_main_window_open_report(int report_id, gint toplevel) { + char * child_name = g_strdup_printf("gnc-report:id=%d", report_id); + gnc_main_window_open_report_url(child_name, toplevel); +} + + +void +gnc_main_window_open_report_url(const char * url, gint toplevel) { + GnomeMDIChild * reportchild = gnc_report_window_create_child(url); + GNCMainInfo * maininfo = gnc_ui_get_data(); + + gnome_mdi_add_child(GNOME_MDI(maininfo->mdi), + GNOME_MDI_CHILD(reportchild)); + if(toplevel) { + gnome_mdi_add_toplevel_view(GNOME_MDI(maininfo->mdi), + GNOME_MDI_CHILD(reportchild)); + } + else { + gnome_mdi_add_view(GNOME_MDI(maininfo->mdi), + GNOME_MDI_CHILD(reportchild)); + } +} + + /******************************************************************** * gnc_report_window_check_urltype * is it OK to show a certain URLType in this window? @@ -141,51 +295,57 @@ gnc_report_window_params_cb(GtkWidget * w, gpointer data) { gnc_report_window * report = data; SCM scm_wintype = gh_eval_str(""); - if(gh_procedure_p(report->scm_options_edit)) { - gh_call2(report->scm_options_edit, - report->scm_options, - report->scm_report); + if((report->scm_report != SCM_BOOL_F) && + (report->scm_options != SCM_BOOL_F)) { + + if(gh_procedure_p(report->scm_options_edit)) { + gh_call2(report->scm_options_edit, + report->scm_options, + report->scm_report); + } + else { + gnc_report_window_default_params_editor(report->scm_options, + report->scm_report); + } } else { - gnc_report_window_default_params_editor(report->scm_options, - report->scm_report); - } - - return TRUE; -} - -static int -gnc_report_window_newwin_cb(GtkWidget * w, gpointer data) { - gnc_report_window * report = data; - gnc_report_window * newwin = gnc_report_window_new(NULL); - SCM get_id = gh_eval_str("gnc:report-id"); - SCM id = gh_call1(get_id, report->scm_report); - - if(gh_number_p(id)) { - gnc_report_window_show_report(newwin, gh_scm2int(id)); + gnc_warning_dialog("There are no options for this report."); } return TRUE; } - static int gnc_report_window_reload_button_cb(GtkWidget * w, gpointer data) { gnc_report_window * report = data; SCM dirty_report = gh_eval_str("gnc:report-set-dirty?!"); - gh_call2(dirty_report, report->scm_report, SCM_BOOL_T); - gnc_html_reload(report->html); + if(report->scm_report != SCM_BOOL_F) { + gh_call2(dirty_report, report->scm_report, SCM_BOOL_T); + gnc_html_reload(report->html); + } return TRUE; } static void gnc_report_window_set_back_button(gnc_report_window * win, int enabled) { - gtk_widget_set_sensitive(win->back_widg, enabled); + GnomeApp * app = win->mc->app; + GnomeUIInfo * info; + + if(app) { + info = gnome_mdi_get_child_menu_info(app); + if(info) gtk_widget_set_sensitive(info[0].widget, enabled); + } } static void gnc_report_window_set_fwd_button(gnc_report_window * win, int enabled) { - gtk_widget_set_sensitive(win->fwd_widg, enabled); + GnomeApp * app = win->mc->app; + GnomeUIInfo * info; + + if(app) { + info = gnome_mdi_get_child_menu_info(app); + if(info) gtk_widget_set_sensitive(info[1].widget, enabled); + } } void @@ -215,7 +375,8 @@ gnc_report_window_load_cb(gnc_html * html, URLType type, SCM inst_options; SCM inst_options_ed; - if(!strncmp("id=", location, 3)) { + if(location && (strlen(location) > 3) && + !strncmp("id=", location, 3)) { sscanf(location+3, "%d", &report_id); } else { @@ -242,6 +403,17 @@ gnc_report_window_load_cb(gnc_html * html, URLType type, win->scm_options = inst_options; scm_protect_object(win->scm_options); + if(win->odb) { + gnc_option_db_destroy(win->odb); + } + win->odb = gnc_option_db_new(win->scm_options); + + win->name_change_callback_id = + gnc_option_db_register_change_callback(win->odb, + gnc_main_window_child_refresh, + win->mc, + "General", "Report name"); + scm_unprotect_object(win->scm_options_edit); win->scm_options_edit = inst_options_ed; scm_protect_object(win->scm_options_edit); @@ -278,78 +450,18 @@ gnc_report_window_load_cb(gnc_html * html, URLType type, static void gnc_report_window_destroy_cb(GtkWidget * w, gpointer data) { gnc_report_window * win = data; - SCM scm_wintype = gh_eval_str(""); - SCM unshow_report = gh_eval_str("gnc:report-unregister-display"); - - if(win->scm_report != SCM_BOOL_F) { - gh_call2(unshow_report, win->scm_report, - gw_wcp_assimilate_ptr(win, scm_wintype)); - } - /* make sure we don't get a double dose -o- destruction */ gtk_signal_disconnect_by_data(GTK_OBJECT(win->container), data); - - /* delete the window from the open list */ - if(win->top_level) { - gnc_unregister_gui_component_by_data (WINDOW_REPORT_CM_CLASS, win); - } - gnc_html_destroy(win->html); - - if(win->popup) { - gtk_widget_destroy(win->popup); - } - win->popup = NULL; - win->container = NULL; - win->html = NULL; - - scm_unprotect_object(win->scm_options); - scm_unprotect_object(win->scm_options_edit); - scm_unprotect_object(win->scm_report); - - g_free(win); -} - - -/******************************************************************** - * gnc_report_window_close_cb - ********************************************************************/ - -static void -gnc_report_window_close_cb(GtkWidget * w, gpointer data) { - gnc_report_window * rw = data; - - if(rw->top_level) { - gnc_close_gui_component_by_data (WINDOW_REPORT_CM_CLASS, rw); - } - else { - gtk_widget_destroy(rw->container); - } -} - - -/******************************************************************** - * gnc_report_window_button_cb - * mouse button clicks - ********************************************************************/ - -static int -gnc_report_window_button_cb(gnc_html * html, GdkEventButton * event, - gpointer user_data) { - gnc_report_window * win = (gnc_report_window *)user_data; - if(event->type == GDK_BUTTON_PRESS) { - if(event->button == 3) { - if(win->popup) { - gnome_popup_menu_do_popup(win->popup, NULL, NULL, - event, (gpointer)win); - return TRUE; - } - } - } - return FALSE; + gnc_report_window_destroy(win); } + +/******************************************************************** + * gnc_report_window_print_cb + ********************************************************************/ + static void gnc_report_window_print_cb(GtkWidget * w, gpointer data) { gnc_report_window * win = data; @@ -381,16 +493,8 @@ gnc_report_window_history_destroy_cb(gnc_html_history_node * node, static void close_handler (gpointer user_data) { - gnc_report_window *win = user_data; - - if (win->top_level) - { - gdk_window_get_geometry (GTK_WIDGET(win->container)->window, NULL, NULL, - &last_width, &last_height, NULL); - - gnc_save_window_size ("report_win", last_width, last_height); - } - + gnc_report_window *win = user_data; + printf("in close handler\n"); gnc_report_window_destroy (win); } @@ -400,19 +504,65 @@ close_handler (gpointer user_data) ********************************************************************/ gnc_report_window * -gnc_report_window_new(GtkWidget * container) { +gnc_report_window_new(GNCMainChildInfo * mc) { gnc_report_window * report = g_new0(gnc_report_window, 1); GtkObject * tlo; GtkWidget * cframe = NULL; - GtkWidget * toolbar = NULL; + report->mc = mc; + report->html = gnc_html_new(); + report->scm_options = SCM_BOOL_F; + report->scm_options_edit = SCM_BOOL_F; + report->scm_report = SCM_BOOL_F; + report->name_change_callback_id = SCM_BOOL_F; + + scm_protect_object(report->scm_options); + scm_protect_object(report->scm_options_edit); + scm_protect_object(report->scm_report); + + gnc_html_history_set_node_destroy_cb(gnc_html_get_history(report->html), + gnc_report_window_history_destroy_cb, + (gpointer)report); + + + report->container = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(report->container), GTK_SHADOW_NONE); + + tlo = GTK_OBJECT(report->container); + gtk_container_add(GTK_CONTAINER(report->container), + gnc_html_get_widget(report->html)); + + gnc_register_gui_component (WINDOW_REPORT_CM_CLASS, NULL, + close_handler, report); + + gnc_html_set_urltype_cb(report->html, gnc_report_window_check_urltype); + gnc_html_set_load_cb(report->html, gnc_report_window_load_cb, report); + + gtk_signal_connect(GTK_OBJECT(report->container), "destroy", + GTK_SIGNAL_FUNC(gnc_report_window_destroy_cb), + report); + + gtk_widget_show_all(report->container); + + return report; +} + + +/******************************************************************** + * gnc_report_window_create_toolbar + * make a toolbar for the top-level MDI app + ********************************************************************/ + +void +gnc_report_window_create_toolbar(gnc_report_window * win, + GNCMainChildInfo * child) { GnomeUIInfo toolbar_data[] = { { GNOME_APP_UI_ITEM, _("Back"), _("Move back one step in the history"), - gnc_report_window_back_cb, report, + gnc_report_window_back_cb, win, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_BACK, @@ -421,7 +571,7 @@ gnc_report_window_new(GtkWidget * container) { { GNOME_APP_UI_ITEM, _("Forward"), _("Move forward one step in the history"), - gnc_report_window_fwd_cb, report, + gnc_report_window_fwd_cb, win, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_FORWARD, @@ -430,7 +580,7 @@ gnc_report_window_new(GtkWidget * container) { { GNOME_APP_UI_ITEM, N_("Reload"), N_("Reload the current report"), - gnc_report_window_reload_button_cb, report, + gnc_report_window_reload_button_cb, win, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_REFRESH, @@ -439,7 +589,7 @@ gnc_report_window_new(GtkWidget * container) { { GNOME_APP_UI_ITEM, N_("Stop"), N_("Cancel outstanding HTML requests"), - gnc_report_window_stop_button_cb, report, + gnc_report_window_stop_button_cb, win, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_STOP, @@ -449,16 +599,16 @@ gnc_report_window_new(GtkWidget * container) { { GNOME_APP_UI_ITEM, _("Export"), _("Export HTML-formatted report to file"), - gnc_report_window_export_button_cb, report, + gnc_report_window_export_button_cb, win, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_CONVERT, 0, 0, NULL }, { GNOME_APP_UI_ITEM, - _("Parameters"), + _("Options"), _("Edit report options"), - gnc_report_window_params_cb, report, + gnc_report_window_params_cb, win, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_PROPERTIES, @@ -467,93 +617,29 @@ gnc_report_window_new(GtkWidget * container) { { GNOME_APP_UI_ITEM, _("Print"), _("Print report window"), - gnc_report_window_print_cb, report, + gnc_report_window_print_cb, win, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_PRINT, 0, 0, NULL }, - GNOMEUIINFO_SEPARATOR, - { GNOME_APP_UI_ITEM, - _("New window"), - _("Open this report in a new window"), - gnc_report_window_newwin_cb, report, - NULL, - GNOME_APP_PIXMAP_STOCK, - GNOME_STOCK_PIXMAP_NEW, - 0, 0, NULL - }, - { GNOME_APP_UI_ITEM, - _("Close"), - _("Close this report window"), - gnc_report_window_close_cb, report, - NULL, - GNOME_APP_PIXMAP_STOCK, - GNOME_STOCK_PIXMAP_CLOSE, - 0, 0, NULL - }, GNOMEUIINFO_END }; - report->html = gnc_html_new(); - report->scm_options = SCM_BOOL_F; - report->scm_options_edit = SCM_BOOL_F; - report->scm_report = SCM_BOOL_F; + child->toolbar_info = + g_memdup(toolbar_data, sizeof(toolbar_data)); + child->toolbar_size = sizeof(toolbar_data) / sizeof(GnomeUIInfo); +} - gnc_html_history_set_node_destroy_cb(gnc_html_get_history(report->html), - gnc_report_window_history_destroy_cb, - (gpointer)report); - - scm_protect_object(report->scm_options); - scm_protect_object(report->scm_options_edit); - scm_protect_object(report->scm_report); - if(container) { - report->container = container; - report->top_level = FALSE; - report->popup = gnome_popup_menu_new(toolbar_data); - gtk_container_add(GTK_CONTAINER(container), - gnc_html_get_widget(report->html)); - } - else { - report->container = create_Report_Window(); - report->top_level = TRUE; - report->popup = NULL; - - tlo = GTK_OBJECT(report->container); - toolbar = gtk_object_get_data(tlo, "report_toolbar"); - cframe = gtk_object_get_data(tlo, "report_frame"); - gnome_app_fill_toolbar(GTK_TOOLBAR(toolbar), toolbar_data, NULL); - gtk_container_add(GTK_CONTAINER(cframe), - gnc_html_get_widget(report->html)); - gnc_register_gui_component (WINDOW_REPORT_CM_CLASS, NULL, - close_handler, report); - } - - report->back_widg = toolbar_data[0].widget; - report->fwd_widg = toolbar_data[1].widget; - - gnc_html_set_urltype_cb(report->html, gnc_report_window_check_urltype); - gnc_html_set_load_cb(report->html, gnc_report_window_load_cb, report); - gnc_html_set_button_cb(report->html, gnc_report_window_button_cb, report); - - gtk_signal_connect(GTK_OBJECT(report->container), "destroy", - GTK_SIGNAL_FUNC(gnc_report_window_destroy_cb), - report); - - if (report->top_level) { - if (last_width == 0) - gnc_get_window_size("report_win", &last_width, &last_height); - - gtk_window_set_default_size(GTK_WINDOW(report->container), - last_width, last_height); - - gnc_window_adjust_for_screen (GTK_WINDOW(report->container)); - } - - gtk_widget_show_all(report->container); - - return report; +/******************************************************************** + * gnc_report_window_create_menu + * child menu for reports (none currently) + ********************************************************************/ +void +gnc_report_window_create_menu(gnc_report_window * report, + GNCMainChildInfo * child) { + child->menu_info = NULL; } @@ -565,9 +651,24 @@ gnc_report_window_new(GtkWidget * container) { void gnc_report_window_destroy(gnc_report_window * win) { - if (!win) return; + SCM scm_wintype = gh_eval_str(""); + SCM unshow_report = gh_eval_str("gnc:report-unregister-display"); - gtk_widget_destroy(GTK_WIDGET(win->container)); + if(win->scm_report != SCM_BOOL_F) { + gh_call2(unshow_report, win->scm_report, + gw_wcp_assimilate_ptr(win, scm_wintype)); + } + + gnc_html_destroy(win->html); + + win->container = NULL; + win->html = NULL; + + scm_unprotect_object(win->scm_options); + scm_unprotect_object(win->scm_options_edit); + scm_unprotect_object(win->scm_report); + + g_free(win); } gnc_html * @@ -575,6 +676,16 @@ gnc_report_window_get_html(gnc_report_window * report) { return report->html; } +GtkWidget * +gnc_report_window_get_container(gnc_report_window * report) { + return report->container; +} + +SCM +gnc_report_window_get_report(gnc_report_window * report) { + return report->scm_report; +} + void gnc_report_window_show_report(gnc_report_window * report, int report_id) { char * location = g_strdup_printf("id=%d", report_id); @@ -584,11 +695,8 @@ gnc_report_window_show_report(gnc_report_window * report, int report_id) { void reportWindow(int report_id) { - gnc_report_window * win; - gnc_set_busy_cursor (NULL, TRUE); - win = gnc_report_window_new(NULL); - gnc_report_window_show_report(win, report_id); + gnc_main_window_open_report(report_id, FALSE); gnc_unset_busy_cursor (NULL); } @@ -612,6 +720,10 @@ gnc_print_report (int report_id) } +/******************************************************************** + * default parameters editor handling + ********************************************************************/ + struct report_default_params_data { GNCOptionWin * win; GNCOptionDB * db; @@ -673,3 +785,4 @@ gnc_report_window_default_params_editor(SCM options, SCM report) { (gpointer)prm); } + diff --git a/src/gnome/window-report.h b/src/gnome/window-report.h index 47824cada3..b6fcfb3220 100644 --- a/src/gnome/window-report.h +++ b/src/gnome/window-report.h @@ -28,20 +28,32 @@ #include "gnc-html.h" #include "dialog-options.h" +#include "window-main.h" typedef struct _gnc_report_window gnc_report_window; /** PROTOTYPES ******************************************************/ -gnc_report_window * gnc_report_window_new(GtkWidget * container); +gnc_report_window * gnc_report_window_new(GNCMainChildInfo * mc); void gnc_report_window_destroy(gnc_report_window * rep); void gnc_report_window_show_report(gnc_report_window * rw, int id); void gnc_report_window_reload(gnc_report_window * rw); gnc_html * gnc_report_window_get_html(gnc_report_window * rw); +GtkWidget * gnc_report_window_get_container(gnc_report_window * rw); +SCM gnc_report_window_get_report(gnc_report_window * rw); + +void gnc_report_window_create_menu(gnc_report_window * report, + GNCMainChildInfo * child); +void gnc_report_window_create_toolbar(gnc_report_window * report, + GNCMainChildInfo * child); void gnc_report_window_default_params_editor(SCM options, SCM report); -void reportWindow(int id); -void gnc_print_report (int report_id); +void gnc_main_window_open_report (int report_id, gint toplevel); +void gnc_main_window_open_report_url (const char * url, gint toplevel); + +GnomeMDIChild * gnc_report_window_create_child(const gchar * url); +void reportWindow(int id); +void gnc_print_report (int report_id); #endif diff --git a/src/scm/bootstrap.scm.in b/src/scm/bootstrap.scm.in index 85bb80361f..d5944234c6 100644 --- a/src/scm/bootstrap.scm.in +++ b/src/scm/bootstrap.scm.in @@ -60,6 +60,11 @@ (if (not result) (set! gnc:*load-slib-backup* #t))) +;; Test for simple-format +(if (not (defined? 'simple-format)) + (begin + (require 'format) + (define simple-format format))) (define (build-path firstelement . restofpath) (define separator "/") diff --git a/src/scm/extensions.scm b/src/scm/extensions.scm index 8e75005ba6..21ad7b40ae 100644 --- a/src/scm/extensions.scm +++ b/src/scm/extensions.scm @@ -57,15 +57,15 @@ (gnc:make-extension 'separator #f #f path #f)) -(define (gnc:extensions-menu-setup win) +(define (gnc:extensions-menu-setup) (define menu (gnc:make-menu "Extensions" (list "_Settings"))) - - (define export-item - (gnc:make-menu-item (N_ "Export data as text (Danger: Unfinished)") - (N_ "Export data as text.") - (list "Extensions" "") - (lambda () (gnc:main-win-account-group-write win)))) - + +; (define export-item +; (gnc:make-menu-item (N_ "Export data as text (Danger: Unfinished)") +; (N_ "Export data as text.") +; (list "Extensions" "") +; (lambda () (gnc:main-win-account-group-write win)))) + (define progress-item (gnc:make-menu-item (N_ "Test progress dialog") (N_ "Test progress dialog") @@ -91,11 +91,11 @@ (gnc:progress-dialog-destroy dialog))))) (gnc:add-extension menu) - (gnc:add-extension export-item) +; (gnc:add-extension export-item) (gnc:add-extension progress-item)) (if (gnc:debugging?) - (gnc:hook-add-dangler gnc:*main-window-opened-hook* + (gnc:hook-add-dangler gnc:*ui-startup-hook* gnc:extensions-menu-setup)) diff --git a/src/scm/hooks.scm b/src/scm/hooks.scm index 676f62153c..1e96efebaf 100644 --- a/src/scm/hooks.scm +++ b/src/scm/hooks.scm @@ -85,16 +85,16 @@ 'shutdown-hook "Functions to run at guile shutdown. Hook args: ()")) +(define gnc:*ui-startup-hook* + (gnc:hook-define + 'ui-startup-hook + "Functions to run when the ui comes up. Hook args: ()")) + (define gnc:*ui-shutdown-hook* (gnc:hook-define 'ui-shutdown-hook "Functions to run at ui shutdown. Hook args: ()")) -(define gnc:*main-window-opened-hook* - (gnc:hook-define - 'main-window-opened-hook - "Functions to run whenever the main window is opened. Hook args: (window)")) - (define gnc:*file-opened-hook* (gnc:hook-define 'file-opened-hook diff --git a/src/scm/html-style-sheet.scm b/src/scm/html-style-sheet.scm index b7a40c13a9..6af05018d6 100644 --- a/src/scm/html-style-sheet.scm +++ b/src/scm/html-style-sheet.scm @@ -61,6 +61,7 @@ (define (gnc:html-style-sheet-template-find tname) (hash-ref *gnc:_style-sheet-templates_* tname)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; define-html-style-sheet ;; actually defines an . @@ -91,7 +92,7 @@ (define (make-record-type "" - '(name options renderer style))) + '(name type options renderer style))) (define gnc:html-style-sheet? (record-predicate )) @@ -102,6 +103,12 @@ (define gnc:html-style-sheet-set-name! (record-modifier 'name)) +(define gnc:html-style-sheet-type + (record-accessor 'type)) + +(define gnc:html-style-sheet-set-type! + (record-modifier 'type)) + (define gnc:html-style-sheet-options (record-accessor 'options)) @@ -120,6 +127,26 @@ (define gnc:html-style-sheet-style (record-accessor 'style)) +(define (gnc:save-style-sheet-options) + (let ((port (open (build-path (getenv "HOME") ".gnucash" "config.auto") + (logior O_WRONLY O_CREAT O_APPEND)))) + (hash-fold + (lambda (id ss-obj p) + (let ((code + (string-append + (format #f "(let ((template (gnc:html-style-sheet-template-find ~S)))\n" + (gnc:html-style-sheet-type ss-obj)) + " (if template \n" + " (let ((options ((gnc:html-style-sheet-template-options-generator template)))) \n" + (gnc:generate-restore-forms + (gnc:html-style-sheet-options ss-obj) "options") + (format #f " (gnc:restore-html-style-sheet ~S ~S options))))\n" + (gnc:html-style-sheet-name ss-obj) + (gnc:html-style-sheet-type ss-obj))))) + (display code port)) + #f) #f *gnc:_style-sheets_*) + (close port))) + (define (gnc:html-style-sheet-set-style! sheet tag . rest) (let ((newstyle #f)) (if (and (= (length rest) 2) @@ -135,7 +162,7 @@ (let* ((template (gnc:html-style-sheet-template-find template-name))) (if template (let ((rv (gnc:make-html-style-sheet-internal - style-sheet-name + style-sheet-name template-name ((gnc:html-style-sheet-template-options-generator template)) (gnc:html-style-sheet-template-renderer template) (gnc:make-html-style-table)))) @@ -161,6 +188,36 @@ rv) #f))) +(define (gnc:restore-html-style-sheet style-sheet-name template-name options) + (let* ((template (gnc:html-style-sheet-template-find template-name))) + (if template + (let ((rv (gnc:make-html-style-sheet-internal + style-sheet-name template-name + options + (gnc:html-style-sheet-template-renderer template) + (gnc:make-html-style-table)))) + ;; set up the fallback data styles for every rendered document + (gnc:html-style-sheet-set-style! + rv "" + gnc:default-html-string-renderer #f) + + (gnc:html-style-sheet-set-style! + rv "" + gnc:default-html-gnc-numeric-renderer #f) + + (gnc:html-style-sheet-set-style! + rv "" + gnc:default-html-number-renderer #f) + + (gnc:html-style-sheet-set-style! + rv "" + gnc:default-html-gnc-monetary-renderer #f) + + ;; store it in the style sheet hash + (hash-set! *gnc:_style-sheets_* style-sheet-name rv) + rv) + #f))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; html-style-sheet-apply-changes diff --git a/src/scm/main.scm b/src/scm/main.scm index d5fb30f977..7ac4866147 100644 --- a/src/scm/main.scm +++ b/src/scm/main.scm @@ -85,7 +85,6 @@ (cond ((gnc:ui-is-running?) (if (not (gnc:ui-is-terminating?)) (begin - (gnc:ui-destroy-all-subwindows) (if (gnc:file-query-save) (begin (gnc:hook-run-danglers gnc:*ui-shutdown-hook*) @@ -135,8 +134,12 @@ ;; add a hook to shut down the expression parser (gnc:hook-add-dangler gnc:*shutdown-hook* gnc:exp-parser-shutdown) - ;; add a hook to save the user configs on shutdown - (gnc:hook-add-dangler gnc:*shutdown-hook* gnc:save-global-options) + ;; add a hook to save the user configs on shutdown. this saves + ;; global options plus (for the moment) saved report and account + ;; tree window parameters. reports and parameters should probably + ;; be in a separate file, with the main data file, or something + ;; else. + (gnc:hook-add-dangler gnc:*shutdown-hook* gnc:save-all-options) ;; add a hook to shut down the C side options code (gnc:hook-add-dangler gnc:*shutdown-hook* gnc:c-options-shutdown) diff --git a/src/scm/options.scm b/src/scm/options.scm index 06102f0d67..32151c703c 100644 --- a/src/scm/options.scm +++ b/src/scm/options.scm @@ -945,9 +945,11 @@ (gnc:option-db-register-option db_handle option)) options)) -(define (gnc:save-options options options-string file header) +(define (gnc:save-options options options-string file header truncate?) (let ((code (gnc:generate-restore-forms options options-string)) - (port (open file (logior O_WRONLY O_CREAT O_TRUNC)))) + (port (if truncate? + (open file (logior O_WRONLY O_CREAT O_TRUNC)) + (open file (logior O_WRONLY O_CREAT O_APPEND))))) (if port (begin (display header port) (display code port) diff --git a/src/scm/path.scm b/src/scm/path.scm index 7406ff6370..7ac3fc6913 100644 --- a/src/scm/path.scm +++ b/src/scm/path.scm @@ -69,7 +69,7 @@ (build-path (getenv "HOME") ".gnucash" "config.user")) (auto-file (build-path (getenv "HOME") ".gnucash" "config.auto"))) - + (if (access? user-file F_OK) (if (false-if-exception (primitive-load user-file)) (set! user-config-loaded? #t) diff --git a/src/scm/prefs.scm b/src/scm/prefs.scm index dedd5690f3..81d30e6b9c 100644 --- a/src/scm/prefs.scm +++ b/src/scm/prefs.scm @@ -71,6 +71,35 @@ (define (gnc:global-options-clear-changes) (gnc:options-clear-changes gnc:*options-entries*)) +;; save-all-options: this is the actual hook that gets called at +;; shutdown. right now, we put all the options in the same file so +;; it's important to make sure it happens in this order. later the +;; hook should probably revert back to just save-global-options. +(define (gnc:save-all-options) + (gnc:save-global-options) + (gnc:save-report-options) + (gnc:save-acct-tree-options) + (gnc:save-style-sheet-options)) + +(define (gnc:save-acct-tree-options) + (let ((port (open (build-path (getenv "HOME") ".gnucash" "config.auto") + (logior O_WRONLY O_CREAT O_APPEND))) + (maxid 0)) + (hash-fold + (lambda (id optobj p) + (let ((code + (string-append + "(let ((options (gnc:make-acct-tree-window-options)))\n" + (gnc:generate-restore-forms optobj "options") + (simple-format + #f " (hash-set! gnc:*acct-tree-options* ~A options))\n" + id)))) + (display code port) + (if (> id maxid) (set! maxid id))) + #f) #f gnc:*acct-tree-options*) + (format port " (set! gnc:*acct-tree-id* ~A)\n\n" (+ 1 maxid)) + (close port))) + (define (gnc:save-global-options) (gnc:make-home-dir) (gnc:save-options gnc:*options-entries* @@ -80,7 +109,8 @@ "(gnc:config-file-format-version 1)\n\n" ";" (_ "GnuCash Configuration Options") - "\n"))) + "\n") + #t)) (define (gnc:config-file-format-version version) #t) @@ -121,55 +151,7 @@ (define (gnc:get-credit-string type) (_ (assoc-ref gnc:*credit-strings* type))) - -;; Main Window options - -(gnc:register-configuration-option - (gnc:make-simple-boolean-option - (N_ "Main Window") (N_ "Double click expands parent accounts") - "a" (N_ "Double clicking on an account with children expands \ -the account instead of opening a register.") #f)) - -(gnc:register-configuration-option - (gnc:make-simple-boolean-option - (N_ "Main Window") (N_ "Reports appear in Main Window") - "a" (N_ "By default, reports go into the main window instead of a separate window.") #t)) - -(gnc:register-configuration-option - (gnc:make-list-option - (N_ "Main Window") (N_ "Account types to display") - "b" "" - (list 'bank 'cash 'credit 'asset 'liability 'stock - 'mutual 'currency 'income 'expense 'equity) - (list (list->vector (list 'bank (N_ "Bank") "")) - (list->vector (list 'cash (N_ "Cash") "")) - (list->vector (list 'credit (N_ "Credit") "")) - (list->vector (list 'asset (N_ "Asset") "")) - (list->vector (list 'liability (N_ "Liability") "")) - (list->vector (list 'stock (N_ "Stock") "")) - (list->vector (list 'mutual (N_ "Mutual Fund") "")) - (list->vector (list 'currency (N_ "Currency") "")) - (list->vector (list 'income (N_ "Income") "")) - (list->vector (list 'expense (N_ "Expense") "")) - (list->vector (list 'equity (N_ "Equity") ""))))) - -(gnc:register-configuration-option - (gnc:make-list-option - (N_ "Main Window") (N_ "Account fields to display") - "c" "" - (list 'description 'total) - (list (list->vector (list 'type (N_ "Type") "")) - (list->vector (list 'code (N_ "Code") "")) - (list->vector (list 'description (N_ "Description") "")) - (list->vector (list 'notes (N_ "Notes") "")) - (list->vector (list 'currency (N_ "Currency") "")) - (list->vector (list 'security (N_ "Security") "")) - (list->vector (list 'balance (N_ "Balance") "")) - (list->vector (list 'total (N_ "Total") ""))))) - - ;; International options - (gnc:register-configuration-option (gnc:make-multichoice-option (N_ "International") (N_ "Date Format") @@ -519,6 +501,81 @@ transaction.") #t)) "d" (N_ "Host to connect to for user registration and support services") "www.gnumatic.com")) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; account tree options +;; these are here because they used to be global preferences; +;; they should probably move elsewhere. +;; +;; like reports, we have an integer tree id that is the index into a +;; global hash table, and URLs of the form gnc-acct-tree:id=%d will +;; open to the right window. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define gnc:*acct-tree-options* (make-hash-table 11)) +(define gnc:*acct-tree-id* 0) + +(define (gnc:find-acct-tree-window-options id) + (hash-ref gnc:*acct-tree-options* id)) + +(define (gnc:make-acct-tree-window-options) + (let* ((options (gnc:new-options)) + (add-option + (lambda (opt) + (gnc:register-option options opt)))) + (add-option + (gnc:make-string-option + (N_ "Account Tree") (N_ "Name of account view") + "a" (N_ "If you keep multiple account views open, it may be helpful + to give each one a descriptive name") (N_ "Accounts"))) + (add-option + (gnc:make-simple-boolean-option + (N_ "Account Tree") (N_ "Double click expands parent accounts") + "a" (N_ "Double clicking on an account with children expands \ + the account instead of opening a register.") #f)) + (add-option + (gnc:make-list-option + (N_ "Account Tree") (N_ "Account types to display") + "b" "" + (list 'bank 'cash 'credit 'asset 'liability 'stock + 'mutual 'currency 'income 'expense 'equity) + (list (list->vector (list 'bank (N_ "Bank") "")) + (list->vector (list 'cash (N_ "Cash") "")) + (list->vector (list 'credit (N_ "Credit") "")) + (list->vector (list 'asset (N_ "Asset") "")) + (list->vector (list 'liability (N_ "Liability") "")) + (list->vector (list 'stock (N_ "Stock") "")) + (list->vector (list 'mutual (N_ "Mutual Fund") "")) + (list->vector (list 'currency (N_ "Currency") "")) + (list->vector (list 'income (N_ "Income") "")) + (list->vector (list 'expense (N_ "Expense") "")) + (list->vector (list 'equity (N_ "Equity") ""))))) + + (add-option + (gnc:make-list-option + (N_ "Account Tree") (N_ "Account fields to display") + "c" "" + (list 'description 'total) + (list (list->vector (list 'type (N_ "Type") "")) + (list->vector (list 'code (N_ "Code") "")) + (list->vector (list 'description (N_ "Description") "")) + (list->vector (list 'notes (N_ "Notes") "")) + (list->vector (list 'currency (N_ "Currency") "")) + (list->vector (list 'security (N_ "Security") "")) + (list->vector (list 'balance (N_ "Balance") "")) + (list->vector (list 'total (N_ "Total") ""))))) + + options)) + +(define (gnc:make-new-acct-tree-window) + (let ((options (gnc:make-acct-tree-window-options)) + (id gnc:*acct-tree-id*)) + (hash-set! gnc:*acct-tree-options* id options) + (set! gnc:*acct-tree-id* (+ 1 id)) + (cons options id))) + +(define (gnc:free-acct-tree-window id) + (hash-remove! gnc:*acct-tree-options* id)) + ;;; Configuation variables (define gnc:*arg-show-version* diff --git a/src/scm/report.scm b/src/scm/report.scm index 23ee0d2823..84179f870a 100644 --- a/src/scm/report.scm +++ b/src/scm/report.scm @@ -38,14 +38,19 @@ (define *gnc:_reports_* (make-hash-table 23)) (define *gnc:_report-next-serial_* 0) -(define (gnc:report-menu-setup win) - (define menu (gnc:make-menu "_Reports" (list "_Accounts"))) - (define tax-menu (gnc:make-menu (N_ "_Taxes") (list "_Reports" ""))) - (define income-expense-menu - (gnc:make-menu (N_ "_Income & Expense") (list "_Reports" ""))) - (define asset-liability-menu - (gnc:make-menu (N_ "_Assets & Liabilities") (list "_Reports" ""))) +(define (gnc:report-menu-setup) + ;; since this menu gets added to every child window, we say it + ;; comes after the "_File" menu. + (define menu (gnc:make-menu "New _Report" + (list "_File" "New _Account Tree"))) (define menu-namer (gnc:new-menu-namer)) + (define tax-menu (gnc:make-menu (N_ "_Taxes") + (list "_File" "New _Report" ""))) + (define income-expense-menu + (gnc:make-menu (N_ "_Income & Expense") (list "_File" "New _Report" ""))) + (define asset-liability-menu + (gnc:make-menu (N_ "_Assets & Liabilities") + (list "_File" "New _Report" ""))) (define menu-hash (make-hash-table 23)) (define (add-report-menu-item name report) @@ -55,57 +60,60 @@ (menu-name (gnc:report-menu-name report)) (menu-tip (gnc:report-menu-tip report)) (item #f)) - + (if (not menu-path) (set! menu-path '("")) (set! menu-path (append menu-path '("")))) - - (set! menu-path (cons "_Reports" menu-path)) - + + (set! menu-path (append (list "_File" "New _Report") menu-path)) + (if menu-name (set! name menu-name)) - + (if (not menu-tip) (set! menu-tip (sprintf #f (_ "Display the %s report") name))) - + (set! item (gnc:make-menu-item ((menu-namer 'add-name) name) menu-tip menu-path (lambda () - (gnc:backtrace-if-exception - (lambda () - (let ((rept (gnc:make-report - (gnc:report-template-name report)))) - (if (gnc:option-value - (gnc:lookup-global-option - "Main Window" "Reports appear in Main Window")) - (gnc:report-in-main-window rept) - (gnc:report-window rept)))))))) + (let ((rept (gnc:make-report + (gnc:report-template-name report)))) + (gnc:main-window-open-report rept #f))))) (gnc:add-extension item)))) + + (gnc:add-extension menu) ;; add the menu option to edit style sheets - (gnc:add-extension menu) (gnc:add-extension (gnc:make-menu-item ((menu-namer 'add-name) (_ "Style Sheets...")) (_ "Edit report style sheets.") - (list "_Reports" "") + (list "_Settings" "") (lambda () (gnc:style-sheet-dialog-open)))) - (gnc:add-extension - (gnc:make-separator (list "_Reports" ""))) - (gnc:add-extension tax-menu) (gnc:add-extension income-expense-menu) (gnc:add-extension asset-liability-menu) - + ;; push reports (new items added on top of menu) (hash-for-each add-report-menu-item *gnc:_report-templates_*)) +(define (gnc:save-report-options) + (let ((port (open (build-path (getenv "HOME") ".gnucash" "config.auto") + (logior O_WRONLY O_CREAT O_APPEND)))) + (hash-fold + (lambda (id report-obj p) + (if (not (null? (gnc:report-display-list report-obj))) + (let ((code (gnc:report-generate-restore-forms report-obj))) + (display code port))) + #f) #f *gnc:_reports_*) + (close port))) + (define (make-record-type "" ;; The data items in a report record @@ -164,6 +172,12 @@ (define gnc:report-menu-tip (record-accessor 'menu-tip)) +(define (gnc:report-template-new-options/name template-name) + (let ((templ (hash-ref *gnc:_report-templates_* template-name))) + (if templ + (gnc:report-template-new-options templ) + #f))) + (define (gnc:report-template-new-options report-template) (let ((generator (gnc:report-template-options-generator report-template)) (namer @@ -231,21 +245,16 @@ (record-modifier 'children)) (define (gnc:report-add-child! report child) - (gnc:report-add-parent! child report) + (gnc:report-set-children! + report (cons (gnc:report-id child) (gnc:report-children report)))) + +(define (gnc:report-add-child-by-id! report child) (gnc:report-set-children! report (cons child (gnc:report-children report)))) -(define (gnc:report-add-child-by-id! report child) - (let ((childrep (gnc:find-report child))) - (if childrep - (begin - (gnc:report-add-parent! childrep report) - (gnc:report-set-children! - report (cons childrep (gnc:report-children report))))))) - (define (gnc:report-add-parent! report parent) (gnc:report-set-parents! - report (cons parent (gnc:report-parents report)))) + report (cons (gnc:report-id parent) (gnc:report-parents report)))) (define gnc:report-dirty? (record-accessor 'dirty?)) @@ -260,7 +269,7 @@ ;; mark the parents as dirty (for-each (lambda (parent) - (gnc:report-set-dirty?! parent val)) + (gnc:report-set-dirty?! (gnc:find-report parent) val)) (gnc:report-parents report)) ;; reload the window @@ -283,18 +292,27 @@ (define (gnc:report-register-display report window) (if (and window report) - (if (not (member window (gnc:report-display-list report))) - (gnc:report-set-display-list! - report - (cons window (gnc:report-display-list report)))))) + (begin + (if (not (member window (gnc:report-display-list report))) + (gnc:report-set-display-list! + report + (cons window (gnc:report-display-list report)))) + (for-each + (lambda (rep) + (gnc:report-register-display (gnc:find-report rep) window)) + (gnc:report-children report))))) (define (gnc:report-unregister-display report window) (if (and window report) - (if (member window (gnc:report-display-list report)) - (gnc:report-set-display-list! - report - (delete window (gnc:report-display-list report)))))) - + (begin + (if (member window (gnc:report-display-list report)) + (gnc:report-set-display-list! + report + (delete window (gnc:report-display-list report)))) + (for-each + (lambda (rep) + (gnc:report-unregister-display (gnc:find-report rep) window)) + (gnc:report-children report))))) (define (gnc:make-report template-name . rest) (let ((r ((record-constructor ) @@ -312,6 +330,14 @@ (hash-set! *gnc:_reports_* (gnc:report-id r) r) id)) +(define (gnc:restore-report id template-name parents children options) + (let ((r ((record-constructor ) + template-name id options parents children #t '() #f))) + (if (>= id *gnc:_report-next-serial_*) + (set! *gnc:_report-next-serial_* (+ id 1))) + (hash-set! *gnc:_reports_* id r))) + + (define (gnc:make-report-options template-name) (let ((template (hash-ref *gnc:_report-templates_* template-name))) (if template @@ -382,13 +408,25 @@ (let ((r (hash-ref *gnc:_reports_* id))) (for-each (lambda (child) - (gnc:report-remove-by-id (gnc:report-id child))) + (gnc:report-remove-by-id child)) (gnc:report-children r)) (hash-remove! *gnc:_reports_* id))) (define (gnc:find-report id) (hash-ref *gnc:_reports_* id)) +(define (gnc:report-generate-restore-forms report) + (string-append + (simple-format + #f "(let ((options (gnc:report-template-new-options/name ~S)))\n" + (gnc:report-type report)) + (gnc:generate-restore-forms (gnc:report-options report) + "options") + (simple-format #f " (gnc:restore-report ~S ~S '~S '~S options))\n" + (gnc:report-id report) (gnc:report-type report) + (gnc:report-parents report) + (gnc:report-children report)))) + (define (gnc:backtrace-if-exception proc . args) (define (dumper key . args) (let ((stack (make-stack #t dumper))) @@ -453,7 +491,6 @@ html) #f)))) - (define (gnc:report-run id) (gnc:backtrace-if-exception (lambda () @@ -469,4 +506,4 @@ html) #f))))) -(gnc:hook-add-dangler gnc:*main-window-opened-hook* gnc:report-menu-setup) +(gnc:hook-add-dangler gnc:*ui-startup-hook* gnc:report-menu-setup) diff --git a/src/scm/report/account-summary.scm b/src/scm/report/account-summary.scm index 9a2b4c21e1..7be29cfd31 100644 --- a/src/scm/report/account-summary.scm +++ b/src/scm/report/account-summary.scm @@ -74,15 +74,16 @@ optname-display-depth optname-show-subaccounts optname-accounts "a" 1 (lambda () - (let ((current-accounts (gnc:get-current-accounts))) + ;; FIXME : gnc:get-current-accounts disappeared + (let ((current-accounts '())) (cond ((not (null? current-accounts)) current-accounts) (else (gnc:group-get-account-list (gnc:get-current-group))))))) - + ;; with or without grouping (gnc:options-add-group-accounts! options pagename-accounts optname-group-accounts "b" #t) - + ;; new options here (gnc:register-option options diff --git a/src/scm/report/average-balance.scm b/src/scm/report/average-balance.scm index 86cd6b0ee9..cb88717db7 100644 --- a/src/scm/report/average-balance.scm +++ b/src/scm/report/average-balance.scm @@ -37,7 +37,8 @@ pagename-general (N_ "Accounts") "d" (N_ "Do transaction report on this account") (lambda () - (let ((current-accounts (gnc:get-current-accounts))) + ;; FIXME : gnc:get-current-accounts disappeared + (let ((current-accounts '())) ;; If some accounts were selected, use those (cond ((not (null? current-accounts)) current-accounts) diff --git a/src/scm/report/budget-report.scm b/src/scm/report/budget-report.scm index a1333557ae..25c9d13409 100644 --- a/src/scm/report/budget-report.scm +++ b/src/scm/report/budget-report.scm @@ -1315,5 +1315,5 @@ ; gnc:budget-entries ; (lambda () (display "Applied the budget.\n")))))); - (gnc:hook-add-dangler gnc:*main-window-opened-hook* - (lambda (win) (gnc:add-extension budget-item)))) + (gnc:hook-add-dangler gnc:*ui-startup-hook* + (lambda () (gnc:add-extension budget-item)))) diff --git a/src/scm/report/hello-world.scm b/src/scm/report/hello-world.scm index bc6ee5a1ac..508e6cad74 100644 --- a/src/scm/report/hello-world.scm +++ b/src/scm/report/hello-world.scm @@ -162,7 +162,9 @@ (gnc:make-account-list-option (N_ "Hello Again") (N_ "An account list option") "g" (N_ "This is an account list option") - (lambda () (gnc:get-current-accounts)) + ;; FIXME : this used to be gnc:get-current-accounts, but + ;; that doesn't exist any more. + (lambda () '()) #f #t)) ;; This is a list option. The user can select one or (possibly) diff --git a/src/scm/report/transaction-report.scm b/src/scm/report/transaction-report.scm index c0ac22b047..fdbd5a8466 100644 --- a/src/scm/report/transaction-report.scm +++ b/src/scm/report/transaction-report.scm @@ -332,7 +332,8 @@ (N_ "General") (N_ "Account") "c" (N_ "Do transaction report on these accounts") (lambda () - (let ((current-accounts (gnc:get-current-accounts)) + ;; FIXME : gnc:get-current-accounts disappeared. + (let ((current-accounts '()) (num-accounts (gnc:group-get-num-accounts (gnc:get-current-group))) (first-account (gnc:group-get-account diff --git a/src/scm/tip-of-the-day.scm b/src/scm/tip-of-the-day.scm index 2387841458..7d8baa7d0b 100644 --- a/src/scm/tip-of-the-day.scm +++ b/src/scm/tip-of-the-day.scm @@ -95,11 +95,13 @@ (gnc:read-tips) -(let ((mainopen-hook (gnc:hook-lookup 'main-window-opened-hook))) - (gnc:hook-add-dangler - mainopen-hook - (lambda (window) - (let ((tip-opt (gnc:lookup-global-option "General" - "Display \"Tip of the Day\""))) - (if (gnc:option-value tip-opt) - (gnc:ui-totd-dialog-create-and-run)))))) +(gnc:hook-add-dangler + gnc:*ui-startup-hook* + (lambda () + (let ((tip-opt (gnc:lookup-global-option "General" + "Display \"Tip of the Day\""))) + (if (gnc:option-value tip-opt) + (gnc:ui-totd-dialog-create-and-run))))) + + +