|
GnuCash 2.4.99
|
00001 /* 00002 * gnucash-bin.c -- The program entry point for GnuCash 00003 * 00004 * Copyright (C) 2006 Chris Shoemaker <c.shoemaker@cox.net> 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License as 00008 * published by the Free Software Foundation; either version 2 of 00009 * the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, contact: 00018 * 00019 * Free Software Foundation Voice: +1-617-542-5942 00020 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 00021 * Boston, MA 02110-1301, USA gnu@gnu.org 00022 */ 00023 #include "config.h" 00024 00025 #include <stdlib.h> 00026 #include <stdio.h> 00027 #include <string.h> 00028 #include <libguile.h> 00029 #include <gtk/gtk.h> 00030 #include <glib/gi18n.h> 00031 #include <libgnome/libgnome.h> 00032 #include "glib.h" 00033 #include "gnc-module.h" 00034 #include "gnc-path.h" 00035 #include "binreloc.h" 00036 #include "gnc-locale-utils.h" 00037 #include "core-utils/gnc-version.h" 00038 #include "gnc-engine.h" 00039 #include "gnc-filepath-utils.h" 00040 #include "gnc-ui-util.h" 00041 #include "gnc-file.h" 00042 #include "gnc-hooks.h" 00043 #include "top-level.h" 00044 #include "gfec.h" 00045 #include "gnc-commodity.h" 00046 #include "gnc-main.h" 00047 #include "gnc-main-window.h" 00048 #include "gnc-splash.h" 00049 #include "gnc-gnome-utils.h" 00050 #include "gnc-plugin-file-history.h" 00051 #include "gnc-gconf-utils.h" 00052 #include "dialog-new-user.h" 00053 #include "gnc-session.h" 00054 #include "engine-helpers.h" 00055 #include "swig-runtime.h" 00056 00057 /* This static indicates the debugging module that this .o belongs to. */ 00058 static QofLogModule log_module = GNC_MOD_GUI; 00059 00060 #ifdef HAVE_GETTEXT 00061 # include <libintl.h> 00062 # include <locale.h> 00063 #endif 00064 00065 #ifdef MAC_INTEGRATION 00066 # include <Foundation/Foundation.h> 00067 #endif 00068 00069 /* GNUCASH_SVN is defined whenever we're building from an SVN tree */ 00070 #ifdef GNUCASH_SVN 00071 static int is_development_version = TRUE; 00072 #else 00073 static int is_development_version = FALSE; 00074 #endif 00075 00076 /* Command-line option variables */ 00077 static int gnucash_show_version = 0; 00078 static const char *add_quotes_file = NULL; 00079 static int nofile = 0; 00080 static const char *file_to_load = NULL; 00081 static gchar **log_flags = NULL; 00082 static gchar *log_to_filename = NULL; 00083 00084 static void 00085 gnc_print_unstable_message(void) 00086 { 00087 if (!is_development_version) return; 00088 00089 g_print("\n\n%s\n%s\n%s\n%s\n", 00090 _("This is a development version. It may or may not work."), 00091 _("Report bugs and other problems to gnucash-devel@gnucash.org"), 00092 _("You can also lookup and file bug reports at http://bugzilla.gnome.org"), 00093 _("To find the last stable version, please refer to http://www.gnucash.org")); 00094 } 00095 00096 static gchar *environment_expand(gchar *param) 00097 { 00098 gchar *search_start; 00099 gchar *opening_brace; 00100 gchar *closing_brace; 00101 gchar *result; 00102 gchar *tmp; 00103 gchar *expanded = NULL; 00104 00105 if (!param) 00106 return NULL; 00107 00108 /* Set an initial return value, so we can always use g_strconcat below) */ 00109 result = g_strdup ("x"); 00110 00111 /* Look for matching pairs of { and }. Anything in between should be expanded */ 00112 search_start = param; 00113 opening_brace = g_strstr_len (search_start, -1, "{"); 00114 closing_brace = g_strstr_len (search_start, -1, "}"); 00115 00116 /* Note: the test on valid braces is fairly simple: 00117 * * if no pair of opening/closing braces is found, no expansion occurs 00118 * * braces can't be nested, this will give unexpected results 00119 * * the string should contain no other braces than those used to mark 00120 * expandable variables, or unexpected results will be returned. 00121 */ 00122 while ( opening_brace && closing_brace && (closing_brace > opening_brace) ) 00123 { 00124 /* Found a first matching pair */ 00125 gchar *to_expand; 00126 const gchar *env_val; 00127 00128 /* If the string had characters before the opening {, copy them first */ 00129 if (opening_brace > search_start) 00130 { 00131 gchar *prefix = g_strndup (search_start, opening_brace - search_start); 00132 00133 tmp = g_strconcat (result, prefix, NULL); 00134 g_free (result); 00135 result = tmp; 00136 g_free (prefix); 00137 } 00138 00139 /* Expand the variable we found and append it to the result */ 00140 to_expand = g_strndup (opening_brace + 1, closing_brace - opening_brace - 1); 00141 env_val = g_getenv (to_expand); 00142 tmp = g_strconcat (result, env_val, NULL); 00143 g_free (result); 00144 result = tmp; 00145 g_free (to_expand); 00146 00147 /* Look for matching pairs of { and }. Anything in between should be expanded */ 00148 search_start = closing_brace + 1; 00149 opening_brace = g_strstr_len (search_start, -1, "{"); 00150 closing_brace = g_strstr_len (search_start, -1, "}"); 00151 } 00152 00153 /* No more braces found, append the remaining characters */ 00154 tmp = g_strconcat (result, search_start, NULL); 00155 g_free (result); 00156 result = tmp; 00157 00158 /* Remove the "x" from our result */ 00159 if (g_strcmp0 (result, "x")) 00160 expanded = g_strdup (result + 1); 00161 g_free (result); 00162 00163 return expanded; 00164 } 00165 00166 static void 00167 environment_override() 00168 { 00169 const gchar *path; 00170 gchar *config_path; 00171 gchar *env_file; 00172 GKeyFile *keyfile = g_key_file_new(); 00173 GError *error; 00174 gchar **env_vars; 00175 gsize param_count; 00176 gint i; 00177 gboolean got_keyfile; 00178 gchar *env_parm, *bin_parm; 00179 00180 /* Export default parameters to the environment */ 00181 env_parm = gnc_path_get_prefix(); 00182 if (!g_setenv("GNC_HOME", env_parm, FALSE)) 00183 g_warning ("Couldn't set/override environment variable GNC_HOME."); 00184 bin_parm = g_build_filename(env_parm, "bin", NULL); 00185 if (!g_setenv("GNC_BIN", bin_parm, FALSE)) 00186 g_warning ("Couldn't set/override environment variable GNC_BIN."); 00187 g_free (env_parm); 00188 g_free (bin_parm); 00189 env_parm = gnc_path_get_pkglibdir(); 00190 if (!g_setenv("GNC_LIB", env_parm, FALSE)) 00191 g_warning ("Couldn't set/override environment variable GNC_LIB."); 00192 g_free (env_parm); 00193 env_parm = gnc_path_get_pkgdatadir(); 00194 if (!g_setenv("GNC_DATA", env_parm, FALSE)) 00195 g_warning ("Couldn't set/override environment variable GNC_DATA."); 00196 g_free (env_parm); 00197 env_parm = gnc_path_get_pkgsysconfdir(); 00198 if (!g_setenv("GNC_CONF", env_parm, FALSE)) 00199 g_warning ("Couldn't set/override environment variable GNC_CONF."); 00200 g_free (env_parm); 00201 env_parm = gnc_path_get_libdir(); 00202 if (!g_setenv("SYS_LIB", env_parm, FALSE)) 00203 g_warning ("Couldn't set/override environment variable SYS_LIB."); 00204 g_free (env_parm); 00205 00206 config_path = gnc_path_get_pkgsysconfdir(); 00207 #ifdef G_OS_WIN32 00208 { 00209 /* unhide files without extension */ 00210 gchar *pathext = g_build_path(";", ".", g_getenv("PATHEXT"), 00211 (gchar*) NULL); 00212 g_setenv("PATHEXT", pathext, TRUE); 00213 g_free(pathext); 00214 } 00215 #endif 00216 00217 env_file = g_build_filename (config_path, "environment", NULL); 00218 got_keyfile = g_key_file_load_from_file (keyfile, env_file, G_KEY_FILE_NONE, &error); 00219 g_free (config_path); 00220 g_free (env_file); 00221 if ( !got_keyfile ) 00222 { 00223 g_key_file_free(keyfile); 00224 return; 00225 } 00226 00227 /* Read the environment overrides and apply them */ 00228 env_vars = g_key_file_get_keys(keyfile, "Variables", ¶m_count, &error); 00229 for ( i = 0; i < param_count; i++ ) 00230 { 00231 gchar **val_list; 00232 gsize val_count; 00233 gint j; 00234 gchar *new_val = NULL, *tmp_val; 00235 00236 /* For each variable, read its new value, optionally expand it and set/unset it */ 00237 val_list = g_key_file_get_string_list (keyfile, "Variables", 00238 env_vars[i], &val_count, 00239 &error ); 00240 if ( val_count == 0 ) 00241 g_unsetenv (env_vars[i]); 00242 else 00243 { 00244 /* Set an initial return value, so we can always use g_build_path below) */ 00245 tmp_val = g_strdup ("x"); 00246 for ( j = 0; j < val_count; j++ ) 00247 { 00248 gchar *expanded = environment_expand (val_list[j]); 00249 new_val = g_build_path (G_SEARCHPATH_SEPARATOR_S, tmp_val, expanded, NULL); 00250 g_free (tmp_val); 00251 g_free(expanded); 00252 tmp_val = new_val; 00253 } 00254 g_strfreev (val_list); 00255 00256 /* Remove the "x" from our result */ 00257 if (g_strcmp0 (tmp_val, "x")) 00258 new_val = g_strdup (tmp_val + sizeof (G_SEARCHPATH_SEPARATOR_S)); 00259 g_free (tmp_val); 00260 00261 if (!g_setenv (env_vars[i], new_val, TRUE)) 00262 g_warning ("Couldn't properly override environment variable \"%s\". " 00263 "This may lead to unexpected results", env_vars[i]); 00264 g_free(new_val); 00265 } 00266 } 00267 00268 g_strfreev(env_vars); 00269 g_key_file_free(keyfile); 00270 } 00271 00272 #ifdef MAC_INTEGRATION 00273 static void 00274 set_mac_locale() 00275 { 00276 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 00277 NSUserDefaults *defs = [NSUserDefaults standardUserDefaults]; 00278 NSArray *languages = [defs objectForKey: @"AppleLanguages"]; 00279 const gchar *langs = NULL; 00280 NSLocale *locale = [NSLocale currentLocale]; 00281 NSString *locale_str = [[[locale objectForKey: NSLocaleLanguageCode] 00282 stringByAppendingString: @"_"] 00283 stringByAppendingString: 00284 [locale objectForKey: NSLocaleCountryCode]]; 00285 /* If we didn't get a valid current locale, the string will be just "_" */ 00286 if ([locale_str isEqualToString: @"_"]) 00287 setlocale(LC_ALL, "en_US"); 00288 else 00289 setlocale(LC_ALL, [locale_str UTF8String]); 00290 /* If the currency doesn't match the base locale, we need to find a locale that does match, because setlocale won't know what to do with just a currency identifier. */ 00291 if (![[locale objectForKey: NSLocaleCurrencyCode] isEqualToString: 00292 [[[NSLocale alloc] initWithLocaleIdentifier: locale_str] objectForKey: NSLocaleCurrencyCode]]) { 00293 NSArray *all_locales = [NSLocale availableLocaleIdentifiers]; 00294 NSEnumerator *locale_iter = [all_locales objectEnumerator]; 00295 NSString *this_locale; 00296 NSString *currency = [locale objectForKey: NSLocaleCurrencyCode]; 00297 NSString *money_locale = nil; 00298 while ((this_locale = (NSString*)[locale_iter nextObject])) 00299 if ([[[[NSLocale alloc] initWithLocaleIdentifier: this_locale] 00300 objectForKey: NSLocaleCurrencyCode] 00301 isEqualToString: currency]) { 00302 money_locale = this_locale; 00303 break; 00304 } 00305 if (money_locale) 00306 setlocale(LC_MONETARY, [money_locale UTF8String]); 00307 } 00308 /* Now call gnc_localeconv() to force creation of the app locale 00309 * before another call to setlocale messes it up. */ 00310 gnc_localeconv (); 00311 /* Process the language list. 00312 * 00313 * Language subgroups (e.g., US English) are reported in the form 00314 * "ll-SS" (e.g. again, "en-US"), not what gettext wants. We convert 00315 * those to old-style locales, which is easy for most cases. There are 00316 * two where it isn't, though: Simplified Chinese (zh-Hans) and 00317 * traditional Chinese (zh-Hant), which are normally assigned the 00318 * locales zh_CN and zh_TW, respectively. Those are handled 00319 * specially.*/ 00320 if ([languages count] > 0) { 00321 NSEnumerator *lang_iter = [languages objectEnumerator]; 00322 NSString *this_lang; 00323 NSArray *elements; 00324 NSArray *new_languages = [NSArray array]; 00325 while ((this_lang = [lang_iter nextObject])) { 00326 this_lang = [this_lang stringByTrimmingCharactersInSet: 00327 [NSCharacterSet characterSetWithCharactersInString: 00328 @"\""]]; 00329 elements = [this_lang componentsSeparatedByString: @"-"]; 00330 if ([elements count] > 1) { 00331 if ([[elements objectAtIndex: 0] isEqualToString: @"zh"]) { 00332 if ([[elements objectAtIndex: 1] isEqualToString: @"Hans"]) 00333 this_lang = [NSString stringWithString: @"zh_CN"]; 00334 else 00335 this_lang = [NSString stringWithString: @"zh_TW"]; 00336 } 00337 else 00338 this_lang = [elements componentsJoinedByString: @"_"]; 00339 } 00340 new_languages = [new_languages arrayByAddingObject: this_lang]; 00341 /* If it's an english language, add the "C" locale after it so that 00342 * any messages can default to it */ 00343 if ( [[elements objectAtIndex: 0] isEqualToString: @"en"]) 00344 new_languages = [new_languages arrayByAddingObject: @"C"]; 00345 00346 } 00347 langs = [[new_languages componentsJoinedByString:@":"] UTF8String]; 00348 } 00349 if (langs && strlen(langs) > 0) 00350 g_setenv("LANGUAGE", langs, TRUE); 00351 [pool drain]; 00352 } 00353 #endif /* MAC_INTEGRATION */ 00354 00355 static gboolean 00356 try_load_config_array(const gchar *fns[]) 00357 { 00358 gchar *filename; 00359 int i; 00360 00361 for (i = 0; fns[i]; i++) 00362 { 00363 filename = gnc_build_dotgnucash_path(fns[i]); 00364 if (gfec_try_load(filename)) 00365 { 00366 g_free(filename); 00367 return TRUE; 00368 } 00369 g_free(filename); 00370 } 00371 return FALSE; 00372 } 00373 00374 static void 00375 update_message(const gchar *msg) 00376 { 00377 gnc_update_splash_screen(msg, GNC_SPLASH_PERCENTAGE_UNKNOWN); 00378 g_message("%s", msg); 00379 } 00380 00381 static void 00382 load_system_config(void) 00383 { 00384 static int is_system_config_loaded = FALSE; 00385 gchar *system_config_dir; 00386 gchar *system_config; 00387 00388 if (is_system_config_loaded) return; 00389 00390 update_message("loading system configuration"); 00391 system_config_dir = gnc_path_get_pkgsysconfdir(); 00392 system_config = g_build_filename(system_config_dir, "config", NULL); 00393 is_system_config_loaded = gfec_try_load(system_config); 00394 g_free(system_config_dir); 00395 g_free(system_config); 00396 } 00397 00398 static void 00399 load_user_config(void) 00400 { 00401 /* Don't continue adding to this list. When 2.0 rolls around bump 00402 the 1.4 (unnumbered) files off the list. */ 00403 static const gchar *user_config_files[] = 00404 { 00405 "config-2.0.user", "config-1.8.user", "config-1.6.user", 00406 "config.user", NULL 00407 }; 00408 static const gchar *auto_config_files[] = 00409 { 00410 "config-2.0.auto", "config-1.8.auto", "config-1.6.auto", 00411 "config.auto", NULL 00412 }; 00413 static const gchar *saved_report_files[] = 00414 { 00415 "saved-reports-2.4", "saved-reports-2.0", NULL 00416 }; 00417 static const gchar *stylesheet_files[] = { "stylesheets-2.0", NULL}; 00418 static int is_user_config_loaded = FALSE; 00419 00420 if (is_user_config_loaded) 00421 return; 00422 else is_user_config_loaded = TRUE; 00423 00424 update_message("loading user configuration"); 00425 try_load_config_array(user_config_files); 00426 update_message("loading auto configuration"); 00427 try_load_config_array(auto_config_files); 00428 update_message("loading saved reports"); 00429 try_load_config_array(saved_report_files); 00430 update_message("loading stylesheets"); 00431 try_load_config_array(stylesheet_files); 00432 } 00433 00434 /* Parse command line options, using GOption interface */ 00435 00436 static void 00437 gnucash_command_line(int *argc, char **argv) 00438 { 00439 int debugging = 0, extra = 0; 00440 char *namespace_regexp = NULL; 00441 const gchar *gconf_path = NULL; 00442 GError *error = NULL; 00443 GOptionContext *context; 00444 GOptionEntry options[] = 00445 { 00446 { 00447 "version", 'v', 0, G_OPTION_ARG_NONE, &gnucash_show_version, 00448 _("Show GnuCash version"), NULL 00449 }, 00450 00451 { 00452 "debug", '\0', 0, G_OPTION_ARG_NONE, &debugging, 00453 _("Enable debugging mode: increasing logging to provide deep detail."), NULL 00454 }, 00455 00456 { 00457 "extra", '\0', 0, G_OPTION_ARG_NONE, &extra, 00458 _("Enable extra/development/debugging features."), NULL 00459 }, 00460 00461 { 00462 "log", '\0', 0, G_OPTION_ARG_STRING_ARRAY, &log_flags, 00463 _("Log level overrides, of the form \"log.ger.path={debug,info,warn,crit,error}\""), 00464 NULL 00465 }, 00466 00467 { 00468 "logto", '\0', 0, G_OPTION_ARG_STRING, &log_to_filename, 00469 _("File to log into; defaults to \"/tmp/gnucash.trace\"; can be \"stderr\" or \"stdout\"."), 00470 NULL 00471 }, 00472 00473 { 00474 "nofile", '\0', 0, G_OPTION_ARG_NONE, &nofile, 00475 _("Do not load the last file opened"), NULL 00476 }, 00477 { 00478 "gconf-path", '\0', 0, G_OPTION_ARG_STRING, &gconf_path, 00479 _("Set the prefix path for gconf queries"), 00480 /* Translators: Argument description for autohelp; see 00481 http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */ 00482 _("GCONFPATH") 00483 }, 00484 { 00485 "add-price-quotes", '\0', 0, G_OPTION_ARG_STRING, &add_quotes_file, 00486 _("Add price quotes to given GnuCash datafile"), 00487 /* Translators: Argument description for autohelp; see 00488 http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */ 00489 _("FILE") 00490 }, 00491 { 00492 "namespace", '\0', 0, G_OPTION_ARG_STRING, &namespace_regexp, 00493 _("Regular expression determining which namespace commodities will be retrieved"), 00494 /* Translators: Argument description for autohelp; see 00495 http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */ 00496 _("REGEXP") 00497 }, 00498 { NULL } 00499 }; 00500 00501 context = g_option_context_new (" [datafile]"); 00502 g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE); 00503 g_option_context_add_group (context, gtk_get_option_group (FALSE)); 00504 if (!g_option_context_parse (context, argc, &argv, &error)) 00505 { 00506 g_warning("Error parsing command line arguments: [%s]; try `gnucash --help` for available options.", error->message); 00507 exit(1); 00508 } 00509 g_option_context_free (context); 00510 if (error) 00511 g_error_free(error); 00512 00513 if (*argc > 0) 00514 file_to_load = argv[1]; 00515 00516 if (gnucash_show_version) 00517 { 00518 if (is_development_version) 00519 { 00520 /* Translators: %s is the version number */ 00521 g_print(_("GnuCash %s development version"), VERSION); 00522 } 00523 else 00524 { 00525 /* Translators: %s is the version number */ 00526 g_print(_("GnuCash %s"), VERSION); 00527 } 00528 g_print("\n"); 00529 /* Translators: 1st %s is the build date; 2nd %s is the SVN 00530 revision number */ 00531 g_print(_("Built %s from r%s"), GNUCASH_BUILD_DATE, GNUCASH_SVN_REV); 00532 g_print("\n"); 00533 exit(0); 00534 } 00535 00536 gnc_set_extra(extra); 00537 00538 if (!gconf_path) 00539 { 00540 const char *path = g_getenv("GNC_GCONF_PATH"); 00541 if (path) 00542 gconf_path = path; 00543 else 00544 gconf_path = GCONF_PATH; 00545 } 00546 00547 gnc_set_gconf_path(g_strdup(gconf_path)); 00548 gnc_set_debugging(debugging); 00549 00550 if (namespace_regexp) 00551 gnc_main_set_namespace_regexp(namespace_regexp); 00552 } 00553 00554 static void 00555 load_gnucash_modules() 00556 { 00557 int i, len; 00558 struct 00559 { 00560 gchar * name; 00561 int version; 00562 gboolean optional; 00563 } modules[] = 00564 { 00565 { "gnucash/app-utils", 0, FALSE }, 00566 { "gnucash/engine", 0, FALSE }, 00567 { "gnucash/register/ledger-core", 0, FALSE }, 00568 { "gnucash/register/register-core", 0, FALSE }, 00569 { "gnucash/register/register-gnome", 0, FALSE }, 00570 { "gnucash/import-export/qif-import", 0, FALSE }, 00571 { "gnucash/import-export/ofx", 0, TRUE }, 00572 { "gnucash/import-export/csv-import", 0, TRUE }, 00573 { "gnucash/import-export/csv-export", 0, TRUE }, 00574 { "gnucash/import-export/log-replay", 0, TRUE }, 00575 { "gnucash/import-export/aqbanking", 0, TRUE }, 00576 { "gnucash/report/report-system", 0, FALSE }, 00577 { "gnucash/report/stylesheets", 0, FALSE }, 00578 { "gnucash/report/standard-reports", 0, FALSE }, 00579 { "gnucash/report/utility-reports", 0, FALSE }, 00580 { "gnucash/report/locale-specific/us", 0, FALSE }, 00581 { "gnucash/report/report-gnome", 0, FALSE }, 00582 { "gnucash/business-gnome", 0, TRUE }, 00583 { "gnucash/gtkmm", 0, TRUE }, 00584 { "gnucash/python", 0, TRUE }, 00585 }; 00586 00587 /* module initializations go here */ 00588 len = sizeof(modules) / sizeof(*modules); 00589 for (i = 0; i < len; i++) 00590 { 00591 DEBUG("Loading module %s started", modules[i].name); 00592 gnc_update_splash_screen(modules[i].name, GNC_SPLASH_PERCENTAGE_UNKNOWN); 00593 if (modules[i].optional) 00594 gnc_module_load_optional(modules[i].name, modules[i].version); 00595 else 00596 gnc_module_load(modules[i].name, modules[i].version); 00597 DEBUG("Loading module %s finished", modules[i].name); 00598 } 00599 if (!gnc_engine_is_initialized()) 00600 { 00601 /* On Windows this check used to fail anyway, see 00602 * https://lists.gnucash.org/pipermail/gnucash-devel/2006-September/018529.html 00603 * but more recently it seems to work as expected 00604 * again. 2006-12-20, cstim. */ 00605 g_warning("GnuCash engine failed to initialize. Exiting.\n"); 00606 exit(1); 00607 } 00608 } 00609 00610 static void 00611 inner_main_add_price_quotes(void *closure, int argc, char **argv) 00612 { 00613 SCM mod, add_quotes, scm_book, scm_result = SCM_BOOL_F; 00614 QofSession *session = NULL; 00615 00616 scm_c_eval_string("(debug-set! stack 200000)"); 00617 00618 mod = scm_c_resolve_module("gnucash price-quotes"); 00619 scm_set_current_module(mod); 00620 00621 /* Don't load the modules since the stylesheet module crashes if the 00622 GUI is not initialized */ 00623 #ifdef PRICE_QUOTES_NEED_MODULES 00624 load_gnucash_modules(); 00625 #endif 00626 00627 qof_event_suspend(); 00628 scm_c_eval_string("(gnc:price-quotes-install-sources)"); 00629 00630 if (!gnc_quote_source_fq_installed()) 00631 { 00632 g_print("%s", _("No quotes retrieved. Finance::Quote isn't " 00633 "installed properly.\n")); 00634 goto fail; 00635 } 00636 00637 add_quotes = scm_c_eval_string("gnc:book-add-quotes"); 00638 session = gnc_get_current_session(); 00639 if (!session) goto fail; 00640 00641 qof_session_begin(session, add_quotes_file, FALSE, FALSE, FALSE); 00642 if (qof_session_get_error(session) != ERR_BACKEND_NO_ERR) goto fail; 00643 00644 qof_session_load(session, NULL); 00645 if (qof_session_get_error(session) != ERR_BACKEND_NO_ERR) goto fail; 00646 00647 scm_book = gnc_book_to_scm(qof_session_get_book(session)); 00648 scm_result = scm_call_2(add_quotes, SCM_BOOL_F, scm_book); 00649 00650 qof_session_save(session, NULL); 00651 if (qof_session_get_error(session) != ERR_BACKEND_NO_ERR) goto fail; 00652 00653 qof_session_destroy(session); 00654 if (!scm_is_true(scm_result)) 00655 { 00656 g_warning("Failed to add quotes to %s.", add_quotes_file); 00657 goto fail; 00658 } 00659 00660 qof_event_resume(); 00661 gnc_shutdown(0); 00662 return; 00663 fail: 00664 if (session && qof_session_get_error(session) != ERR_BACKEND_NO_ERR) 00665 g_warning("Session Error: %s", qof_session_get_error_message(session)); 00666 qof_event_resume(); 00667 gnc_shutdown(1); 00668 } 00669 00670 static char * 00671 get_file_to_load() 00672 { 00673 if (file_to_load) 00674 return g_strdup(file_to_load); 00675 else 00676 return gnc_history_get_last(); 00677 } 00678 00679 static void 00680 inner_main (void *closure, int argc, char **argv) 00681 { 00682 SCM main_mod; 00683 char* fn; 00684 GError *error = NULL; 00685 00686 scm_c_eval_string("(debug-set! stack 200000)"); 00687 00688 main_mod = scm_c_resolve_module("gnucash main"); 00689 scm_set_current_module(main_mod); 00690 00691 load_gnucash_modules(); 00692 00693 /* Load the config before starting up the gui. This insures that 00694 * custom reports have been read into memory before the Reports 00695 * menu is created. */ 00696 load_system_config(); 00697 load_user_config(); 00698 00699 /* Setting-up the report menu must come after the module 00700 loading but before the gui initialization. */ 00701 scm_c_use_module("gnucash report report-gnome"); 00702 scm_c_eval_string("(gnc:report-menu-setup)"); 00703 00704 /* TODO: After some more guile-extraction, this should happen even 00705 before booting guile. */ 00706 gnc_main_gui_init(); 00707 00708 gnc_hook_add_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit, NULL); 00709 00710 scm_c_eval_string("(gnc:main)"); 00711 00712 /* Install Price Quote Sources */ 00713 gnc_update_splash_screen(_("Checking Finance::Quote..."), GNC_SPLASH_PERCENTAGE_UNKNOWN); 00714 scm_c_use_module("gnucash price-quotes"); 00715 scm_c_eval_string("(gnc:price-quotes-install-sources)"); 00716 00717 gnc_hook_run(HOOK_STARTUP, NULL); 00718 00719 if (!nofile && (fn = get_file_to_load())) 00720 { 00721 gnc_update_splash_screen(_("Loading data..."), GNC_SPLASH_PERCENTAGE_UNKNOWN); 00722 gnc_file_open_file(fn, /*open_readonly*/ FALSE); 00723 g_free(fn); 00724 } 00725 else if (gnc_gconf_get_bool("dialogs/new_user", "first_startup", &error) 00726 && !error) 00727 { 00728 gnc_destroy_splash_screen(); 00729 gnc_ui_new_user_dialog(); 00730 } 00731 00732 gnc_destroy_splash_screen(); 00733 gnc_main_window_show_all_windows(); 00734 00735 gnc_hook_run(HOOK_UI_POST_STARTUP, NULL); 00736 gnc_ui_start_event_loop(); 00737 gnc_hook_remove_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit); 00738 00739 gnc_shutdown(0); 00740 return; 00741 } 00742 00743 static void 00744 gnc_log_init() 00745 { 00746 if (log_to_filename != NULL) 00747 { 00748 qof_log_init_filename_special(log_to_filename); 00749 } 00750 else 00751 { 00752 /* initialize logging to our file. */ 00753 gchar *tracefilename; 00754 tracefilename = g_build_filename(g_get_tmp_dir(), "gnucash.trace", 00755 (gchar *)NULL); 00756 qof_log_init_filename(tracefilename); 00757 g_free(tracefilename); 00758 } 00759 00760 // set a reasonable default. 00761 qof_log_set_default(QOF_LOG_WARNING); 00762 00763 gnc_log_default(); 00764 00765 if (gnc_is_debugging()) 00766 { 00767 qof_log_set_level("", QOF_LOG_INFO); 00768 qof_log_set_level("qof", QOF_LOG_INFO); 00769 qof_log_set_level("gnc", QOF_LOG_INFO); 00770 } 00771 00772 { 00773 gchar *log_config_filename; 00774 log_config_filename = gnc_build_dotgnucash_path("log.conf"); 00775 if (g_file_test(log_config_filename, G_FILE_TEST_EXISTS)) 00776 qof_log_parse_log_config(log_config_filename); 00777 g_free(log_config_filename); 00778 } 00779 00780 if (log_flags != NULL) 00781 { 00782 int i = 0; 00783 for (; log_flags[i] != NULL; i++) 00784 { 00785 QofLogLevel level; 00786 gchar **parts = NULL; 00787 00788 gchar *log_opt = log_flags[i]; 00789 parts = g_strsplit(log_opt, "=", 2); 00790 if (parts == NULL || parts[0] == NULL || parts[1] == NULL) 00791 { 00792 g_warning("string [%s] not parseable", log_opt); 00793 continue; 00794 } 00795 00796 level = qof_log_level_from_string(parts[1]); 00797 qof_log_set_level(parts[0], level); 00798 g_strfreev(parts); 00799 } 00800 } 00801 } 00802 00803 int 00804 main(int argc, char ** argv) 00805 { 00806 #if !defined(G_THREADS_ENABLED) || defined(G_THREADS_IMPL_NONE) 00807 # error "No GLib thread implementation available!" 00808 #endif 00809 g_thread_init(NULL); 00810 00811 #ifdef ENABLE_BINRELOC 00812 { 00813 GError *binreloc_error = NULL; 00814 if (!gnc_gbr_init(&binreloc_error)) 00815 { 00816 g_print("main: Error on gnc_gbr_init: %s\n", binreloc_error->message); 00817 g_error_free(binreloc_error); 00818 } 00819 } 00820 #endif 00821 00822 /* This should be called before gettext is initialized 00823 * The user may have configured a different language via 00824 * the environment file. 00825 */ 00826 #ifdef MAC_INTEGRATION 00827 set_mac_locale(); 00828 #else 00829 environment_override(); 00830 #endif 00831 #ifdef HAVE_GETTEXT 00832 { 00833 gchar *localedir = gnc_path_get_localedir(); 00834 bindtextdomain(GETTEXT_PACKAGE, localedir); 00835 textdomain(GETTEXT_PACKAGE); 00836 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); 00837 g_free(localedir); 00838 } 00839 #endif 00840 00841 qof_log_init(); 00842 qof_log_set_default(QOF_LOG_INFO); 00843 00844 /* Note: setlocale will also be called later by gtk_init (which gets 00845 * invoked by gnome_program_init), but that's too late. The locale 00846 * must be properly set before parsing the command line arguments 00847 * or filenames may be returned in a charset other than UTF-8 and 00848 * not work with other glib calls. 00849 */ 00850 setlocale(LC_ALL, ""); 00851 gnucash_command_line(&argc, argv); 00852 gnc_print_unstable_message(); 00853 00854 gnc_module_system_init(); 00855 gnc_log_init(); 00856 00857 00858 if (add_quotes_file) 00859 { 00860 gchar *prefix = gnc_path_get_prefix (); 00861 gchar *pkgsysconfdir = gnc_path_get_pkgsysconfdir (); 00862 gchar *pkgdatadir = gnc_path_get_pkgdatadir (); 00863 gchar *pkglibdir = gnc_path_get_pkglibdir (); 00864 /* This option needs to run without a display, so we can't 00865 initialize any GUI libraries. */ 00866 gnome_program_init( 00867 PACKAGE, VERSION, LIBGNOME_MODULE, 00868 argc, argv, 00869 GNOME_PARAM_APP_PREFIX, prefix, 00870 GNOME_PARAM_APP_SYSCONFDIR, pkgsysconfdir, 00871 GNOME_PARAM_APP_DATADIR, pkgdatadir, 00872 GNOME_PARAM_APP_LIBDIR, pkglibdir, 00873 GNOME_PARAM_NONE); 00874 g_free (prefix); 00875 g_free (pkgsysconfdir); 00876 g_free (pkgdatadir); 00877 g_free (pkglibdir); 00878 scm_boot_guile(argc, argv, inner_main_add_price_quotes, 0); 00879 exit(0); /* never reached */ 00880 } 00881 00882 gnc_gnome_init (argc, argv, VERSION); 00883 gnc_gui_init(); 00884 scm_boot_guile(argc, argv, inner_main, 0); 00885 exit(0); /* never reached */ 00886 }
1.7.4