/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with the program; if not, see * * * Authors: * Chris Lahey * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef G_OS_WIN32 #include #endif #include #include #include #include "filter/e-filter-option.h" #include "e-util.h" #include "e-util-private.h" /** * e_get_user_data_dir: * * Returns the base directory for Evolution-specific user data. * The string is owned by Evolution and must not be modified or freed. * * Returns: base directory for user data **/ const gchar * e_get_user_data_dir (void) { static gchar *dirname = NULL; if (G_UNLIKELY (dirname == NULL)) dirname = g_build_filename ( g_get_home_dir (), ".evolution", NULL); return dirname; } /** * e_get_accels_filename: * * Returns the name of the user data file containing custom keyboard * accelerator specifications. * * Returns: filename for accelerator specifications **/ const gchar * e_get_accels_filename (void) { static gchar *filename = NULL; /* XXX The directory corresponds to gnome_user_accels_dir_get() * from libgnome. Continue using this location until GNOME * decides on an XDG-compliant location. Perhaps something * like $(XDG_CONFIG_DIR)/accels. */ if (G_UNLIKELY (filename == NULL)) filename = g_build_filename ( g_get_home_dir (), ".gnome2", "accels", PACKAGE, NULL); return filename; } /** * e_show_uri: * @parent: a parent #GtkWindow or %NULL * @uri: the URI to show * * Launches the default application to show the given URI. The URI must * be of a form understood by GIO. If the URI cannot be shown, it presents * a dialog describing the error. The dialog is set as transient to @parent * if @parent is non-%NULL. **/ void e_show_uri (GtkWindow *parent, const gchar *uri) { GtkWidget *dialog; GdkScreen *screen = NULL; GError *error = NULL; gchar *decoded_uri; guint32 timestamp; g_return_if_fail (uri != NULL); timestamp = gtk_get_current_event_time (); if (parent != NULL) screen = gtk_widget_get_screen (GTK_WIDGET (parent)); decoded_uri = g_strdup (uri); camel_url_decode (decoded_uri); if (gtk_show_uri (screen, decoded_uri, timestamp, &error)) goto exit; dialog = gtk_message_dialog_new_with_markup ( parent, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", _("Could not open the link.")); gtk_message_dialog_format_secondary_text ( GTK_MESSAGE_DIALOG (dialog), "%s", error->message); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); g_error_free (error); exit: g_free (decoded_uri); } /** * e_display_help: * @parent: a parent #GtkWindow or %NULL * @link_id: help section to present or %NULL * * Opens the user documentation to the section given by @link_id, or to the * table of contents if @link_id is %NULL. If the user documentation cannot * be opened, it presents a dialog describing the error. The dialog is set * as transient to @parent if @parent is non-%NULL. **/ void e_display_help (GtkWindow *parent, const gchar *link_id) { GString *uri; GtkWidget *dialog; GdkScreen *screen = NULL; GError *error = NULL; guint32 timestamp; uri = g_string_new ("ghelp:" PACKAGE); timestamp = gtk_get_current_event_time (); if (parent != NULL) screen = gtk_widget_get_screen (GTK_WIDGET (parent)); if (link_id != NULL) g_string_append_printf (uri, "?%s", link_id); if (gtk_show_uri (screen, uri->str, timestamp, &error)) goto exit; dialog = gtk_message_dialog_new_with_markup ( parent, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", _("Could not display help for Evolution.")); gtk_message_dialog_format_secondary_text ( GTK_MESSAGE_DIALOG (dialog), "%s", error->message); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); g_error_free (error); exit: g_string_free (uri, TRUE); } /** * e_lookup_action: * @ui_manager: a #GtkUIManager * @action_name: the name of an action * * Returns the first #GtkAction named @action_name by traversing the * list of action groups in @ui_manager. If no such action exists, the * function emits a critical warning before returning %NULL, since this * probably indicates a programming error and most code is not prepared * to deal with lookup failures. * * Returns: the first #GtkAction named @action_name **/ GtkAction * e_lookup_action (GtkUIManager *ui_manager, const gchar *action_name) { GtkAction *action = NULL; GList *iter; g_return_val_if_fail (GTK_IS_UI_MANAGER (ui_manager), NULL); g_return_val_if_fail (action_name != NULL, NULL); iter = gtk_ui_manager_get_action_groups (ui_manager); while (iter != NULL) { GtkActionGroup *action_group = iter->data; action = gtk_action_group_get_action ( action_group, action_name); if (action != NULL) return action; iter = g_list_next (iter); } g_critical ("%s: action `%s' not found", G_STRFUNC, action_name); return NULL; } /** * e_lookup_action_group: * @ui_manager: a #GtkUIManager * @group_name: the name of an action group * * Returns the #GtkActionGroup in @ui_manager named @group_name. If no * such action group exists, the function emits a critical warnings before * returning %NULL, since this probably indicates a programming error and * most code is not prepared to deal with lookup failures. * * Returns: the #GtkActionGroup named @group_name **/ GtkActionGroup * e_lookup_action_group (GtkUIManager *ui_manager, const gchar *group_name) { GList *iter; g_return_val_if_fail (GTK_IS_UI_MANAGER (ui_manager), NULL); g_return_val_if_fail (group_name != NULL, NULL); iter = gtk_ui_manager_get_action_groups (ui_manager); while (iter != NULL) { GtkActionGroup *action_group = iter->data; const gchar *name; name = gtk_action_group_get_name (action_group); if (strcmp (name, group_name) == 0) return action_group; iter = g_list_next (iter); } g_critical ("%s: action group `%s' not found", G_STRFUNC, group_name); return NULL; } /** * e_load_ui_builder_definition: * @builder: a #GtkBuilder * @basename: basename of the UI definition file * * Loads a UI definition into @builder from Evolution's UI directory. * Failure here is fatal, since the application can't function without * its UI definitions. **/ void e_load_ui_builder_definition (GtkBuilder *builder, const gchar *basename) { gchar *filename; GError *error = NULL; g_return_if_fail (GTK_IS_BUILDER (builder)); g_return_if_fail (basename != NULL); filename = g_build_filename (EVOLUTION_UIDIR, basename, NULL); gtk_builder_add_from_file (builder, filename, &error); g_free (filename); if (error != NULL) { g_error ("%s: %s", basename, error->message); g_assert_not_reached (); } } /** * e_load_ui_manager_definition: * @ui_manager: a #GtkUIManager * @basename: basename of the UI definition file * @is_express: are we in 'express' mode ? * * Loads a UI definition into @ui_manager from Evolution's UI directory. * Failure here is fatal, since the application can't function without * its UI definitions. Depending on the mode signalled by @is_express a * simplified version of the UI may be presented. * * Returns: The merge ID for the merged UI. The merge ID can be used to * unmerge the UI with gtk_ui_manager_remove_ui(). **/ guint e_load_ui_manager_definition (GtkUIManager *ui_manager, const gchar *basename, gboolean is_express) { gchar *filename; guint merge_id = 0; GError *error = NULL; gchar *buffer; g_return_val_if_fail (GTK_IS_UI_MANAGER (ui_manager), 0); g_return_val_if_fail (basename != NULL, 0); filename = g_build_filename (EVOLUTION_UIDIR, basename, NULL); /* * Very simple line based pre-processing based on comments: * ... */ if (g_file_get_contents (filename, &buffer, NULL, &error)) { int i; gchar *filtered, **lines; gboolean include = TRUE; lines = g_strsplit (buffer, "\n", -1); for (i = 0; lines[i]; i++) { char *p; if ((p = strstr (lines[i], "