From a521262717ffde6945d3d3fe723310f5ba397949 Mon Sep 17 00:00:00 2001 From: Chris Shoemaker Date: Mon, 23 Jan 2006 17:38:13 +0000 Subject: [PATCH] Major step in extraction of application startup from guile. Details: Remove the last bits of libguile from top-level.[ch]. Change the gui initialization funtions so they can be called from C. Drop some gwrappers for gui initialization functions. Process the --nofile and filename command-line options from C. Drastic simpilification of main.scm. Initialize the gui and enter the gtk event-loop from C. Even though there's some more clean-up to do, this patch does mark a certain milestone: A developer seeking to understand and/or modify GnuCash's startup process can now essentially ignore the guile portion. Most parts of our startup now look pretty typical for a gnome-2 app. The parts that remain firmly in guile are initialization of the report menus and the installation of price-quote sources. Caveat: We have multiple mechanisms for handling the filename argument string -- some in guile and some in C. The C-side mechanisms (in engine/gnc-filepath-utils.c) seem a little nicer than the guile ones (in main.scm). They have slightly different behavior (e.g. which paths they'll search for data files.) They both handle URIs and making absolute paths out of relative ones. This patch switches from using the guile functions to the C function. I've tested that the common cases are handled the same way, but it wouldn't surprise me if some corner-cases are not. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@12956 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/bin/gnucash-bin.c | 52 ++++++++++++++++-- src/gnome/Makefile.am | 1 + src/gnome/gw-gnc-spec.scm | 24 -------- src/gnome/top-level.c | 68 +++++++++++------------ src/gnome/top-level.h | 15 +++-- src/scm/Makefile.am | 2 - src/scm/build-config.scm.in | 2 - src/scm/main-window.scm | 7 +-- src/scm/main.scm | 106 +++++++++--------------------------- 9 files changed, 116 insertions(+), 161 deletions(-) diff --git a/src/bin/gnucash-bin.c b/src/bin/gnucash-bin.c index 59982bf3de..4f681cbc36 100644 --- a/src/bin/gnucash-bin.c +++ b/src/bin/gnucash-bin.c @@ -43,15 +43,22 @@ #include "gnc-main.h" #include "gnc-splash.h" #include "gnc-gnome-utils.h" +#include "gnc-plugin-file-history.h" +#include "gnc-gconf-utils.h" +#include "dialog-new-user.h" -static int gnucash_show_version; /* GNUCASH_SVN is defined whenever we're building from an SVN tree */ #ifdef GNUCASH_SVN static int is_development_version = TRUE; #else static int is_development_version = FALSE; #endif -static char *add_quotes_file; + +/* Command-line option variables */ +static int gnucash_show_version; +static const char *add_quotes_file; +static int nofile; +static const char *file_to_load; static void gnc_print_unstable_message(void) @@ -209,7 +216,7 @@ gnucash_command_line(int argc, char **argv) {"loglevel", '\0', POPT_ARG_INT, NULL, 0, _("Set the logging level from 0 (least) to 6 (most)"), _("LOGLEVEL")}, - {"nofile", '\0', POPT_ARG_NONE, NULL, 0, + {"nofile", '\0', POPT_ARG_NONE, &nofile, 0, _("Do not load the last file opened"), NULL}, {"config-path", '\0', POPT_ARG_STRING, &config_path, 0, _("Set configuration path"), _("CONFIGPATH")}, @@ -232,6 +239,7 @@ gnucash_command_line(int argc, char **argv) poptSetOtherOptionHelp(pc, "[OPTIONS...] [datafile]"); while ((rc = poptGetNextOpt(pc)) > 0); + file_to_load = poptGetArg(pc); poptFreeContext(pc); if (gnucash_show_version) { @@ -330,22 +338,56 @@ inner_main_add_price_quotes(void *closure, int argc, char **argv) return; } +static char * +get_file_to_load() +{ + if (file_to_load) + return g_strdup(file_to_load); + else + return gnc_history_get_last(); +} + static void inner_main (void *closure, int argc, char **argv) { SCM main_mod; + char* fn; + GError *error = NULL; main_mod = scm_c_resolve_module("gnucash main"); scm_set_current_module(main_mod); - /* Can't show splash screen here unless we init gnome first */ - //gnc_show_splash_screen(); + /* TODO: After some more guile-extraction, this should happen + even before booting guile. */ + gnc_gui_init(); load_gnucash_modules(); load_system_config(); load_user_config(); + gnc_hook_add_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit, NULL); scm_c_eval_string("(gnc:main)"); + + + if (!nofile && (fn = get_file_to_load())) { + gnc_update_splash_screen(_("Loading data...")); + gnc_destroy_splash_screen(); + if (gnc_file_open_file(fn)) + gnc_hook_run(HOOK_BOOK_OPENED, NULL); + g_free(fn); + } + else if (gnc_gconf_get_bool("dialogs/new_user", "first_startup", &error) && + !error) { + gnc_destroy_splash_screen(); + gnc_ui_new_user_dialog(); + } + + gnc_destroy_splash_screen(); + + gnc_hook_run(HOOK_UI_POST_STARTUP, NULL); + gnc_ui_start_event_loop(); + gnc_hook_remove_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit); + shutdown(0); return; } diff --git a/src/gnome/Makefile.am b/src/gnome/Makefile.am index 6a8c3ed0fe..23d4f86206 100644 --- a/src/gnome/Makefile.am +++ b/src/gnome/Makefile.am @@ -12,6 +12,7 @@ libgncgnome_la_LIBADD = \ ${top_builddir}/src/report/report-gnome/libgncmod-report-gnome.la \ ${top_builddir}/src/register/ledger-core/libgncmod-ledger-core.la \ ${top_builddir}/src/gnome-search/libgncmod-gnome-search.la \ + ${top_builddir}/src/gnome-utils/libgncmod-gnome-utils.la \ ${top_builddir}/lib/glib26/libgncglib.la \ ${GUILE_LIBS} ${GNOME_LIBS} ${GLIB_LIBS} ${QOF_LIBS} diff --git a/src/gnome/gw-gnc-spec.scm b/src/gnome/gw-gnc-spec.scm index c1323cb2c5..25745da4aa 100644 --- a/src/gnome/gw-gnc-spec.scm +++ b/src/gnome/gw-gnc-spec.scm @@ -72,30 +72,6 @@ '() "Show the new user dialog.") - (gw:wrap-function - ws - 'gnc:start-ui-event-loop - ' - "gnc_ui_start_event_loop" - '() - "Start the UI event loop.") - - (gw:wrap-function - ws - 'gnc:gui-init - ' - "gnc_gui_init" - '(( command-line)) - "Initialize the remaining parts of the lower level ui. Returns main-window and remaining command line.") - - (gw:wrap-function - ws - 'gnc:gui-init-splash - ' - "gnc_gui_init_splash" - '(( command-line)) - "Initialize the lower level ui parts and put up the splash screen. Returns remaining command line.") - (gw:wrap-function ws 'gnc:update-splash-screen diff --git a/src/gnome/top-level.c b/src/gnome/top-level.c index 6f582a5b07..e6c3e305ca 100644 --- a/src/gnome/top-level.c +++ b/src/gnome/top-level.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -72,6 +71,7 @@ #include "guile-util.h" #include "top-level.h" #include "window-report.h" +#include "gnc-window.h" #define ACCEL_MAP_NAME "accelerator-map" @@ -238,11 +238,9 @@ gnc_html_price_url_cb (const char *location, const char *label, /* ============================================================== */ -SCM -gnc_gui_init_splash (SCM command_line) +void +gnc_gui_init_splash (void) { - SCM ret = command_line; - ENTER (" "); if (!splash_is_initialized) @@ -254,32 +252,33 @@ gnc_gui_init_splash (SCM command_line) } LEAVE (" "); - - return ret; } -SCM -gnc_gui_init (SCM command_line) +void +gnc_gui_init (void) { - SCM ret = command_line; - GncMainWindow *main_window; - gchar *map; - - ENTER (" "); - - if (!gnome_is_initialized) - { + GncMainWindow *main_window; + gchar *map; + + ENTER (" "); + + if (gnome_is_initialized) { + LEAVE("already initialized"); + return; + } + /* Make sure the splash (and hense gnome) was initialized */ if (!splash_is_initialized) - ret = gnc_gui_init_splash (ret); + gnc_gui_init_splash(); gnome_is_initialized = TRUE; gnc_ui_util_init(); gnc_configure_date_format(); - gnc_gconf_general_register_cb(KEY_DATE_FORMAT, - (GncGconfGeneralCb)gnc_configure_date_format, NULL); - gnc_gconf_general_register_any_cb((GncGconfGeneralAnyCb)gnc_gui_refresh_all, NULL); + gnc_gconf_general_register_cb( + KEY_DATE_FORMAT, (GncGconfGeneralCb)gnc_configure_date_format, NULL); + gnc_gconf_general_register_any_cb( + (GncGconfGeneralAnyCb)gnc_gui_refresh_all, NULL); if (!gnucash_style_init()) gnc_shutdown(1); @@ -309,11 +308,16 @@ gnc_gui_init (SCM command_line) g_free(map); /* FIXME Remove this test code */ - gnc_plugin_manager_add_plugin (gnc_plugin_manager_get (), gnc_plugin_account_tree_new ()); - gnc_plugin_manager_add_plugin (gnc_plugin_manager_get (), gnc_plugin_basic_commands_new ()); - gnc_plugin_manager_add_plugin (gnc_plugin_manager_get (), gnc_plugin_file_history_new ()); - gnc_plugin_manager_add_plugin (gnc_plugin_manager_get (), gnc_plugin_menu_additions_new ()); - gnc_plugin_manager_add_plugin (gnc_plugin_manager_get (), gnc_plugin_register_new ()); + gnc_plugin_manager_add_plugin ( + gnc_plugin_manager_get (), gnc_plugin_account_tree_new ()); + gnc_plugin_manager_add_plugin ( + gnc_plugin_manager_get (), gnc_plugin_basic_commands_new ()); + gnc_plugin_manager_add_plugin ( + gnc_plugin_manager_get (), gnc_plugin_file_history_new ()); + gnc_plugin_manager_add_plugin ( + gnc_plugin_manager_get (), gnc_plugin_menu_additions_new ()); + gnc_plugin_manager_add_plugin ( + gnc_plugin_manager_get (), gnc_plugin_register_new ()); /* I'm not sure why the FIXME note says to remove this. Maybe each module should be adding its own plugin to the manager? Anyway... Oh, maybe... nah */ @@ -325,17 +329,11 @@ gnc_gui_init (SCM command_line) /* Run the ui startup hooks. */ gnc_hook_run(HOOK_UI_STARTUP, NULL); - // return ( main_window . command_line ) - { - SCM gncMainWindowType; - gncMainWindowType = scm_c_eval_string(""); - ret = scm_cons( gw_wcp_assimilate_ptr(main_window, gncMainWindowType), ret ); - } - } + gnc_window_set_progressbar_window (GNC_WINDOW(main_window)); - LEAVE (" "); + LEAVE (" "); - return ret; + return; } /* ============================================================== */ diff --git a/src/gnome/top-level.h b/src/gnome/top-level.h index 3a666963ca..e2c33547cf 100644 --- a/src/gnome/top-level.h +++ b/src/gnome/top-level.h @@ -24,14 +24,13 @@ #define TOP_LEVEL_H #include -#include -gboolean gnucash_ui_is_running (void); -gboolean gnucash_ui_is_terminating (void); -SCM gnc_gui_init_splash (SCM command_line); -SCM gnc_gui_init (SCM command_line); -void gnc_gui_shutdown (void); -void gnc_gui_destroy (void); -int gnc_ui_start_event_loop (void); +gboolean gnucash_ui_is_running (void); +gboolean gnucash_ui_is_terminating (void); +void gnc_gui_init_splash (void); +void gnc_gui_init (void); +void gnc_gui_shutdown (void); +void gnc_gui_destroy (void); +int gnc_ui_start_event_loop (void); #endif diff --git a/src/scm/Makefile.am b/src/scm/Makefile.am index 54c8d77911..861caffc87 100644 --- a/src/scm/Makefile.am +++ b/src/scm/Makefile.am @@ -44,8 +44,6 @@ build-config.scm: ${srcdir}/build-config.scm.in Makefile rm -f $@.tmp sed < $< > $@.tmp \ -e 's:@-VERSION-@:${VERSION}:' \ - -e 's:@-GNC_CONFIGDIR-@:${GNC_CONFIGDIR}:' \ - -e 's:@-GNC_SHAREDIR-@:${GNC_SHAREDIR}:' \ -e 's:@-GNC_HELPDIR-@:${GNC_HELPDIR}:' mv $@.tmp $@ diff --git a/src/scm/build-config.scm.in b/src/scm/build-config.scm.in index 79ad324426..13687edcd3 100644 --- a/src/scm/build-config.scm.in +++ b/src/scm/build-config.scm.in @@ -3,6 +3,4 @@ ;; Automatically generated defaults (don't use these directly -- ;; they're used during actual initialization elsewhere) -(define gnc:_install-config-path_ '("@-GNC_CONFIGDIR-@")) -(define gnc:_install-share-path_ '("@-GNC_SHAREDIR-@")) (define gnc:_install-doc-path_ '("@-GNC_HELPDIR-@")) diff --git a/src/scm/main-window.scm b/src/scm/main-window.scm index 2b9850e5f9..d3e14c1494 100644 --- a/src/scm/main-window.scm +++ b/src/scm/main-window.scm @@ -50,7 +50,8 @@ ;; get a list of the reports we'll be needing to nuke (hash-fold (lambda (k v p) - (set! dead-reports (cons k dead-reports)) #t) #t *gnc:_reports_*) + (set! dead-reports (cons k dead-reports)) #t) + #t *gnc:_reports_*) ;; actually remove them (if they're being displayed, the ;; window's reference will keep the report alive until the @@ -95,7 +96,3 @@ slots (_ "Book Options") changed_cb))) -(gnc:hook-remove-dangler gnc:*book-closed-hook* - gnc:main-window-book-close-handler) -(gnc:hook-add-dangler gnc:*book-closed-hook* - gnc:main-window-book-close-handler) diff --git a/src/scm/main.scm b/src/scm/main.scm index 96ea048898..db5e208262 100644 --- a/src/scm/main.scm +++ b/src/scm/main.scm @@ -37,6 +37,8 @@ ;; files we can load from the top-level because they're "well behaved" ;; (these should probably be in modules eventually) (load-from-path "doc.scm") +(load-from-path "main-window.scm") ;; depends on app-utils (N_, etc.)... +(load-from-path "fin.scm") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Exports @@ -318,56 +320,6 @@ string and 'directories' must be a list of strings." (gnc:find-file file (list (car dirs))) (loop prefixes (cdr dirs)))))) -(define (gnc:startup-pass-2) - (gnc:debug "starting up (2).") - - ;; SUPER UGLY HACK -- this should go away when I come back for the - ;; second cleanup pass... - (let ((original-module (current-module)) - (bootstrap (resolve-module '(gnucash main)))) - - (define (load-module name vers optional?) - (let ((str (string-append (_ "Loading modules... ") name))) - (gnc:update-splash-screen str) - (if optional? - (gnc:module-load-optional name vers) - (gnc:module-load name vers)))) - - (set-current-module bootstrap) - - ;; files we should be able to load from the top-level because - ;; they're "well behaved" (these should probably be in modules - ;; eventually) - (load-from-path "main-window.scm") ;; depends on app-utils (N_, etc.)... - (load-from-path "printing/print-check.scm") ;; depends on simple-obj... - ;; +jsled - 2002.07.08 - (load-from-path "fin.scm") - - (gnc:update-splash-screen (_ "Checking Finance::Quote...")) - (gnc:price-quotes-install-sources) - - (set-current-module original-module)) - - ;; Load the system configs - (gnc:update-splash-screen (_ "Loading configs...")) - - (gnc:report-menu-setup) - - ;; the Welcome to GnuCash "extravaganza" report - (gnc:add-extension - (gnc:make-menu-item - (N_ "Welcome Sample Report") - (N_ "Welcome-to-GnuCash report screen") - (list gnc:menuname-reports gnc:menuname-utility "") - (lambda (window) - (gnc:main-window-open-report (gnc:make-welcome-report) window)))) - - (gnc:hook-run-danglers gnc:*startup-hook*) - - (if (gnc:config-var-value-get gnc:*loglevel*) - (gnc:set-log-level-global (gnc:config-var-value-get gnc:*loglevel*)))) - - (define (gnc:shutdown exit-status) (gnc:debug "Shutdown -- exit-status: " exit-status) @@ -458,37 +410,31 @@ string and 'directories' must be a list of strings." (if (not (gnc:handle-command-line-args)) (gnc:shutdown 1)) - (gnc:hook-add-dangler gnc:*ui-shutdown-hook* gnc:gui-finish) - ;; We init splash before gui-init, but gui-init will do the - ;; splash itself. - (set! gnc:*command-line-remaining* - (gnc:gui-init-splash gnc:*command-line-remaining*)) + (gnc:hook-remove-dangler gnc:*book-closed-hook* + gnc:main-window-book-close-handler) + (gnc:hook-add-dangler gnc:*book-closed-hook* + gnc:main-window-book-close-handler) + + (load-from-path "printing/print-check.scm") ;; depends on simple-obj... + + (gnc:update-splash-screen (_ "Checking Finance::Quote...")) + (gnc:price-quotes-install-sources) + + (gnc:report-menu-setup) + + ;; the Welcome to GnuCash "extravaganza" report + (gnc:add-extension + (gnc:make-menu-item + (N_ "Welcome Sample Report") + (N_ "Welcome-to-GnuCash report screen") + (list gnc:menuname-reports gnc:menuname-utility "") + (lambda (window) + (gnc:main-window-open-report (gnc:make-welcome-report) window)))) - (gnc:startup-pass-2) - - ;; Why are we doing this again? - (gnc:hook-add-dangler gnc:*ui-shutdown-hook* gnc:gui-finish) - (let* ((init-window-cons-rest - (gnc:gui-init gnc:*command-line-remaining*)) - (main-window (car init-window-cons-rest))) - (set! gnc:*command-line-remaining* (cdr init-window-cons-rest)) - (if (and - (not (gnc:account-file-to-load)) - (not (string? (gnc:history-get-last))) - (gnc:gconf-get-bool "dialogs/new_user" "first_startup")) - (begin - (gnc:destroy-splash-screen) - (gnc:new-user-dialog)) - (begin - (gnc:destroy-splash-screen) - (gnc:main-window-set-progressbar-window main-window) - (gnc:load-account-file) - )) - ;; no matter how or what we loaded, ensure the main-window - ;; title is valid... - (gnc:hook-run-danglers gnc:*ui-post-startup-hook*) - (gnc:start-ui-event-loop) ;; this won't return until we're exiting - (gnc:hook-remove-dangler gnc:*ui-shutdown-hook* gnc:gui-finish)) + (gnc:hook-run-danglers gnc:*startup-hook*) + (if (gnc:config-var-value-get gnc:*loglevel*) + (gnc:set-log-level-global (gnc:config-var-value-get gnc:*loglevel*))) + ;;return to C )