26#include <glib/gi18n.h>
27#include <libxml/xmlIO.h>
38#include "gnc-menu-extensions.h"
39#include "gnc-component-manager.h"
40#include "gnc-splash.h"
43#include "dialog-doclink-utils.h"
45#include "dialog-totd.h"
48#include "gnc-session.h"
49#include "qofbookslots.h"
52#include "gnc-help-utils.h"
55#import <Cocoa/Cocoa.h>
58extern SCM scm_init_sw_gnome_utils_module(
void);
60static QofLogModule log_module = GNC_MOD_GUI;
61static int gnome_is_running = FALSE;
62static int gnome_is_terminating = FALSE;
63static int gnome_is_initialized = FALSE;
66#define ACCEL_MAP_NAME "accelerator-map"
68const gchar *msg_no_help_found =
69 N_(
"GnuCash could not find the files of the help documentation.");
70const gchar *msg_no_help_reason =
71 N_(
"This is likely because the \"gnucash-docs\" package is not properly installed.");
73const gchar *msg_no_help_location = N_(
"Expected location");
78 gnc_component_manager_init ();
80 scm_init_sw_gnome_utils_module();
81 scm_c_use_module (
"sw_gnome_utils");
82 scm_c_use_module(
"gnucash gnome-utils");
93gnc_configure_date_format (
void)
96 GNC_PREF_DATE_FORMAT);
103 PERR(
"Incorrect date format");
120gnc_configure_date_completion (
void)
124 GNC_PREF_DATE_BACKMONTHS);
128 else if (backmonths > 11)
140 GtkCssProvider *provider_user, *provider_app, *provider_fallback;
146 provider_user = gtk_css_provider_new ();
147 provider_app = gtk_css_provider_new ();
148 provider_fallback = gtk_css_provider_new ();
149 display = gdk_display_get_default ();
150 screen = gdk_display_get_default_screen (display);
152 gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider_fallback), GTK_STYLE_PROVIDER_PRIORITY_FALLBACK);
153 gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider_app), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
154 gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider_user), GTK_STYLE_PROVIDER_PRIORITY_USER);
156 gtk_css_provider_load_from_resource (provider_app, GNUCASH_RESOURCE_PREFIX
"/gnucash.css");
157 gtk_css_provider_load_from_resource (provider_fallback, GNUCASH_RESOURCE_PREFIX
"/gnucash-fallback.css");
159 var = gnc_userconfig_dir ();
163 str = g_build_filename (var,
"gtk-3.0.css", (
char *)NULL);
164 gtk_css_provider_load_from_path (provider_user, str, &error);
167 g_object_unref (provider_user);
168 g_object_unref (provider_app);
169 g_object_unref (provider_fallback);
172#ifdef MAC_INTEGRATION
179gnc_gnome_help (GtkWindow *parent,
const char *dir,
const char *detail)
181 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
182 NSString *subdir = [NSString stringWithUTF8String: dir];
187 tag = [NSString stringWithUTF8String: detail];
191 if (![[NSBundle mainBundle] bundleIdentifier])
200 NSArray *components = [NSArray arrayWithObjects:
@"share",
@"doc",
@"gnucash-docs", nil ];
201 NSString *prefix = [[[NSBundle mainBundle] resourcePath]
202 stringByDeletingLastPathComponent];
203 NSArray *prefix_comps = [[prefix pathComponents]
204 arrayByAddingObjectsFromArray: components];
205 NSString *docs_dir = [NSString pathWithComponents: prefix_comps];
206 NSArray *languages = [[NSUserDefaults standardUserDefaults]
207 objectForKey:
@"AppleLanguages"];
209 subdir = [[[subdir lowercaseString] componentsSeparatedByString:
@" "]
210 componentsJoinedByString:
@"-"];
211 if (![[NSFileManager defaultManager] fileExistsAtPath: docs_dir])
213 gnc_error_dialog (parent,
"%s\n%s\n%s: %s",
_(msg_no_help_found),
214 _(msg_no_help_reason),
215 _(msg_no_help_location), [docs_dir UTF8String]);
219 if ([languages count] > 0)
221 NSEnumerator *lang_iter = [languages objectEnumerator];
224 while ((this_lang = [lang_iter nextObject]))
228 NSString *completed_path = [NSString alloc];
229 this_lang = [this_lang stringByTrimmingCharactersInSet:
230 [NSCharacterSet characterSetWithCharactersInString:
232 elements = [this_lang componentsSeparatedByString: @"-
"];
233 this_lang = [elements objectAtIndex: 0];
234 path = [docs_dir stringByAppendingPathComponent: this_lang];
235 paths = [path completePathIntoString: &completed_path
237 matchesIntoArray: NULL filterTypes: NULL];
239 [[NSFileManager defaultManager]
240 fileExistsAtPath: completed_path
246 url = [NSURL fileURLWithPath:
248 stringByAppendingPathComponent: subdir]
249 stringByAppendingPathComponent: tag]
250 stringByAppendingPathExtension: @"html
"]];
252 @catch (NSException *e)
254 PWARN("fileURLWithPath threw %s: %s
",
255 [[e name] UTF8String], [[e reason] UTF8String]);
260 if ([this_lang compare: @"en
"] == NSOrderedSame)
261 break; /* Special case, forces use of "C
" locale */
269 fileURLWithPath: [[[[docs_dir
270 stringByAppendingPathComponent: @"C
"]
271 stringByAppendingPathComponent: subdir]
272 stringByAppendingPathComponent: tag]
273 stringByAppendingPathExtension: @"html
"]];
275 @catch (NSException *e)
277 PWARN("fileURLWithPath threw %s: %s
",
278 [[e name] UTF8String], [[e reason] UTF8String]);
283 /* It's a lot easier in a bundle! OSX finds the best translation for us. */
288 url = [NSURL fileURLWithPath: [[NSBundle mainBundle]
291 inDirectory: subdir ]];
293 @catch (NSException *e)
295 PWARN("fileURLWithPath threw %s: %s
",
296 [[e name] UTF8String], [[e reason] UTF8String]);
300 /* Now just open the URL in the default app for opening URLs */
302 [[NSWorkspace sharedWorkspace] openURL: url];
305 gnc_error_dialog (parent, "%s\n%s
", _(msg_no_help_found), _(msg_no_help_reason));
309#elif defined G_OS_WIN32 /* G_OS_WIN32 */
311gnc_gnome_help (GtkWindow *parent, const char *file_name, const char *anchor)
313 const gchar * const *lang;
314 gchar *pkgdatadir, *fullpath, *found = NULL;
316 pkgdatadir = gnc_path_get_pkgdatadir ();
317 for (lang = g_get_language_names (); *lang; lang++)
319 fullpath = g_build_filename (pkgdatadir, "help
", *lang, file_name,
321 if (g_file_test (fullpath, G_FILE_TEST_IS_REGULAR))
323 found = g_strdup (fullpath);
333 gnc_error_dialog (parent, "%s\n%s
", _(msg_no_help_found), _(msg_no_help_reason));
337 gnc_show_htmlhelp (found, anchor);
343gnc_gnome_help (GtkWindow *parent, const char *file_name, const char *anchor)
345 GError *error = NULL;
347 gboolean success = TRUE;
350 uri = g_strconcat ("help:
", file_name, "/
", anchor, NULL);
352 uri = g_strconcat ("help:
", file_name, NULL);
354 DEBUG ("Attempting to opening help uri %s
", uri);
357 success = gtk_show_uri_on_window (NULL, uri, gtk_get_current_event_time (), &error);
363 g_assert(error != NULL);
365 gnc_error_dialog (parent, "%s\n%s
", _(msg_no_help_found), _(msg_no_help_reason));
367 PERR ("%s
", error->message);
374#ifdef MAC_INTEGRATION
376/* Don't be alarmed if this function looks strange to you: It's
377 * written in Objective-C, the native language of the OSX Cocoa
381gnc_launch_doclink (GtkWindow *parent, const char *uri)
383 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
384 NSString *uri_str = [NSString stringWithUTF8String: uri];
385 NSURL *url = [[[NSURL alloc] initWithString: uri_str] autorelease];
386 const gchar *message =
387 _("GnuCash could not find the linked document.
");
391 [[NSWorkspace sharedWorkspace] openURL: url];
396 gnc_error_dialog (parent, "%s
", message);
401#elif defined G_OS_WIN32 /* G_OS_WIN32 */
403gnc_launch_doclink (GtkWindow *parent, const char *uri)
405 wchar_t *winuri = NULL;
406 gchar *filename = NULL;
407 /* ShellExecuteW open doesn't decode http escapes if it's passed a
408 * file URI so we have to do it. */
409 if (gnc_uri_is_file_uri (uri))
411 gchar *uri_scheme = gnc_uri_get_scheme (uri);
412 filename = gnc_doclink_get_unescape_uri (NULL, uri, uri_scheme);
413 winuri = (wchar_t *)g_utf8_to_utf16(filename, -1, NULL, NULL, NULL);
417 winuri = (wchar_t *)g_utf8_to_utf16(uri, -1, NULL, NULL, NULL);
421 wchar_t *wincmd = (wchar_t *)g_utf8_to_utf16("open
", -1,
423 if ((INT_PTR)ShellExecuteW(NULL, wincmd, winuri,
424 NULL, NULL, SW_SHOWNORMAL) <= 32)
426 const gchar *message =
427 _("GnuCash could not find the linked document.
");
428 gnc_error_dialog (parent, "%s:\n%s
", message, filename);
438gnc_launch_doclink (GtkWindow *parent, const char *uri)
440 GError *error = NULL;
446 DEBUG ("Attempting to open uri %s
", uri);
448 success = gtk_show_uri_on_window (NULL, uri, gtk_get_current_event_time (), &error);
453 g_assert (error != NULL);
455 gchar *error_uri = NULL;
456 const gchar *message =
457 _("GnuCash could not open the linked document:
");
459 if (gnc_uri_is_file_uri (uri))
461 gchar *uri_scheme = gnc_uri_get_scheme (uri);
462 error_uri = gnc_doclink_get_unescape_uri (NULL, uri, uri_scheme);
466 error_uri = g_strdup (uri);
468 gnc_error_dialog (parent, "%s\n%s
", message, error_uri);
471 PERR ("%s
", error->message);
472 g_error_free (error);
485gnc_gnome_get_pixmap (const char *name)
490 g_return_val_if_fail (name != NULL, NULL);
492 fullname = gnc_filepath_locate_pixmap (name);
493 if (fullname == NULL)
496 DEBUG ("Loading pixmap file %s
", fullname);
498 pixmap = gtk_image_new_from_file (fullname);
501 PERR ("Could not load pixmap
");
516gnc_gnome_get_gdkpixbuf (const char *name)
519 GError *error = NULL;
522 g_return_val_if_fail (name != NULL, NULL);
524 fullname = gnc_filepath_locate_pixmap (name);
525 if (fullname == NULL)
528 DEBUG ("Loading pixbuf file %s
", fullname);
529 pixbuf = gdk_pixbuf_new_from_file (fullname, &error);
532 g_assert (pixbuf == NULL);
533 PERR ("Could not load pixbuf: %s
", error->message);
534 g_error_free (error);
542gnc_ui_check_events (gpointer not_used)
547 if (gtk_main_level() != 1)
550 if (!gnc_current_session_exist())
552 session = gnc_get_current_session ();
554 if (gnc_gui_refresh_suspended ())
557 if (!qof_session_events_pending (session))
560 gnc_suspend_gui_refresh ();
562 force = qof_session_process_events (session);
564 gnc_resume_gui_refresh ();
567 gnc_gui_refresh_all ();
574gnc_ui_start_event_loop (void)
578 gnome_is_running = TRUE;
580 id = g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, 10000, /* 10 secs */
581 gnc_ui_check_events, NULL, NULL);
583 scm_call_1(scm_c_eval_string("gnc:set-ui-status
"), SCM_BOOL_T);
585 /* Enter gnome event loop */
588 g_source_remove (id);
590 scm_call_1(scm_c_eval_string("gnc:set-ui-status
"), SCM_BOOL_F);
592 gnome_is_running = FALSE;
593 gnome_is_terminating = FALSE;
601 static GncMainWindow *main_window;
606 if (gnome_is_initialized)
609 /* use custom icon */
610 gnc_load_app_icons();
611 gtk_window_set_default_icon_name(GNC_ICON_APP);
613 g_set_application_name(PACKAGE_NAME);
616 gnc_show_splash_screen();
618 gnome_is_initialized = TRUE;
621 gnc_configure_date_format();
622 gnc_configure_date_completion();
624 gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
625 GNC_PREF_DATE_FORMAT,
626 gnc_configure_date_format,
628 gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
629 GNC_PREF_DATE_COMPL_THISYEAR,
630 gnc_configure_date_completion,
632 gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
633 GNC_PREF_DATE_COMPL_SLIDING,
634 gnc_configure_date_completion,
636 gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
637 GNC_PREF_DATE_BACKMONTHS,
638 gnc_configure_date_completion,
640 gnc_prefs_register_group_cb (GNC_PREFS_GROUP_GENERAL,
644 gnc_file_set_shutdown_callback (gnc_shutdown);
646 main_window = gnc_main_window_new ();
648 // gtk_widget_show (GTK_WIDGET (main_window));
649 gnc_window_set_progressbar_window (GNC_WINDOW(main_window));
652 map = gnc_build_userdata_path(ACCEL_MAP_NAME);
653 if (!g_file_test (map, G_FILE_TEST_EXISTS))
658 gchar *data_dir = gnc_path_get_pkgdatadir();
659#ifdef MAC_INTEGRATION
660 map_source = g_build_filename (data_dir, "ui
", "accelerator-map-osx
", NULL);
662 map_source = g_build_filename (data_dir, "ui
", "accelerator-map
", NULL);
663#endif /* MAC_INTEGRATION */
665 if (map_source && g_file_get_contents (map_source, &text, &length, NULL))
668 g_file_set_contents (map, text, length, NULL);
675 gtk_accel_map_load(map);
678 /* Load css configuration file */
681 gnc_totd_dialog (gnc_get_splash_screen (), TRUE);
688gnucash_ui_is_running(void)
690 return gnome_is_running;
694gnc_gui_destroy (void)
696 if (!gnome_is_initialized)
699 if (gnc_prefs_is_set_up())
701 gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
702 GNC_PREF_DATE_FORMAT,
703 gnc_configure_date_format,
705 gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
706 GNC_PREF_DATE_COMPL_THISYEAR,
707 gnc_configure_date_completion,
709 gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
710 GNC_PREF_DATE_COMPL_SLIDING,
711 gnc_configure_date_completion,
713 gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
714 GNC_PREF_DATE_BACKMONTHS,
715 gnc_configure_date_completion,
717 gnc_prefs_remove_group_cb_by_func (GNC_PREFS_GROUP_GENERAL,
721 gnc_ui_util_remove_registered_prefs ();
722 gnc_prefs_remove_registered ();
724 gnc_extensions_shutdown ();
728gnc_gui_shutdown (void)
732 if (gnome_is_running && !gnome_is_terminating)
734 gnome_is_terminating = TRUE;
735// map = gnc_build_userdata_path(ACCEL_MAP_NAME);
736// gtk_accel_map_save(map);
738 gnc_component_manager_shutdown ();
743/* shutdown gnucash. This function will initiate an orderly
744 * shutdown, and when that has finished it will exit the program.
747gnc_shutdown (int exit_status)
749 if (gnucash_ui_is_running())
751 if (!gnome_is_terminating)
753 if (gnc_file_query_save (gnc_ui_get_main_window (NULL), FALSE))
755 gnc_hook_run(HOOK_UI_SHUTDOWN, NULL);
763 gnc_hook_run(HOOK_SHUTDOWN, NULL);
764 gnc_engine_shutdown();
"select" and "new" commodity windows
All type declarations for the whole Gnucash engine.
File path resolution utility functions.
Gnome specific utility functions.
Preferences initialization function.
Generic api to store and retrieve preferences.
utility functions for the GnuCash UI
Utility functions for convert uri in separate components and back.
Functions that are supported by all types of windows.
void qof_date_format_set(QofDateFormat df)
The qof_date_format_set() routine sets date format to one of US, UK, CE, OR ISO.
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...
QofDateFormat
Enum for determining a date format.
QofDateCompletion
Enum for date completion modes (for dates entered without year)
@ QOF_DATE_FORMAT_LOCALE
Take from locale information.
@ QOF_DATE_COMPLETION_THISYEAR
use current year
@ QOF_DATE_COMPLETION_SLIDING
use sliding 12-month window
void gnc_add_css_file(void)
Load a gtk resource configuration file to customize gtk appearance and behaviour.
void gnc_gnome_utils_init(void)
Initialize the gnome-utils library Should be run once before using any gnome-utils features.
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome's yelp for linux, and open to a given link within a gi...
#define PERR(format, args...)
Log a serious error.
gdouble gnc_prefs_get_float(const gchar *group, const gchar *pref_name)
Get an float value from the preferences backend.
gint gnc_prefs_get_int(const gchar *group, const gchar *pref_name)
Get an integer value from the preferences backend.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.