gnc-gnome-utils.c

00001 /********************************************************************\
00002  * gnc-gnome-utils.c -- utility functions for gnome for GnuCash     *
00003  * Copyright (C) 2001 Linux Developers Group                        *
00004  *                                                                  *
00005  * This program is free software; you can redistribute it and/or    *
00006  * modify it under the terms of the GNU General Public License as   *
00007  * published by the Free Software Foundation; either version 2 of   *
00008  * the License, or (at your option) any later version.              *
00009  *                                                                  *
00010  * This program is distributed in the hope that it will be useful,  *
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00013  * GNU General Public License for more details.                     *
00014  *                                                                  *
00015  * You should have received a copy of the GNU General Public License*
00016  * along with this program; if not, contact:                        *
00017  *                                                                  *
00018  * Free Software Foundation           Voice:  +1-617-542-5942       *
00019  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00020  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00021  *                                                                  *
00022 \********************************************************************/
00023 
00024 #include "config.h"
00025 
00026 #include <gnome.h>
00027 #include <glib/gi18n.h>
00028 #include <libguile.h>
00029 #include <gconf/gconf.h>
00030 #ifdef HAVE_X11_XLIB_H
00031 # include <X11/Xlib.h>
00032 #endif
00033 #include <libxml/xmlIO.h>
00034 
00035 #include "gnc-html-graph-gog.h"
00036 
00037 #include "druid-gconf-setup.h"
00038 #include "gnc-gconf-utils.h"
00039 #include "gnc-gnome-utils.h"
00040 #include "gnc-html.h"
00041 #include "gnc-engine.h"
00042 #include "gnc-path.h"
00043 #include "gnc-ui.h"
00044 #include "gnc-file.h"
00045 #include "gnc-hooks.h"
00046 #include "gnc-filepath-utils.h"
00047 #include "gnc-menu-extensions.h"
00048 #include "gnc-component-manager.h"
00049 #include "gnc-splash.h"
00050 #include "gnc-window.h"
00051 #include "gnc-icons.h"
00052 #include "dialog-options.h"
00053 #include "dialog-commodity.h"
00054 #include "dialog-totd.h"
00055 #include "gnc-ui-util.h"
00056 #include "gnc-session.h"
00057 #ifdef G_OS_WIN32
00058 #    include "gnc-help-utils.h"
00059 #endif
00060 
00061 static QofLogModule log_module = GNC_MOD_GUI;
00062 static GnomeProgram *gnucash_program = NULL;
00063 static int gnome_is_running = FALSE;
00064 static int gnome_is_terminating = FALSE;
00065 static int gnome_is_initialized = FALSE;
00066 
00067 
00068 #define ACCEL_MAP_NAME "accelerator-map"
00069 
00070 static void
00071 gnc_global_options_help_cb (GNCOptionWin *win, gpointer dat)
00072 {
00073   gnc_gnome_help (HF_HELP, HL_GLOBPREFS);
00074 }
00075 
00076 static void
00077 gnc_commodity_help_cb (void)
00078 {
00079   gnc_gnome_help (HF_HELP, HL_COMMODITY);
00080 }
00081 
00082 /* gnc_configure_date_format
00083  *    sets dateFormat to the current value on the scheme side
00084  *
00085  * Args: Nothing
00086  * Returns: Nothing
00087  */
00088 static void 
00089 gnc_configure_date_format (void)
00090 {
00091   char *format_code = gnc_gconf_get_string(GCONF_GENERAL, 
00092                                            KEY_DATE_FORMAT, NULL);
00093 
00094   QofDateFormat df;
00095 
00096   if (format_code == NULL)
00097     format_code = g_strdup("locale");
00098   if (*format_code == '\0') {
00099     g_free(format_code);
00100     format_code = g_strdup("locale");
00101   }
00102 
00103   if (gnc_date_string_to_dateformat(format_code, &df))
00104   {
00105     PERR("Incorrect date format code");
00106     if (format_code != NULL)
00107       free(format_code);
00108     return;
00109   }
00110 
00111   qof_date_format_set(df);
00112 
00113   if (format_code != NULL)
00114     free(format_code);
00115 }
00116 
00117 char *
00118 gnc_gnome_locate_pixmap (const char *name)
00119 {
00120   char *fullname;
00121 
00122   g_return_val_if_fail (name != NULL, NULL);
00123 
00124   fullname = gnome_program_locate_file (gnucash_program,
00125                                         GNOME_FILE_DOMAIN_APP_PIXMAP,
00126                                         name, TRUE, NULL);
00127   if (fullname == NULL) {
00128     PERR ("Could not locate pixmap/pixbuf file %s", name);
00129     return NULL;
00130   }
00131 
00132   return fullname;
00133 }
00134 
00135 char *
00136 gnc_gnome_locate_file (GnomeFileDomain domain, const char *name)
00137 {
00138   char *fullname;
00139 
00140   g_return_val_if_fail(name, NULL);
00141   fullname = gnome_program_locate_file(gnucash_program,
00142                                        domain, name, TRUE, NULL);
00143   if (!fullname)
00144       PERR ("Could not locate file %s", name);
00145   return fullname;
00146 }
00147 
00148 char *
00149 gnc_gnome_locate_data_file (const char *name)
00150 {
00151   char *fullname;
00152 
00153   g_return_val_if_fail (name != NULL, NULL);
00154 
00155   fullname = gnome_program_locate_file (gnucash_program,
00156                                         GNOME_FILE_DOMAIN_APP_DATADIR,
00157                                         name, TRUE, NULL);
00158 
00159   if (fullname == NULL) {
00160     PERR ("Could not locate file %s", name);
00161     return NULL;
00162   }
00163 
00164   return fullname;
00165 }
00166 
00167 char *
00168 gnc_gnome_locate_ui_file (const char *name)
00169 {
00170   char *partial;
00171   char *fullname;
00172 
00173   g_return_val_if_fail (name != NULL, NULL);
00174 
00175   partial = g_strdup_printf("ui/%s", name);
00176   fullname = gnc_gnome_locate_data_file(partial);
00177   g_free(partial);
00178 
00179   return fullname;
00180 }
00181 
00182 static void
00183 gnc_gtk_add_rc_file (void)
00184 {
00185   const gchar *var;
00186   gchar *str;
00187 
00188   var = g_get_home_dir ();
00189   if (var) {
00190     str = g_build_filename (var, ".gtkrc-2.0.gnucash", (char *)NULL);
00191     gtk_rc_add_default_file (str);
00192     g_free (str);
00193   }
00194 }
00195 
00196 void
00197 gnc_gnome_init (int argc, char **argv, const char * version)
00198 {
00199   GError *error = NULL;
00200   gchar *prefix = gnc_path_get_prefix ();
00201   gchar *pkgsysconfdir = gnc_path_get_pkgsysconfdir ();
00202   gchar *pkgdatadir = gnc_path_get_pkgdatadir ();
00203   gchar *pkglibdir = gnc_path_get_pkglibdir ();
00204 
00205   gnc_gtk_add_rc_file();
00206   gnucash_program = gnome_program_init(
00207       "gnucash", version, LIBGNOMEUI_MODULE,
00208       argc, argv,
00209       GNOME_PARAM_APP_PREFIX, prefix,
00210       GNOME_PARAM_APP_SYSCONFDIR, pkgsysconfdir,
00211       GNOME_PARAM_APP_DATADIR, pkgdatadir,
00212       GNOME_PARAM_APP_LIBDIR, pkglibdir,
00213       GNOME_PARAM_NONE);
00214   g_free (prefix);
00215   g_free (pkgsysconfdir);
00216   g_free (pkgdatadir);
00217   g_free (pkglibdir);
00218 
00219 #ifdef G_OS_WIN32
00220   /* workaround for bug #421792 */
00221   xmlCleanupInputCallbacks();
00222 #endif
00223 
00224   /* initialization required for gtkhtml */
00225   gtk_widget_set_default_colormap (gdk_rgb_get_colormap ());
00226 
00227   /* use custom icon */
00228   {
00229     int idx;
00230     char *icon_filenames[] = {"gnucash-icon-16x16.png",
00231                               "gnucash-icon-32x32.png",
00232                               "gnucash-icon-48x48.png",
00233                               NULL};
00234     GList *icons = NULL;
00235     char *fullname, *name_iter;
00236 
00237     for (idx = 0; icon_filenames[idx] != NULL; idx++) {
00238       GdkPixbuf *buf = NULL;
00239 
00240       fullname = gnc_gnome_locate_pixmap(icon_filenames[idx]);
00241       if (fullname == NULL) {
00242         g_warning("couldn't find icon file [%s]", icon_filenames[idx]);
00243         continue;
00244       }
00245         
00246       buf = gnc_gnome_get_gdkpixbuf(fullname);
00247       if (buf == NULL)
00248       {
00249         g_warning("error loading image from [%s]", fullname);
00250         g_free(fullname);
00251         continue;
00252       }
00253       g_free(fullname);
00254       icons = g_list_append(icons, buf);
00255     }
00256 
00257     gtk_window_set_default_icon_list(icons);
00258     g_list_foreach(icons, (GFunc)g_object_unref, NULL);
00259     g_list_free(icons);
00260   }
00261 
00262   druid_gconf_install_check_schemas();
00263 
00264   return;
00265 }
00266 
00267 #ifndef G_OS_WIN32
00268 void
00269 gnc_gnome_help (const char *file_name, const char *anchor)
00270 {
00271   GError *error = NULL;
00272 
00273   DEBUG ("Attempting to opening help file %s", file_name);
00274   if (gnome_help_display (file_name, anchor, &error))
00275     return;
00276 
00277   g_assert(error != NULL);
00278   {
00279     const gchar *message =
00280       _("GnuCash could not find the files for the help documentation.  "
00281         "This is likely because the 'gnucash-docs' package is not installed.");
00282     gnc_error_dialog(NULL, "%s", message);
00283   }
00284   PERR ("%s", error->message);
00285   g_error_free(error);
00286 }
00287 
00288 #else /* G_OS_WIN32 */
00289 void
00290 gnc_gnome_help (const char *file_name, const char *anchor)
00291 {
00292   const gchar * const *lang;
00293   gchar *pkgdatadir, *fullpath, *found = NULL;
00294   
00295   pkgdatadir = gnc_path_get_pkgdatadir ();
00296   for (lang=g_get_language_names (); *lang; lang++) {
00297     fullpath = g_build_filename (pkgdatadir, "help", *lang, file_name,
00298                                  (gchar*) NULL);
00299     if (g_file_test (fullpath, G_FILE_TEST_IS_REGULAR)) {
00300       found = g_strdup (fullpath);
00301       g_free (fullpath);
00302       break;
00303     }
00304     g_free (fullpath);
00305   }
00306   g_free (pkgdatadir);
00307 
00308   if (!found) {
00309     const gchar *message =
00310       _("GnuCash could not find the files for the help documentation.");
00311     gnc_error_dialog (NULL, message);
00312   } else {
00313     gnc_show_htmlhelp (found, anchor);
00314   }
00315   g_free (found);
00316 }
00317 #endif
00318 
00319 /********************************************************************\
00320  * gnc_gnome_get_pixmap                                             *
00321  *   returns a GtkWidget given a pixmap filename                    *
00322  *                                                                  *
00323  * Args: none                                                       *
00324  * Returns: GtkWidget or NULL if there was a problem                *
00325  \*******************************************************************/
00326 GtkWidget *
00327 gnc_gnome_get_pixmap (const char *name)
00328 {
00329   GtkWidget *pixmap;
00330   char *fullname;
00331 
00332   g_return_val_if_fail (name != NULL, NULL);
00333 
00334   fullname = gnc_gnome_locate_pixmap (name);
00335   if (fullname == NULL)
00336     return NULL;
00337 
00338   DEBUG ("Loading pixmap file %s", fullname);
00339 
00340   pixmap = gtk_image_new_from_file (fullname);
00341   if (pixmap == NULL) {
00342     PERR ("Could not load pixmap");
00343   }
00344   g_free (fullname);
00345 
00346   return pixmap;
00347 }
00348 
00349 /********************************************************************\
00350  * gnc_gnome_get_gdkpixbuf                                          *
00351  *   returns a GdkImlibImage object given a pixmap filename         *
00352  *                                                                  *
00353  * Args: none                                                       *
00354  * Returns: GdkPixbuf or NULL if there was a problem                *
00355  \*******************************************************************/
00356 GdkPixbuf *
00357 gnc_gnome_get_gdkpixbuf (const char *name)
00358 {
00359   GdkPixbuf *pixbuf;
00360   GError *error = NULL;
00361   char *fullname;
00362 
00363   g_return_val_if_fail (name != NULL, NULL);
00364 
00365   fullname = gnc_gnome_locate_pixmap (name);
00366   if (fullname == NULL)
00367     return NULL;
00368 
00369   DEBUG ("Loading pixbuf file %s", fullname);
00370   pixbuf = gdk_pixbuf_new_from_file (fullname, &error);
00371   if (error != NULL) {
00372     g_assert (pixbuf == NULL);
00373     PERR ("Could not load pixbuf: %s", error->message);
00374     g_error_free (error);
00375   }
00376   g_free (fullname);
00377 
00378   return pixbuf;
00379 }
00380 
00381 static gboolean
00382 gnc_ui_check_events (gpointer not_used)
00383 {
00384   QofSession *session;
00385   gboolean force;
00386 
00387   if (gtk_main_level() != 1)
00388     return TRUE;
00389 
00390   if (!gnc_current_session_exist())
00391     return TRUE;
00392   session = gnc_get_current_session ();
00393 
00394   if (gnc_gui_refresh_suspended ())
00395     return TRUE;
00396 
00397   if (!qof_session_events_pending (session))
00398     return TRUE;
00399 
00400   gnc_suspend_gui_refresh ();
00401 
00402   force = qof_session_process_events (session);
00403 
00404   gnc_resume_gui_refresh ();
00405 
00406   if (force)
00407     gnc_gui_refresh_all ();
00408 
00409   return TRUE;
00410 }
00411 
00412 #ifdef HAVE_X11_XLIB_H
00413 static int
00414 gnc_x_error (Display *display, XErrorEvent *error)
00415 {
00416   if (error->error_code)
00417   {
00418     char buf[64];
00419 
00420     XGetErrorText (display, error->error_code, buf, 63);
00421 
00422     g_warning ("X-ERROR **: %s\n  serial %ld error_code %d "
00423                "request_code %d minor_code %d\n", 
00424                buf, 
00425                error->serial, 
00426                error->error_code, 
00427                error->request_code,
00428                error->minor_code);
00429   }
00430 
00431   return 0;
00432 }
00433 #endif
00434 
00435 int
00436 gnc_ui_start_event_loop (void)
00437 {
00438   guint id;
00439 
00440   gnome_is_running = TRUE;
00441 
00442   id = g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, 10000, /* 10 secs */
00443                            gnc_ui_check_events, NULL, NULL);
00444 
00445 #ifdef HAVE_X11_XLIB_H
00446   XSetErrorHandler (gnc_x_error);
00447 #endif
00448 
00449   /* Enter gnome event loop */
00450   gtk_main ();
00451 
00452   g_source_remove (id);
00453 
00454   gnome_is_running = FALSE;
00455   gnome_is_terminating = FALSE;
00456 
00457   return 0;
00458 }
00459 
00460 GncMainWindow *
00461 gnc_gui_init(void)
00462 {
00463     static GncMainWindow *main_window;
00464     gchar *map;
00465 
00466     if (gnome_is_initialized) {
00467         return main_window;
00468     }
00469 
00470     if (gnc_gconf_get_bool(GCONF_GENERAL, "show_splash_screen", NULL))
00471         gnc_gui_init_splash();
00472 
00473     gnome_is_initialized = TRUE;
00474 
00475     gnc_ui_util_init();
00476     gnc_configure_date_format();
00477 
00478     gnc_gconf_general_register_cb(
00479         KEY_DATE_FORMAT, (GncGconfGeneralCb)gnc_configure_date_format, NULL);
00480     gnc_gconf_general_register_any_cb(
00481         (GncGconfGeneralAnyCb)gnc_gui_refresh_all, NULL);
00482 
00483     gnc_ui_commodity_set_help_callback (gnc_commodity_help_cb);
00484     gnc_file_set_shutdown_callback (gnc_shutdown);
00485 
00486     gnc_options_dialog_set_global_help_cb (gnc_global_options_help_cb, NULL);
00487 
00488     main_window = gnc_main_window_new ();
00489     // Bug#350993:
00490     // gtk_widget_show (GTK_WIDGET (main_window));
00491     gnc_window_set_progressbar_window (GNC_WINDOW(main_window));
00492 
00493     map = gnc_build_dotgnucash_path(ACCEL_MAP_NAME);
00494     gtk_accel_map_load(map);
00495     g_free(map);
00496 
00497     gnc_load_stock_icons();
00498     gnc_totd_dialog(GTK_WINDOW(main_window), TRUE);
00499 
00500     return main_window;
00501 }
00502 
00503 gboolean
00504 gnucash_ui_is_running(void)
00505 {
00506   return gnome_is_running;
00507 }
00508 
00509 static void
00510 gnc_gui_destroy (void)
00511 {
00512   if (!gnome_is_initialized)
00513     return;
00514 
00515   gnc_extensions_shutdown ();
00516 }
00517 
00518 static void
00519 gnc_gui_shutdown (void)
00520 {
00521   gchar *map;
00522 
00523   if (gnome_is_running && !gnome_is_terminating)
00524   {
00525     gnome_is_terminating = TRUE;
00526 
00527     map = gnc_build_dotgnucash_path(ACCEL_MAP_NAME);
00528     gtk_accel_map_save(map);
00529     g_free(map);
00530 
00531     gtk_main_quit();
00532   }
00533 }
00534 
00535 /*  shutdown gnucash.  This function will initiate an orderly
00536  *  shutdown, and when that has finished it will exit the program.
00537  */
00538 void
00539 gnc_shutdown (int exit_status)
00540 {
00541     if (gnucash_ui_is_running()) {
00542         if (!gnome_is_terminating) {
00543             if (gnc_file_query_save(FALSE)) {
00544                 gnc_hook_run(HOOK_UI_SHUTDOWN, NULL);
00545                 gnc_gui_shutdown();
00546             }
00547         }
00548     } else {
00549         gnc_gui_destroy();
00550         gnc_hook_run(HOOK_SHUTDOWN, NULL);
00551         gnc_engine_shutdown();
00552         exit(exit_status);
00553     }   
00554 }
00555 

Generated on Tue Oct 14 05:04:40 2008 for GnuCash by  doxygen 1.5.2