GnuCash  4.11-11-ge9df8d41d2+
gnc-gnome-utils.c
1 /********************************************************************\
2  * gnc-gnome-utils.c -- utility functions for gnome for GnuCash *
3  * Copyright (C) 2001 Linux Developers Group *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact: *
17  * *
18  * Free Software Foundation Voice: +1-617-542-5942 *
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20  * Boston, MA 02110-1301, USA gnu@gnu.org *
21  * *
22 \********************************************************************/
23 
24 #include <config.h>
25 
26 #include <glib/gi18n.h>
27 #include <libxml/xmlIO.h>
28 
29 #include "gnc-prefs-utils.h"
30 #include "gnc-prefs.h"
31 #include "gnc-gnome-utils.h"
32 #include "gnc-engine.h"
33 #include "gnc-path.h"
34 #include "gnc-ui.h"
35 #include "gnc-file.h"
36 #include "gnc-hooks.h"
37 #include "gnc-filepath-utils.h"
38 #include "gnc-menu-extensions.h"
39 #include "gnc-component-manager.h"
40 #include "gnc-splash.h"
41 #include "gnc-window.h"
42 #include "gnc-icons.h"
43 #include "dialog-doclink-utils.h"
44 #include "dialog-options.h"
45 #include "dialog-commodity.h"
46 #include "dialog-totd.h"
47 #include "gnc-ui-util.h"
48 #include "gnc-uri-utils.h"
49 #include "gnc-session.h"
50 #include "qofbookslots.h"
51 #ifdef G_OS_WIN32
52 #include <windows.h>
53 #include "gnc-help-utils.h"
54 #endif
55 #ifdef MAC_INTEGRATION
56 #import <Cocoa/Cocoa.h>
57 #endif
58 
59 extern SCM scm_init_sw_gnome_utils_module(void);
60 
61 static QofLogModule log_module = GNC_MOD_GUI;
62 static int gnome_is_running = FALSE;
63 static int gnome_is_terminating = FALSE;
64 static int gnome_is_initialized = FALSE;
65 
66 
67 #define ACCEL_MAP_NAME "accelerator-map"
68 
69 const gchar *msg_no_help_found =
70  N_("GnuCash could not find the files of the help documentation.");
71 const gchar *msg_no_help_reason =
72  N_("This is likely because the \"gnucash-docs\" package is not properly installed.");
73  /* Translators: URI of missing help files */
74 const gchar *msg_no_help_location = N_("Expected location");
75 
76 static void gnc_book_options_help_cb (GNCOptionWin *win, gpointer dat);
77 
78 void
80 {
81  gnc_component_manager_init ();
82  gnc_options_ui_initialize ();
83 
84  scm_init_sw_gnome_utils_module();
85  scm_c_use_module ("sw_gnome_utils");
86  scm_c_use_module("gnucash gnome-utils");
87 }
88 
89 
90 static void
91 gnc_global_options_help_cb (GNCOptionWin *win, gpointer dat)
92 {
93  gnc_gnome_help (GTK_WINDOW(gnc_options_dialog_widget (win)), HF_HELP, HL_GLOBPREFS);
94 }
95 
96 static void
97 gnc_book_options_help_cb (GNCOptionWin *win, gpointer dat)
98 {
99  gnc_gnome_help (GTK_WINDOW(gnc_options_dialog_widget (win)), HF_HELP, HL_BOOK_OPTIONS);
100 }
101 
102 void
104 {
105  gnc_options_dialog_set_help_cb(win,
106  (GNCOptionWinCallback)gnc_book_options_help_cb,
107  NULL);
108 }
109 
110 void
112 {
113  GNCOption *num_source_option;
114  GtkWidget *num_source_is_split_action_button;
115  gboolean num_source_is_split_action;
116 
117  if (!odb) return;
118  num_source_is_split_action = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL,
119  GNC_PREF_NUM_SOURCE);
120  if (num_source_is_split_action)
121  {
122  num_source_option = gnc_option_db_get_option_by_name(odb,
123  OPTION_SECTION_ACCOUNTS,
124  OPTION_NAME_NUM_FIELD_SOURCE);
125  num_source_is_split_action_button =
126  gnc_option_get_gtk_widget (num_source_option);
127  gtk_toggle_button_set_active
128  (GTK_TOGGLE_BUTTON (num_source_is_split_action_button),
129  num_source_is_split_action);
130  }
131 }
132 
133 static void
134 gnc_style_sheet_options_help_cb (GNCOptionWin *win, gpointer dat)
135 {
136  gnc_gnome_help (GTK_WINDOW(gnc_options_dialog_widget (win)), HF_HELP, HL_STYLE_SHEET);
137 }
138 
139 void
141 {
142  gnc_options_dialog_set_help_cb (win,
143  (GNCOptionWinCallback)gnc_style_sheet_options_help_cb,
144  NULL);
145 }
146 
147 /* gnc_configure_date_format
148  * sets dateFormat to the current value on the scheme side
149  *
150  * Args: Nothing
151  * Returns: Nothing
152  */
153 static void
154 gnc_configure_date_format (void)
155 {
156  QofDateFormat df = gnc_prefs_get_int(GNC_PREFS_GROUP_GENERAL,
157  GNC_PREF_DATE_FORMAT);
158 
159  /* Only a subset of the qof date formats is currently
160  * supported for date entry.
161  */
162  if (df > QOF_DATE_FORMAT_LOCALE)
163  {
164  PERR("Incorrect date format");
165  return;
166  }
167 
169 }
170 
171 /* gnc_configure_date_completion
172  * sets dateCompletion to the current value on the scheme side.
173  * QOF_DATE_COMPLETION_THISYEAR: use current year
174  * QOF_DATE_COMPLETION_SLIDING: use a sliding 12-month window
175  * backmonths 0-11: windows starts this many months before current month
176  *
177  * Args: Nothing
178  * Returns: Nothing
179  */
180 static void
181 gnc_configure_date_completion (void)
182 {
184  int backmonths = gnc_prefs_get_float(GNC_PREFS_GROUP_GENERAL,
185  GNC_PREF_DATE_BACKMONTHS);
186 
187  if (backmonths < 0)
188  backmonths = 0;
189  else if (backmonths > 11)
190  backmonths = 11;
191 
192  if (gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_DATE_COMPL_SLIDING))
194 
195  qof_date_completion_set(dc, backmonths);
196 }
197 
198 void
200 {
201  GtkCssProvider *provider_user, *provider_app, *provider_fallback;
202  GdkDisplay *display;
203  GdkScreen *screen;
204  const gchar *var;
205  GError *error = 0;
206 
207  provider_user = gtk_css_provider_new ();
208  provider_app = gtk_css_provider_new ();
209  provider_fallback = gtk_css_provider_new ();
210  display = gdk_display_get_default ();
211  screen = gdk_display_get_default_screen (display);
212 
213  gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider_fallback), GTK_STYLE_PROVIDER_PRIORITY_FALLBACK);
214  gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider_app), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
215  gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider_user), GTK_STYLE_PROVIDER_PRIORITY_USER);
216 
217  gtk_css_provider_load_from_resource (provider_app, "/org/gnucash/gnucash.css");
218  gtk_css_provider_load_from_resource (provider_fallback, "/org/gnucash/gnucash-fallback.css");
219 
220  var = gnc_userconfig_dir ();
221  if (var)
222  {
223  gchar *str;
224  str = g_build_filename (var, "gtk-3.0.css", (char *)NULL);
225  gtk_css_provider_load_from_path (provider_user, str, &error);
226  g_free (str);
227  }
228  g_object_unref (provider_user);
229  g_object_unref (provider_app);
230  g_object_unref (provider_fallback);
231 }
232 
233 /* This function fixes an issue with yelp that it does not work with the
234  * ?anchor variant, see https://gitlab.gnome.org/GNOME/yelp/issues/116
235  */
236 static gchar *
237 gnc_gnome_help_yelp_anchor_fix (GtkWindow *parent, const char *file_name, const char *anchor)
238 {
239  const gchar * const *sdatadirs = g_get_system_data_dirs ();
240  const gchar * const *langs = g_get_language_names ();
241  gchar *lookfor = g_strconcat ("gnome/help/", file_name, NULL);
242  gchar *help_path = NULL;
243  gchar *help_file = NULL;
244  gchar *full_path = NULL;
245  gchar *uri = NULL;
246 
247  for (; *sdatadirs; sdatadirs++)
248  {
249  gchar *filepath = g_build_filename (*sdatadirs, lookfor, NULL);
250  if (g_file_test (filepath, G_FILE_TEST_EXISTS))
251  help_path = g_strdup (filepath);
252  g_free (filepath);
253  }
254  g_free (lookfor);
255 
256  if (!help_path)
257  {
258  gnc_error_dialog (parent, "%s\n%s", _(msg_no_help_found), _(msg_no_help_reason));
259  PERR("Unable to find 'gnome/help' directory");
260  return NULL;
261  }
262 
263  // add the file extension, currently .xml
264  help_file = g_strconcat (file_name, ".xml", NULL);
265 
266  for (; *langs; langs++)
267  {
268  gchar *filename = g_build_filename (help_path, *langs, help_file, NULL);
269  if (g_file_test (filename, G_FILE_TEST_EXISTS))
270  {
271  full_path = filename;
272  break;
273  }
274  g_free (filename);
275  }
276  g_free (help_path);
277  g_free (help_file);
278 
279  if (full_path)
280  uri = g_strconcat ("ghelp:", full_path, "?", anchor, NULL);
281  else
282  {
283  gnc_error_dialog (parent, "%s\n%s", _(msg_no_help_found), _(msg_no_help_reason));
284  PERR("Unable to find valid help language directory");
285  return NULL;
286  }
287  g_free (full_path);
288  return uri;
289 }
290 
291 #ifdef MAC_INTEGRATION
292 
293 /* Don't be alarmed if this function looks strange to you: It's
294  * written in Objective-C, the native language of the OSX Cocoa
295  * toolkit.
296  */
297 void
298 gnc_gnome_help (GtkWindow *parent, const char *dir, const char *detail)
299 {
300  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
301  NSString *subdir = [NSString stringWithUTF8String: dir];
302  NSString *tag, *subdirectory;
303  NSURL *url = NULL;
304 
305  if (detail)
306  tag = [NSString stringWithUTF8String: detail];
307  else if ([subdir compare: @HF_HELP] == NSOrderedSame)
308  tag = @"help";
309  else if ([subdir compare: @HF_GUIDE] == NSOrderedSame)
310  tag = @"index";
311  else
312  {
313  PWARN("gnc_gnome_help called with unknown subdirectory %s", dir);
314  return;
315  }
316 
317  if (![[NSBundle mainBundle] bundleIdentifier])
318  {
319  /* If bundleIdentifier is NULL, then we're running from the
320  * commandline and must construct a file path to the resource. We can
321  * still get the resource path, but it will point to the "bin"
322  * directory so we chop that off, break up what's left into pieces,
323  * add some more pieces, and put it all back together again. Then,
324  * because the gettext way of handling localizations is different from
325  * OSX's, we have to figure out which translation to use. */
326  NSArray *components = [NSArray arrayWithObjects: @"share", @"doc", @"gnucash-docs", nil ];
327  NSString *prefix = [[[NSBundle mainBundle] resourcePath]
328  stringByDeletingLastPathComponent];
329  NSArray *prefix_comps = [[prefix pathComponents]
330  arrayByAddingObjectsFromArray: components];
331  NSString *docs_dir = [NSString pathWithComponents: prefix_comps];
332  NSArray *languages = [[NSUserDefaults standardUserDefaults]
333  objectForKey: @"AppleLanguages"];
334  BOOL dir;
335  subdir = [[[subdir lowercaseString] componentsSeparatedByString: @" "]
336  componentsJoinedByString: @"-"];
337  if (![[NSFileManager defaultManager] fileExistsAtPath: docs_dir])
338  {
339  gnc_error_dialog (parent, "%s\n%s\n%s: %s", _(msg_no_help_found),
340  _(msg_no_help_reason),
341  _(msg_no_help_location), [docs_dir UTF8String]);
342  [pool release];
343  return;
344  }
345  if ([languages count] > 0)
346  {
347  NSEnumerator *lang_iter = [languages objectEnumerator];
348  NSString *path;
349  NSString *this_lang;
350  while ((this_lang = [lang_iter nextObject]))
351  {
352  NSArray *elements;
353  unsigned int paths;
354  NSString *completed_path = [NSString alloc];
355  this_lang = [this_lang stringByTrimmingCharactersInSet:
356  [NSCharacterSet characterSetWithCharactersInString:
357  @"\""]];
358  elements = [this_lang componentsSeparatedByString: @"-"];
359  this_lang = [elements objectAtIndex: 0];
360  path = [docs_dir stringByAppendingPathComponent: this_lang];
361  paths = [path completePathIntoString: &completed_path
362  caseSensitive: FALSE
363  matchesIntoArray: NULL filterTypes: NULL];
364  if (paths > 1 &&
365  [[NSFileManager defaultManager]
366  fileExistsAtPath: completed_path
367  isDirectory: &dir])
368  if (dir)
369  {
370  @try
371  {
372  url = [NSURL fileURLWithPath:
373  [[[completed_path
374  stringByAppendingPathComponent: subdir]
375  stringByAppendingPathComponent: tag]
376  stringByAppendingPathExtension: @"html"]];
377  }
378  @catch (NSException *e)
379  {
380  PWARN("fileURLWithPath threw %s: %s",
381  [[e name] UTF8String], [[e reason] UTF8String]);
382  return;
383  }
384  break;
385  }
386  if ([this_lang compare: @"en"] == NSOrderedSame)
387  break; /* Special case, forces use of "C" locale */
388  }
389  }
390  if (!url)
391  {
392  @try
393  {
394  url = [NSURL
395  fileURLWithPath: [[[[docs_dir
396  stringByAppendingPathComponent: @"C"]
397  stringByAppendingPathComponent: subdir]
398  stringByAppendingPathComponent: tag]
399  stringByAppendingPathExtension: @"html"]];
400  }
401  @catch (NSException *e)
402  {
403  PWARN("fileURLWithPath threw %s: %s",
404  [[e name] UTF8String], [[e reason] UTF8String]);
405  return;
406  }
407  }
408  }
409  /* It's a lot easier in a bundle! OSX finds the best translation for us. */
410  else
411  {
412  @try
413  {
414  url = [NSURL fileURLWithPath: [[NSBundle mainBundle]
415  pathForResource: tag
416  ofType: @"html"
417  inDirectory: subdir ]];
418  }
419  @catch (NSException *e)
420  {
421  PWARN("fileURLWithPath threw %s: %s",
422  [[e name] UTF8String], [[e reason] UTF8String]);
423  return;
424  }
425  }
426  /* Now just open the URL in the default app for opening URLs */
427  if (url)
428  [[NSWorkspace sharedWorkspace] openURL: url];
429  else
430  {
431  gnc_error_dialog (parent, "%s\n%s", _(msg_no_help_found), _(msg_no_help_reason));
432  }
433  [pool release];
434 }
435 #elif defined G_OS_WIN32 /* G_OS_WIN32 */
436 void
437 gnc_gnome_help (GtkWindow *parent, const char *file_name, const char *anchor)
438 {
439  const gchar * const *lang;
440  gchar *pkgdatadir, *fullpath, *found = NULL;
441 
442  pkgdatadir = gnc_path_get_pkgdatadir ();
443  for (lang = g_get_language_names (); *lang; lang++)
444  {
445  fullpath = g_build_filename (pkgdatadir, "help", *lang, file_name,
446  (gchar*) NULL);
447  if (g_file_test (fullpath, G_FILE_TEST_IS_REGULAR))
448  {
449  found = g_strdup (fullpath);
450  g_free (fullpath);
451  break;
452  }
453  g_free (fullpath);
454  }
455  g_free (pkgdatadir);
456 
457  if (!found)
458  {
459  gnc_error_dialog (parent, "%s\n%s", _(msg_no_help_found), _(msg_no_help_reason));
460  }
461  else
462  {
463  gnc_show_htmlhelp (found, anchor);
464  }
465  g_free (found);
466 }
467 #else
468 void
469 gnc_gnome_help (GtkWindow *parent, const char *file_name, const char *anchor)
470 {
471  GError *error = NULL;
472  gchar *uri = NULL;
473  gboolean success = TRUE;
474 
475  if (anchor)
476  uri = gnc_gnome_help_yelp_anchor_fix (parent, file_name, anchor);
477  else
478  uri = g_strconcat ("ghelp:", file_name, NULL);
479 
480  DEBUG ("Attempting to opening help uri %s", uri);
481 
482  if (uri)
483  success = gtk_show_uri_on_window (NULL, uri, gtk_get_current_event_time (), &error);
484 
485  g_free (uri);
486  if (success)
487  return;
488 
489  g_assert(error != NULL);
490  {
491  gnc_error_dialog (parent, "%s\n%s", _(msg_no_help_found), _(msg_no_help_reason));
492  }
493  PERR ("%s", error->message);
494  g_error_free(error);
495 }
496 
497 
498 #endif
499 
500 #ifdef MAC_INTEGRATION
501 
502 /* Don't be alarmed if this function looks strange to you: It's
503  * written in Objective-C, the native language of the OSX Cocoa
504  * toolkit.
505  */
506 void
507 gnc_launch_doclink (GtkWindow *parent, const char *uri)
508 {
509  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
510  NSString *uri_str = [NSString stringWithUTF8String: uri];
511  NSURL *url = [[[NSURL alloc] initWithString: uri_str] autorelease];
512  const gchar *message =
513  _("GnuCash could not find the linked document.");
514 
515  if (url)
516  {
517  [[NSWorkspace sharedWorkspace] openURL: url];
518  [pool release];
519  return;
520  }
521 
522  gnc_error_dialog (parent, "%s", message);
523 
524  [pool release];
525  return;
526 }
527 #elif defined G_OS_WIN32 /* G_OS_WIN32 */
528 void
529 gnc_launch_doclink (GtkWindow *parent, const char *uri)
530 {
531  wchar_t *winuri = NULL;
532  gchar *filename = NULL;
533  /* ShellExecuteW open doesn't decode http escapes if it's passed a
534  * file URI so we have to do it. */
535  if (gnc_uri_is_file_uri (uri))
536  {
537  gchar *uri_scheme = gnc_uri_get_scheme (uri);
538  filename = gnc_doclink_get_unescape_uri (NULL, uri, uri_scheme);
539  winuri = (wchar_t *)g_utf8_to_utf16(filename, -1, NULL, NULL, NULL);
540  g_free (uri_scheme);
541  }
542  else
543  winuri = (wchar_t *)g_utf8_to_utf16(uri, -1, NULL, NULL, NULL);
544 
545  if (winuri)
546  {
547  wchar_t *wincmd = (wchar_t *)g_utf8_to_utf16("open", -1,
548  NULL, NULL, NULL);
549  if ((INT_PTR)ShellExecuteW(NULL, wincmd, winuri,
550  NULL, NULL, SW_SHOWNORMAL) <= 32)
551  {
552  const gchar *message =
553  _("GnuCash could not find the linked document.");
554  gnc_error_dialog (parent, "%s:\n%s", message, filename);
555  }
556  g_free (wincmd);
557  g_free (winuri);
558  g_free (filename);
559  }
560 }
561 
562 #else
563 void
564 gnc_launch_doclink (GtkWindow *parent, const char *uri)
565 {
566  GError *error = NULL;
567  gboolean success;
568 
569  if (!uri)
570  return;
571 
572  DEBUG ("Attempting to open uri %s", uri);
573 
574  success = gtk_show_uri_on_window (NULL, uri, gtk_get_current_event_time (), &error);
575 
576  if (success)
577  return;
578 
579  g_assert (error != NULL);
580  {
581  gchar *error_uri = NULL;
582  const gchar *message =
583  _("GnuCash could not open the linked document:");
584 
585  if (gnc_uri_is_file_uri (uri))
586  {
587  gchar *uri_scheme = gnc_uri_get_scheme (uri);
588  error_uri = gnc_doclink_get_unescape_uri (NULL, uri, uri_scheme);
589  g_free (uri_scheme);
590  }
591  else
592  error_uri = g_strdup (uri);
593 
594  gnc_error_dialog (parent, "%s\n%s", message, error_uri);
595  g_free (error_uri);
596  }
597  PERR ("%s", error->message);
598  g_error_free (error);
599 }
600 
601 #endif
602 
603 /********************************************************************\
604  * gnc_gnome_get_pixmap *
605  * returns a GtkWidget given a pixmap filename *
606  * *
607  * Args: none *
608  * Returns: GtkWidget or NULL if there was a problem *
609  \*******************************************************************/
610 GtkWidget *
611 gnc_gnome_get_pixmap (const char *name)
612 {
613  GtkWidget *pixmap;
614  char *fullname;
615 
616  g_return_val_if_fail (name != NULL, NULL);
617 
618  fullname = gnc_filepath_locate_pixmap (name);
619  if (fullname == NULL)
620  return NULL;
621 
622  DEBUG ("Loading pixmap file %s", fullname);
623 
624  pixmap = gtk_image_new_from_file (fullname);
625  if (pixmap == NULL)
626  {
627  PERR ("Could not load pixmap");
628  }
629  g_free (fullname);
630 
631  return pixmap;
632 }
633 
634 /********************************************************************\
635  * gnc_gnome_get_gdkpixbuf *
636  * returns a GdkImlibImage object given a pixmap filename *
637  * *
638  * Args: none *
639  * Returns: GdkPixbuf or NULL if there was a problem *
640  \*******************************************************************/
641 GdkPixbuf *
642 gnc_gnome_get_gdkpixbuf (const char *name)
643 {
644  GdkPixbuf *pixbuf;
645  GError *error = NULL;
646  char *fullname;
647 
648  g_return_val_if_fail (name != NULL, NULL);
649 
650  fullname = gnc_filepath_locate_pixmap (name);
651  if (fullname == NULL)
652  return NULL;
653 
654  DEBUG ("Loading pixbuf file %s", fullname);
655  pixbuf = gdk_pixbuf_new_from_file (fullname, &error);
656  if (error != NULL)
657  {
658  g_assert (pixbuf == NULL);
659  PERR ("Could not load pixbuf: %s", error->message);
660  g_error_free (error);
661  }
662  g_free (fullname);
663 
664  return pixbuf;
665 }
666 
667 static gboolean
668 gnc_ui_check_events (gpointer not_used)
669 {
670  QofSession *session;
671  gboolean force;
672 
673  if (gtk_main_level() != 1)
674  return TRUE;
675 
676  if (!gnc_current_session_exist())
677  return TRUE;
678  session = gnc_get_current_session ();
679 
680  if (gnc_gui_refresh_suspended ())
681  return TRUE;
682 
683  if (!qof_session_events_pending (session))
684  return TRUE;
685 
686  gnc_suspend_gui_refresh ();
687 
688  force = qof_session_process_events (session);
689 
690  gnc_resume_gui_refresh ();
691 
692  if (force)
693  gnc_gui_refresh_all ();
694 
695  return TRUE;
696 }
697 
698 
699 int
700 gnc_ui_start_event_loop (void)
701 {
702  guint id;
703 
704  gnome_is_running = TRUE;
705 
706  id = g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, 10000, /* 10 secs */
707  gnc_ui_check_events, NULL, NULL);
708 
709  scm_call_1(scm_c_eval_string("gnc:set-ui-status"), SCM_BOOL_T);
710 
711  /* Enter gnome event loop */
712  gtk_main ();
713 
714  g_source_remove (id);
715 
716  scm_call_1(scm_c_eval_string("gnc:set-ui-status"), SCM_BOOL_F);
717 
718  gnome_is_running = FALSE;
719  gnome_is_terminating = FALSE;
720 
721  return 0;
722 }
723 
724 GncMainWindow *
725 gnc_gui_init(void)
726 {
727  static GncMainWindow *main_window;
728  gchar *map;
729 #ifdef MAC_INTEGRATION
730  gchar *data_dir;
731 #endif
732 
733  ENTER ("");
734 
735  if (gnome_is_initialized)
736  return main_window;
737 
738  /* use custom icon */
739  gnc_load_app_icons();
740  gtk_window_set_default_icon_name(GNC_ICON_APP);
741 
742  g_set_application_name(PACKAGE_NAME);
743 
744  gnc_prefs_init();
745  gnc_show_splash_screen();
746 
747  gnome_is_initialized = TRUE;
748 
749  gnc_ui_util_init();
750  gnc_configure_date_format();
751  gnc_configure_date_completion();
752 
753  gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
754  GNC_PREF_DATE_FORMAT,
755  gnc_configure_date_format,
756  NULL);
757  gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
758  GNC_PREF_DATE_COMPL_THISYEAR,
759  gnc_configure_date_completion,
760  NULL);
761  gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
762  GNC_PREF_DATE_COMPL_SLIDING,
763  gnc_configure_date_completion,
764  NULL);
765  gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
766  GNC_PREF_DATE_BACKMONTHS,
767  gnc_configure_date_completion,
768  NULL);
769  gnc_prefs_register_group_cb (GNC_PREFS_GROUP_GENERAL,
770  gnc_gui_refresh_all,
771  NULL);
772 
773  gnc_file_set_shutdown_callback (gnc_shutdown);
774 
775  gnc_options_dialog_set_global_help_cb (gnc_global_options_help_cb, NULL);
776 
777  main_window = gnc_main_window_new ();
778  // Bug#350993:
779  // gtk_widget_show (GTK_WIDGET (main_window));
780  gnc_window_set_progressbar_window (GNC_WINDOW(main_window));
781 
782 #ifdef MAC_INTEGRATION
783  map = gnc_build_userdata_path(ACCEL_MAP_NAME);
784  if (!g_file_test (map, G_FILE_TEST_EXISTS))
785  {
786  g_free (map);
787  data_dir = gnc_path_get_pkgdatadir();
788  map = g_build_filename(data_dir, "ui", "osx_accel_map", NULL);
789  g_free(data_dir);
790  }
791 #else
792  map = gnc_build_userdata_path(ACCEL_MAP_NAME);
793 #endif /* MAC_INTEGRATION */
794  gtk_accel_map_load(map);
795  g_free(map);
796 
797  /* Load css configuration file */
798  gnc_add_css_file ();
799 
800  gnc_totd_dialog (gnc_get_splash_screen (), TRUE);
801 
802  LEAVE ("");
803  return main_window;
804 }
805 
806 gboolean
807 gnucash_ui_is_running(void)
808 {
809  return gnome_is_running;
810 }
811 
812 static void
813 gnc_gui_destroy (void)
814 {
815  if (!gnome_is_initialized)
816  return;
817 
818  if (gnc_prefs_is_set_up())
819  {
820  gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
821  GNC_PREF_DATE_FORMAT,
822  gnc_configure_date_format,
823  NULL);
824  gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
825  GNC_PREF_DATE_COMPL_THISYEAR,
826  gnc_configure_date_completion,
827  NULL);
828  gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
829  GNC_PREF_DATE_COMPL_SLIDING,
830  gnc_configure_date_completion,
831  NULL);
832  gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
833  GNC_PREF_DATE_BACKMONTHS,
834  gnc_configure_date_completion,
835  NULL);
836  gnc_prefs_remove_group_cb_by_func (GNC_PREFS_GROUP_GENERAL,
837  gnc_gui_refresh_all,
838  NULL);
839 
840  gnc_ui_util_remove_registered_prefs ();
841  gnc_prefs_remove_registered ();
842  }
843  gnc_extensions_shutdown ();
844 }
845 
846 static void
847 gnc_gui_shutdown (void)
848 {
849  gchar *map;
850 
851  if (gnome_is_running && !gnome_is_terminating)
852  {
853  gnome_is_terminating = TRUE;
854  map = gnc_build_userdata_path(ACCEL_MAP_NAME);
855  gtk_accel_map_save(map);
856  g_free(map);
857  gnc_component_manager_shutdown ();
858  gtk_main_quit();
859  }
860 }
861 
862 /* shutdown gnucash. This function will initiate an orderly
863  * shutdown, and when that has finished it will exit the program.
864  */
865 void
866 gnc_shutdown (int exit_status)
867 {
868  if (gnucash_ui_is_running())
869  {
870  if (!gnome_is_terminating)
871  {
872  if (gnc_file_query_save (gnc_ui_get_main_window (NULL), FALSE))
873  {
874  gnc_hook_run(HOOK_UI_SHUTDOWN, NULL);
875  gnc_gui_shutdown();
876  }
877  }
878  }
879  else
880  {
881  gnc_gui_destroy();
882  gnc_hook_run(HOOK_SHUTDOWN, NULL);
883  gnc_engine_shutdown();
884  exit(exit_status);
885  }
886 }
887 
QofDateCompletion
Enum for date completion modes (for dates entered without year)
Definition: gnc-date.h:144
utility functions for the GnuCash UI
Functions that are supported by all types of windows.
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244
void qof_date_completion_set(QofDateCompletion dc, int backmonths)
The qof_date_completion_set() routing sets the date completion method to one of QOF_DATE_COMPLETION_T...
Definition: gnc-date.cpp:475
gint gnc_prefs_get_int(const gchar *group, const gchar *pref_name)
Get an integer value from the preferences backend.
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
use sliding 12-month window
Definition: gnc-date.h:147
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome&#39;s yelp for linux, and open to a given link within a gi...
Preferences initialization function.
void gnc_options_dialog_set_book_options_help_cb(GNCOptionWin *win)
Set the help callback to &#39;gnc_book_options_help_cb&#39; to open a help browser and point it to the Book O...
Gnome specific utility functions.
Definition: init.py:1
void gnc_add_css_file(void)
Load a gtk resource configuration file to customize gtk appearance and behaviour. ...
All type declarations for the whole Gnucash engine.
void gnc_gnome_utils_init(void)
Initialize the gnome-utils library Should be run once before using any gnome-utils features...
Generic api to store and retrieve preferences.
void gnc_options_dialog_set_style_sheet_options_help_cb(GNCOptionWin *win)
Set the help callback to &#39;gnc_style_sheet_options_help_cb&#39; to open a help browser and point it to the...
void gnc_options_dialog_set_new_book_option_values(GNCOptionDB *odb)
Set the initial values of new book options to values specified in user preferences.
const gchar * gnc_userconfig_dir(void)
Return the user&#39;s config directory for gnucash.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
Utility functions for convert uri in separate components and back.
use current year
Definition: gnc-date.h:146
File path resolution utility functions.
Take from locale information.
Definition: gnc-date.h:134
void qof_date_format_set(QofDateFormat df)
The qof_date_format_set() routine sets date format to one of US, UK, CE, OR ISO.
Definition: gnc-date.cpp:442
QofDateFormat
Enum for determining a date format.
Definition: gnc-date.h:128
"select" and "new" commodity windows
gdouble gnc_prefs_get_float(const gchar *group, const gchar *pref_name)
Get an float value from the preferences backend.