/*
* 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], "