aboutsummaryrefslogtreecommitdiffstats
path: root/e-util
diff options
context:
space:
mode:
Diffstat (limited to 'e-util')
-rw-r--r--e-util/Makefile.am20
-rw-r--r--e-util/e-account-utils.c96
-rw-r--r--e-util/e-account-utils.h (renamed from e-util/e-corba-utils.c)36
-rw-r--r--e-util/e-corba-utils.h31
-rw-r--r--e-util/e-dialog-utils.c26
-rw-r--r--e-util/e-dialog-utils.h2
-rw-r--r--e-util/e-gui-utils.c66
-rw-r--r--e-util/e-logger.c74
-rw-r--r--e-util/e-logger.h26
-rw-r--r--e-util/e-marshal.list1
-rw-r--r--e-util/e-non-intrusive-error-dialog.c1
-rw-r--r--e-util/e-non-intrusive-error-dialog.h2
-rw-r--r--e-util/e-plugin-ui.c435
-rw-r--r--e-util/e-plugin-ui.h9
-rw-r--r--e-util/e-signature-utils.c347
-rw-r--r--e-util/e-signature-utils.h (renamed from e-util/e-gui-utils.h)27
-rw-r--r--e-util/e-util-labels.c586
-rw-r--r--e-util/e-util-labels.h57
-rw-r--r--e-util/e-util.c238
-rw-r--r--e-util/e-util.h20
-rw-r--r--e-util/gconf-bridge.c6
21 files changed, 1098 insertions, 1008 deletions
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index ee54891c1d..e8df3bcb13 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -34,18 +34,18 @@ INCLUDES = \
-DSEARCH_RULE_DIR=\"$(ruledir)\" \
-DG_LOG_DOMAIN=\"e-utils\" \
$(GNOME_PILOT_CFLAGS) \
- $(ICONV_CFLAGS) \
+ $(ICONV_CFLAGS) \
$(E_UTIL_CFLAGS)
privsolib_LTLIBRARIES = libeutil.la libeconduit.la
eutilinclude_HEADERS = \
+ e-account-utils.h \
e-bconf-map.h \
e-binding.h \
e-categories-config.h \
e-config.h \
e-config-listener.h \
- e-corba-utils.h \
e-cursor.h \
e-dialog-utils.h \
e-dialog-widgets.h \
@@ -53,15 +53,14 @@ eutilinclude_HEADERS = \
e-event.h \
e-folder-map.h \
e-fsutils.h \
- e-gui-utils.h \
e-html-utils.h \
e-icon-factory.h \
e-import.h \
e-logger.h \
- e-non-intrusive-error-dialog.h \
e-marshal.h \
e-menu.h \
e-mktemp.h \
+ e-non-intrusive-error-dialog.h \
e-print.h \
e-plugin.h \
e-plugin-ui.h \
@@ -70,6 +69,7 @@ eutilinclude_HEADERS = \
e-request.h \
e-signature.h \
e-signature-list.h \
+ e-signature-utils.h \
e-bit-array.h \
e-sorter.h \
e-sorter-array.h \
@@ -77,17 +77,16 @@ eutilinclude_HEADERS = \
e-text-event-processor-types.h \
e-text-event-processor.h \
e-util.h \
- e-util-labels.h \
e-xml-utils.h
libeutil_la_SOURCES = \
$(eutilinclude_HEADERS) \
+ e-account-utils.c \
e-bconf-map.c \
e-binding.c \
e-categories-config.c \
- e-config.c \
e-config-listener.c \
- e-corba-utils.c \
+ e-config.c \
e-cursor.c \
e-dialog-utils.c \
e-dialog-widgets.c \
@@ -95,30 +94,29 @@ libeutil_la_SOURCES = \
e-event.c \
e-folder-map.c \
e-fsutils.c \
- e-gui-utils.c \
e-html-utils.c \
e-icon-factory.c \
e-import.c \
e-logger.c \
- e-non-intrusive-error-dialog.c \
e-marshal.c \
e-menu.c \
e-mktemp.c \
- e-plugin.c \
+ e-non-intrusive-error-dialog.c \
e-plugin-ui.c \
+ e-plugin.c \
e-popup.c \
e-print.c \
e-profile-event.c \
e-request.c \
e-signature.c \
e-signature-list.c \
+ e-signature-utils.c \
e-bit-array.c \
e-sorter.c \
e-sorter-array.c \
e-text-event-processor-emacs-like.c \
e-text-event-processor.c \
e-util.c \
- e-util-labels.c \
e-util-private.h \
e-xml-utils.c \
gconf-bridge.c \
diff --git a/e-util/e-account-utils.c b/e-util/e-account-utils.c
new file mode 100644
index 0000000000..d98a378b48
--- /dev/null
+++ b/e-util/e-account-utils.c
@@ -0,0 +1,96 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#include "e-account-utils.h"
+
+#include <gconf/gconf-client.h>
+
+static EAccountList *global_account_list;
+
+EAccountList *
+e_get_account_list (void)
+{
+ if (G_UNLIKELY (global_account_list == NULL)) {
+ GConfClient *client;
+
+ client = gconf_client_get_default ();
+ global_account_list = e_account_list_new (client);
+ g_object_unref (client);
+ }
+
+ g_return_val_if_fail (global_account_list != NULL, NULL);
+
+ return global_account_list;
+}
+
+EAccount *
+e_get_default_account (void)
+{
+ EAccountList *account_list;
+ const EAccount *account;
+
+ account_list = e_get_account_list ();
+ account = e_account_list_get_default (account_list);
+
+ /* XXX EAccountList misuses const. */
+ return (EAccount *) account;
+}
+
+void
+e_set_default_account (EAccount *account)
+{
+ EAccountList *account_list;
+
+ g_return_if_fail (E_IS_ACCOUNT (account));
+
+ account_list = e_get_account_list ();
+ e_account_list_set_default (account_list, account);
+}
+
+EAccount *
+e_get_account_by_name (const gchar *name)
+{
+ EAccountList *account_list;
+ const EAccount *account;
+ e_account_find_t find;
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+ find = E_ACCOUNT_FIND_NAME;
+ account_list = e_get_account_list ();
+ account = e_account_list_find (account_list, find, name);
+
+ /* XXX EAccountList misuses const. */
+ return (EAccount *) account;
+}
+
+EAccount *
+e_get_account_by_uid (const gchar *uid)
+{
+ EAccountList *account_list;
+ const EAccount *account;
+ e_account_find_t find;
+
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ find = E_ACCOUNT_FIND_UID;
+ account_list = e_get_account_list ();
+ account = e_account_list_find (account_list, find, uid);
+
+ /* XXX EAccountList misuses const. */
+ return (EAccount *) account;
+}
diff --git a/e-util/e-corba-utils.c b/e-util/e-account-utils.h
index 0288602a7e..24262349d2 100644
--- a/e-util/e-corba-utils.c
+++ b/e-util/e-account-utils.h
@@ -12,32 +12,24 @@
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#ifndef E_ACCOUNT_UTILS_H
+#define E_ACCOUNT_UTILS_H
+
+#include <glib.h>
+#include <libedataserver/e-account.h>
+#include <libedataserver/e-account-list.h>
-#include "e-corba-utils.h"
+G_BEGIN_DECLS
-
-const CORBA_char *
-e_safe_corba_string (const char *s)
-{
- if (s == NULL)
- return (CORBA_char *) "";
+EAccountList * e_get_account_list (void);
+EAccount * e_get_default_account (void);
+void e_set_default_account (EAccount *account);
+EAccount * e_get_account_by_name (const gchar *name);
+EAccount * e_get_account_by_uid (const gchar *uid);
- return s;
-}
+G_END_DECLS
-CORBA_char *
-e_safe_corba_string_dup (const char *s)
-{
- return CORBA_string_dup (e_safe_corba_string (s));
-}
+#endif /* E_ACCOUNT_UTILS_H */
diff --git a/e-util/e-corba-utils.h b/e-util/e-corba-utils.h
deleted file mode 100644
index 979237929d..0000000000
--- a/e-util/e-corba-utils.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_CORBA_UTILS_H
-#define E_CORBA_UTILS_H
-
-#include <orbit/orbit.h>
-
-const CORBA_char *e_safe_corba_string (const char *s);
-CORBA_char *e_safe_corba_string_dup (const char *s);
-
-#endif
diff --git a/e-util/e-dialog-utils.c b/e-util/e-dialog-utils.c
index 0546430512..7d1d4836b6 100644
--- a/e-util/e-dialog-utils.c
+++ b/e-util/e-dialog-utils.c
@@ -344,29 +344,29 @@ e_file_dialog_save_folder (const char *title)
* no signals connected and is not shown.
**/
GtkWidget *
-e_file_get_save_filesel (GtkWidget *parent, const char *title, const char *name, GtkFileChooserAction action)
+e_file_get_save_filesel (GtkWindow *parent, const char *title, const char *name, GtkFileChooserAction action)
{
GtkWidget *filesel;
char *uri;
- filesel = gtk_file_chooser_dialog_new (title,
- NULL,
- action,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- (action == GTK_FILE_CHOOSER_ACTION_OPEN) ? GTK_STOCK_OPEN:GTK_STOCK_SAVE, GTK_RESPONSE_OK,
- NULL);
+ g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
+
+ filesel = gtk_file_chooser_dialog_new (
+ title, parent, action,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ (action == GTK_FILE_CHOOSER_ACTION_OPEN) ?
+ GTK_STOCK_OPEN : GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
gtk_dialog_set_default_response (GTK_DIALOG (filesel), GTK_RESPONSE_OK);
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (filesel), FALSE);
- if (parent)
- e_dialog_set_transient_for((GtkWindow *)filesel, parent);
-
- uri = e_file_get_save_path();
+ uri = e_file_get_save_path ();
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (filesel), uri);
+ gtk_file_chooser_set_current_folder_uri (
+ GTK_FILE_CHOOSER (filesel), uri);
if (name && name[0])
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (filesel), name);
+ gtk_file_chooser_set_current_name (
+ GTK_FILE_CHOOSER (filesel), name);
g_free (uri);
diff --git a/e-util/e-dialog-utils.h b/e-util/e-dialog-utils.h
index 9d594122e2..9e6e7992c1 100644
--- a/e-util/e-dialog-utils.h
+++ b/e-util/e-dialog-utils.h
@@ -43,7 +43,7 @@ char *e_file_dialog_save (const char *title, const char *fname)
char *e_file_dialog_save_folder (const char *title);
-GtkWidget * e_file_get_save_filesel (GtkWidget *parent, const char *title, const char *name, GtkFileChooserAction action);
+GtkWidget * e_file_get_save_filesel (GtkWindow *parent, const char *title, const char *name, GtkFileChooserAction action);
gboolean e_file_can_save(GtkWindow *parent, const char *uri);
gboolean e_file_check_local(const char *name);
diff --git a/e-util/e-gui-utils.c b/e-util/e-gui-utils.c
deleted file mode 100644
index 37d3fc9c48..0000000000
--- a/e-util/e-gui-utils.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * GUI utility functions
- *
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Miguel de Icaza (miguel@ximian.com)
- * Chris Toshok (toshok@ximian.com)
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include "e-gui-utils.h"
-
-#include <libgnome/gnome-program.h>
-#include <libgnomeui/gnome-icon-lookup.h>
-
-/**
- * e_icon_for_mime_type:
- * @mime_type: a MIME type
- * @size_hint: the size the caller plans to display the icon at
- *
- * Tries to find an icon representing @mime_type that will display
- * nicely at @size_hint by @size_hint pixels. The returned icon
- * may or may not actually be that size.
- *
- * Return value: a pixbuf, which the caller must unref when it is done
- **/
-GdkPixbuf *
-e_icon_for_mime_type (const char *mime_type, int size_hint)
-{
- gchar *icon_name;
- GdkPixbuf *pixbuf = NULL;
-
- icon_name = gnome_icon_lookup (
- gtk_icon_theme_get_default (),
- NULL, NULL, NULL, NULL, mime_type, 0, NULL);
-
- if (icon_name != NULL) {
- pixbuf = gtk_icon_theme_load_icon (
- gtk_icon_theme_get_default (),
- icon_name, size_hint, 0, NULL);
- g_free (icon_name);
- }
-
- return pixbuf;
-}
diff --git a/e-util/e-logger.c b/e-util/e-logger.c
index 9db0ca0e37..c304e362e6 100644
--- a/e-util/e-logger.c
+++ b/e-util/e-logger.c
@@ -43,7 +43,7 @@
((obj), E_TYPE_LOGGER, ELoggerPrivate))
struct _ELoggerPrivate {
- gchar *component;
+ gchar *name;
gchar *logfile;
FILE *fp;
@@ -52,13 +52,13 @@ struct _ELoggerPrivate {
enum {
PROP_0,
- PROP_COMPONENT
+ PROP_NAME
};
static gpointer parent_class;
static gboolean
-flush_logfile (ELogger *logger)
+logger_flush (ELogger *logger)
{
if (logger->priv->fp)
fflush (logger->priv->fp);
@@ -68,16 +68,26 @@ flush_logfile (ELogger *logger)
}
static void
-logger_set_component (ELogger *logger,
- const gchar *component)
+logger_set_dirty (ELogger *logger)
+{
+ if (logger->priv->timer)
+ return;
+
+ logger->priv->timer = g_timeout_add (
+ TIMEOUT_INTERVAL, (GSourceFunc) logger_flush, logger);
+}
+
+static void
+logger_set_name (ELogger *logger,
+ const gchar *name)
{
gchar *temp;
- g_return_if_fail (logger->priv->component == NULL);
+ g_return_if_fail (logger->priv->name == NULL);
- temp = g_strdup_printf ("%s.log.XXXXXX", component);
+ temp = g_strdup_printf ("%s.log.XXXXXX", name);
- logger->priv->component = g_strdup (component);
+ logger->priv->name = g_strdup (name);
logger->priv->logfile = e_mktemp (temp);
logger->priv->fp = g_fopen (logger->priv->logfile, "w");
logger->priv->timer = 0;
@@ -95,8 +105,8 @@ logger_set_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
- case PROP_COMPONENT:
- logger_set_component (
+ case PROP_NAME:
+ logger_set_name (
E_LOGGER (object),
g_value_get_string (value));
return;
@@ -112,9 +122,9 @@ logger_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
- case PROP_COMPONENT:
+ case PROP_NAME:
g_value_set_string (
- value, e_logger_get_component (
+ value, e_logger_get_name (
E_LOGGER (object)));
return;
}
@@ -133,7 +143,7 @@ logger_finalize (GObject *object)
if (logger->priv->fp)
fclose (logger->priv->fp);
- g_free (logger->priv->component);
+ g_free (logger->priv->name);
g_free (logger->priv->logfile);
/* Chain up to parent's finalize() method. */
@@ -155,11 +165,11 @@ logger_class_init (ELoggerClass *class)
g_object_class_install_property (
object_class,
- PROP_COMPONENT,
+ PROP_NAME,
g_param_spec_string (
- "component",
- _("Component"),
- _("Name of the component being logged"),
+ "name",
+ _("Name"),
+ _("Name of the logger"),
"anonymous",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
@@ -198,34 +208,24 @@ e_logger_get_type (void)
}
ELogger *
-e_logger_create (gchar *component)
+e_logger_new (const gchar *name)
{
- g_return_val_if_fail (component != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
- return g_object_new (E_TYPE_LOGGER, "component", component, NULL);
+ return g_object_new (E_TYPE_LOGGER, "name", name, NULL);
}
const gchar *
-e_logger_get_component (ELogger *logger)
+e_logger_get_name (ELogger *logger)
{
g_return_val_if_fail (E_IS_LOGGER (logger), NULL);
- return logger->priv->component;
-}
-
-static void
-set_dirty (ELogger *logger)
-{
- if (logger->priv->timer)
- return;
-
- logger->priv->timer = g_timeout_add (
- TIMEOUT_INTERVAL, (GSourceFunc) flush_logfile, logger);
+ return logger->priv->name;
}
void
e_logger_log (ELogger *logger,
- gint level,
+ ELogLevel level,
gchar *primary,
gchar *secondary)
{
@@ -240,13 +240,13 @@ e_logger_log (ELogger *logger,
fprintf (logger->priv->fp, "%d:%ld:%s\n", level, t, primary);
fprintf (logger->priv->fp, "%d:%ld:%s\n", level, t, secondary);
- set_dirty (logger);
+ logger_set_dirty (logger);
}
void
e_logger_get_logs (ELogger *logger,
ELogFunction func,
- gpointer data)
+ gpointer user_data)
{
FILE *fp;
gchar buf[250];
@@ -288,11 +288,11 @@ e_logger_get_logs (ELogger *logger,
g_string_append (str, tmp);
}
- func (str->str, data);
+ func (str->str, user_data);
g_string_free (str, TRUE);
} else
- func (tmp, data);
+ func (tmp, user_data);
}
fclose (fp);
diff --git a/e-util/e-logger.h b/e-util/e-logger.h
index f7dfd8017e..ce595d691c 100644
--- a/e-util/e-logger.h
+++ b/e-util/e-logger.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef __E_LOGGER_H__
-#define __E_LOGGER_H__
+#ifndef E_LOGGER_H
+#define E_LOGGER_H
#include <glib-object.h>
@@ -52,34 +52,32 @@ typedef struct _ELoggerPrivate ELoggerPrivate;
typedef void (*ELogFunction) (gchar *line, gpointer data);
-enum e_log_level_t {
+typedef enum {
E_LOG_ERROR,
- E_LOG_WARNINGS,
+ E_LOG_WARNING,
E_LOG_DEBUG
-};
+} ELogLevel;
-/* The object */
struct _ELogger {
GObject parent;
-
- struct _ELoggerPrivate *priv;
+ ELoggerPrivate *priv;
};
struct _ELoggerClass {
- GObjectClass popup_class;
+ GObjectClass parent_class;
};
GType e_logger_get_type (void);
-ELogger * e_logger_create (gchar *component);
-const gchar * e_logger_get_component (ELogger *logger);
+ELogger * e_logger_new (const gchar *name);
+const gchar * e_logger_get_name (ELogger *logger);
void e_logger_log (ELogger *logger,
- gint level,
+ ELogLevel level,
gchar *primary,
gchar *secondary);
void e_logger_get_logs (ELogger *logger,
ELogFunction func,
- gpointer data);
+ gpointer user_data);
G_END_DECLS
-#endif /* __E_LOGGER_H__ */
+#endif /* E_LOGGER_H */
diff --git a/e-util/e-marshal.list b/e-util/e-marshal.list
index 366602491b..b667ca4a84 100644
--- a/e-util/e-marshal.list
+++ b/e-util/e-marshal.list
@@ -66,3 +66,4 @@ NONE:STRING,STRING,STRING
NONE:STRING,STRING,UINT
OBJECT:OBJECT,DOUBLE,DOUBLE,BOOLEAN
POINTER:NONE
+STRING:NONE
diff --git a/e-util/e-non-intrusive-error-dialog.c b/e-util/e-non-intrusive-error-dialog.c
index 070c1e9bef..5fd98cacd2 100644
--- a/e-util/e-non-intrusive-error-dialog.c
+++ b/e-util/e-non-intrusive-error-dialog.c
@@ -305,4 +305,3 @@ eni_show_logger(ELogger *logger, GtkWidget *top,const char *error_timeout_path,
gtk_widget_show_all (window);
}
-
diff --git a/e-util/e-non-intrusive-error-dialog.h b/e-util/e-non-intrusive-error-dialog.h
index e801d47a52..159242c0fa 100644
--- a/e-util/e-non-intrusive-error-dialog.h
+++ b/e-util/e-non-intrusive-error-dialog.h
@@ -38,7 +38,7 @@ struct _log_data {
GdkPixbuf *pbuf;
} ldata [] = {
{ E_LOG_ERROR, N_("Error"), N_("Errors"), GTK_STOCK_DIALOG_ERROR },
- { E_LOG_WARNINGS, N_("Warning"), N_("Warnings and Errors"), GTK_STOCK_DIALOG_WARNING },
+ { E_LOG_WARNING, N_("Warning"), N_("Warnings and Errors"), GTK_STOCK_DIALOG_WARNING },
{ E_LOG_DEBUG, N_("Debug"), N_("Error, Warnings and Debug messages"), GTK_STOCK_DIALOG_INFO }
};
diff --git a/e-util/e-plugin-ui.c b/e-util/e-plugin-ui.c
index c192ece939..2528efd0fa 100644
--- a/e-util/e-plugin-ui.c
+++ b/e-util/e-plugin-ui.c
@@ -25,7 +25,6 @@
#define E_PLUGIN_UI_INIT_FUNC "e_plugin_ui_init"
#define E_PLUGIN_UI_HOOK_CLASS_ID "org.gnome.evolution.ui:1.0"
-#define E_PLUGIN_UI_MANAGER_ID_KEY "e-plugin-ui-manager-id"
struct _EPluginUIHookPrivate {
@@ -33,9 +32,11 @@ struct _EPluginUIHookPrivate {
*
* For example:
*
- * <ui-manager id="org.gnome.evolution.sample">
- * ... UI definition ...
- * </ui-manager>
+ * <hook class="org.gnome.evolution.ui:1.0">
+ * <ui-manager id="org.gnome.evolution.sample">
+ * ... UI definition ...
+ * </ui-manager>
+ * </hook>
*
* Results in:
*
@@ -49,195 +50,309 @@ struct _EPluginUIHookPrivate {
* optional.
*/
GHashTable *ui_definitions;
+
+ /* The registry is the heart of EPluginUI. It tracks GtkUIManager
+ * instances, GtkUIManager IDs, and UI merge IDs as a hash table of
+ * hash tables:
+ *
+ * GtkUIManager instance -> GtkUIManager ID -> UI Merge ID
+ *
+ * A GtkUIManager instance and ID form a unique key for looking up
+ * UI merge IDs. The reason both are needed is because the same
+ * GtkUIManager instance and be registered under multiple IDs.
+ *
+ * This is done primarily to support shell views, which share a
+ * common GtkUIManager instance for a particular shell window.
+ * Each shell view registers the same GtkUIManager instance under
+ * a unique ID:
+ *
+ * "org.gnome.evolution.mail" }
+ * "org.gnome.evolution.contacts" } aliases for a common
+ * "org.gnome.evolution.calendar" } GtkUIManager instance
+ * "org.gnome.evolution.memos" }
+ * "org.gnome.evolution.tasks" }
+ *
+ * Note: The shell window also registers the same GtkUIManager
+ * instance as "org.gnome.evolution.shell".
+ *
+ * This way, plugins that extend a shell view's UI will follow the
+ * merging and unmerging of the shell view automatically.
+ *
+ * The presence or absence of GtkUIManager IDs in the registry is
+ * significant. Presence of a (instance, ID) pair indicates that
+ * UI manager is active, absence indicates inactive. Furthermore,
+ * a non-zero merge ID for an active UI manager indicates the
+ * plugin is enabled. Zero indicates disabled.
+ *
+ * Here's a quick scenario to illustrate:
+ *
+ * Suppose we have a plugin that extends the mail shell view UI.
+ * Its EPlugin definition file has this section:
+ *
+ * <hook class="org.gnome.evolution.ui:1.0">
+ * <ui-manager id="org.gnome.evolution.mail">
+ * ... UI definition ...
+ * </ui-manager>
+ * </hook>
+ *
+ * The plugin is enabled and the active shell view is "mail".
+ * Let "ManagerA" denote the common GtkUIManager instance for
+ * this shell window. Here's what happens to the registry as
+ * the user performs various actions;
+ *
+ * - Initial State Merge ID
+ * V
+ * { "ManagerA", { "org.gnome.evolution.mail", 3 } }
+ *
+ * - User Disables the Plugin
+ *
+ * { "ManagerA", { "org.gnome.evolution.mail", 0 } }
+ *
+ * - User Enables the Plugin
+ *
+ * { "ManagerA", { "org.gnome.evolution.mail", 4 } }
+ *
+ * - User Switches to Calendar View
+ *
+ * { "ManagerA", { } }
+ *
+ * - User Disables the Plugin
+ *
+ * { "ManagerA", { } }
+ *
+ * - User Switches to Mail View
+ *
+ * { "ManagerA", { "org.gnome.evolution.mail", 0 } }
+ *
+ * - User Enables the Plugin
+ *
+ * { "ManagerA", { "org.gnome.evolution.mail", 5 } }
+ */
+ GHashTable *registry;
};
-/* The registry is a hash table of hash tables. It maps
- *
- * EPluginUIHook instance --> GtkUIManager instance --> UI merge id
- *
- * GtkUIManager instances are automatically removed when finalized.
- */
-static GHashTable *registry;
static gpointer parent_class;
static void
-plugin_ui_registry_remove (EPluginUIHook *hook,
- GtkUIManager *manager)
+plugin_ui_hook_unregister_manager (EPluginUIHook *hook,
+ GtkUIManager *manager)
{
- GHashTable *hash_table;
+ GHashTable *registry;
/* Note: Manager may already be finalized. */
-
- hash_table = g_hash_table_lookup (registry, hook);
- g_return_if_fail (hash_table != NULL);
-
- g_hash_table_remove (hash_table, manager);
- if (g_hash_table_size (hash_table) == 0)
- g_hash_table_remove (registry, hook);
+ registry = hook->priv->registry;
+ g_hash_table_remove (registry, manager);
}
static void
-plugin_ui_registry_insert (EPluginUIHook *hook,
- GtkUIManager *manager,
- guint merge_id)
+plugin_ui_hook_register_manager (EPluginUIHook *hook,
+ GtkUIManager *manager,
+ gpointer user_data)
{
+ EPlugin *plugin;
+ EPluginUIInitFunc func;
+ GHashTable *registry;
GHashTable *hash_table;
- hash_table = g_hash_table_lookup (registry, hook);
- if (hash_table == NULL) {
- hash_table = g_hash_table_new (g_direct_hash, g_direct_equal);
- g_hash_table_insert (registry, hook, hash_table);
- }
+ plugin = ((EPluginHook *) hook)->plugin;
+ func = e_plugin_get_symbol (plugin, E_PLUGIN_UI_INIT_FUNC);
+
+ /* Pass the manager and user_data to the plugin's e_plugin_ui_init()
+ * function (if it defined one). The plugin should install whatever
+ * GtkActions and GtkActionGroups are neccessary to implement the
+ * action names in its UI definition. */
+ if (func != NULL && !func (manager, user_data))
+ return;
g_object_weak_ref (
G_OBJECT (manager), (GWeakNotify)
- plugin_ui_registry_remove, hook);
+ plugin_ui_hook_unregister_manager, hook);
- g_hash_table_insert (hash_table, manager, GUINT_TO_POINTER (merge_id));
+ registry = hook->priv->registry;
+ hash_table = g_hash_table_lookup (registry, manager);
+
+ if (hash_table == NULL) {
+ hash_table = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
+ g_hash_table_insert (registry, manager, hash_table);
+ }
}
-/* Helper for plugin_ui_hook_merge_ui() */
-static void
-plugin_ui_hook_merge_foreach (GtkUIManager *manager,
- const gchar *ui_definition,
- GHashTable *hash_table)
+static guint
+plugin_ui_hook_merge_ui (EPluginUIHook *hook,
+ GtkUIManager *manager,
+ const gchar *id)
{
+ GHashTable *hash_table;
+ const gchar *ui_definition;
guint merge_id;
GError *error = NULL;
- /* Merge the UI definition into the manager. */
+ hash_table = hook->priv->ui_definitions;
+ ui_definition = g_hash_table_lookup (hash_table, id);
+ g_return_val_if_fail (ui_definition != NULL, 0);
+
merge_id = gtk_ui_manager_add_ui_from_string (
manager, ui_definition, -1, &error);
- gtk_ui_manager_ensure_update (manager);
+
if (error != NULL) {
g_warning ("%s", error->message);
g_error_free (error);
}
- /* Merge ID will be 0 on error, which is what we want. */
- g_hash_table_insert (hash_table, manager, GUINT_TO_POINTER (merge_id));
+ return merge_id;
}
static void
-plugin_ui_hook_merge_ui (EPluginUIHook *hook)
+plugin_ui_enable_manager (EPluginUIHook *hook,
+ GtkUIManager *manager,
+ const gchar *id)
{
- GHashTable *old_merge_ids;
- GHashTable *new_merge_ids;
- GHashTable *intermediate;
+ GHashTable *hash_table;
+ GHashTable *ui_definitions;
GList *keys;
- old_merge_ids = g_hash_table_lookup (registry, hook);
- if (old_merge_ids == NULL)
- return;
+ hash_table = hook->priv->registry;
+ hash_table = g_hash_table_lookup (hash_table, manager);
- /* The GtkUIManager instances and UI definitions live in separate
- * tables, so we need to build an intermediate table that we can
- * easily iterate over. */
- keys = g_hash_table_get_keys (old_merge_ids);
- intermediate = g_hash_table_new (g_direct_hash, g_direct_equal);
+ if (hash_table == NULL)
+ return;
- while (keys != NULL) {
- GtkUIManager *manager = keys->data;
- gchar *ui_definition;
+ if (id != NULL)
+ keys = g_list_prepend (NULL, (gpointer) id);
+ else
+ keys = g_hash_table_get_keys (hash_table);
- ui_definition = g_hash_table_lookup (
- hook->priv->ui_definitions,
- e_plugin_ui_get_manager_id (manager));
+ ui_definitions = hook->priv->ui_definitions;
- g_hash_table_insert (intermediate, manager, ui_definition);
+ while (keys != NULL) {
+ guint merge_id;
+ gpointer data;
+ id = keys->data;
keys = g_list_delete_link (keys, keys);
- }
- new_merge_ids = g_hash_table_new (g_direct_hash, g_direct_equal);
+ if (g_hash_table_lookup (ui_definitions, id) == NULL)
+ continue;
+
+ data = g_hash_table_lookup (hash_table, id);
+ merge_id = GPOINTER_TO_UINT (data);
- g_hash_table_foreach (
- intermediate, (GHFunc)
- plugin_ui_hook_merge_foreach, new_merge_ids);
+ if (merge_id > 0)
+ continue;
- g_hash_table_insert (registry, hook, new_merge_ids);
+ if (((EPluginHook *) hook)->plugin->enabled)
+ merge_id = plugin_ui_hook_merge_ui (hook, manager, id);
- g_hash_table_destroy (intermediate);
+ /* Merge ID will be 0 on error, which is what we want. */
+ data = GUINT_TO_POINTER (merge_id);
+ g_hash_table_insert (hash_table, g_strdup (id), data);
+ }
}
-/* Helper for plugin_ui_hook_unmerge_ui() */
static void
-plugin_ui_hook_unmerge_foreach (GtkUIManager *manager,
- gpointer value,
- GHashTable *hash_table)
+plugin_ui_disable_manager (EPluginUIHook *hook,
+ GtkUIManager *manager,
+ const gchar *id,
+ gboolean remove)
{
- guint merge_id;
+ GHashTable *hash_table;
+ GHashTable *ui_definitions;
+ GList *keys;
+
+ hash_table = hook->priv->registry;
+ hash_table = g_hash_table_lookup (hash_table, manager);
+
+ if (hash_table == NULL)
+ return;
+
+ if (id != NULL)
+ keys = g_list_prepend (NULL, (gpointer) id);
+ else
+ keys = g_hash_table_get_keys (hash_table);
+
+ ui_definitions = hook->priv->ui_definitions;
+
+ while (keys != NULL) {
+ guint merge_id;
+ gpointer data;
- merge_id = GPOINTER_TO_UINT (value);
- gtk_ui_manager_remove_ui (manager, merge_id);
+ id = keys->data;
+ keys = g_list_delete_link (keys, keys);
+
+ if (g_hash_table_lookup (ui_definitions, id) == NULL)
+ continue;
- g_hash_table_insert (hash_table, manager, GUINT_TO_POINTER (0));
+ data = g_hash_table_lookup (hash_table, id);
+ merge_id = GPOINTER_TO_UINT (data);
+
+ /* Merge ID could be 0 if the plugin is disabled. */
+ if (merge_id > 0)
+ gtk_ui_manager_remove_ui (manager, merge_id);
+
+ if (remove)
+ g_hash_table_remove (hash_table, id);
+ else
+ g_hash_table_insert (hash_table, g_strdup (id), NULL);
+ }
}
static void
-plugin_ui_hook_unmerge_ui (EPluginUIHook *hook)
+plugin_ui_enable_hook (EPluginUIHook *hook)
{
- GHashTable *old_merge_ids;
- GHashTable *new_merge_ids;
-
- old_merge_ids = g_hash_table_lookup (registry, hook);
- if (old_merge_ids == NULL)
- return;
+ GHashTable *hash_table;
+ GHashTableIter iter;
+ gpointer key;
- new_merge_ids = g_hash_table_new (g_direct_hash, g_direct_equal);
+ /* Enable all GtkUIManagers for this hook. */
- g_hash_table_foreach (
- old_merge_ids, (GHFunc)
- plugin_ui_hook_unmerge_foreach, new_merge_ids);
+ hash_table = hook->priv->registry;
+ g_hash_table_iter_init (&iter, hash_table);
- g_hash_table_insert (registry, hook, new_merge_ids);
+ while (g_hash_table_iter_next (&iter, &key, NULL)) {
+ GtkUIManager *manager = key;
+ plugin_ui_enable_manager (hook, manager, NULL);
+ }
}
static void
-plugin_ui_hook_register_manager (EPluginUIHook *hook,
- GtkUIManager *manager,
- const gchar *ui_definition,
- gpointer user_data)
+plugin_ui_disable_hook (EPluginUIHook *hook)
{
- EPlugin *plugin;
- EPluginUIInitFunc func;
- guint merge_id = 0;
+ GHashTable *hash_table;
+ GHashTableIter iter;
+ gpointer key;
- plugin = ((EPluginHook *) hook)->plugin;
- func = e_plugin_get_symbol (plugin, E_PLUGIN_UI_INIT_FUNC);
+ /* Disable all GtkUIManagers for this hook. */
- /* Pass the manager and user_data to the plugin's e_plugin_ui_init()
- * function (if it defined one). The plugin should install whatever
- * GtkActions and GtkActionGroups are neccessary to implement the
- * action names in its UI definition. */
- if (func != NULL && !func (manager, user_data))
- return;
+ hash_table = hook->priv->registry;
+ g_hash_table_iter_init (&iter, hash_table);
- if (plugin->enabled) {
- GError *error = NULL;
-
- /* Merge the UI definition into the manager. */
- merge_id = gtk_ui_manager_add_ui_from_string (
- manager, ui_definition, -1, &error);
- gtk_ui_manager_ensure_update (manager);
- if (error != NULL) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
+ while (g_hash_table_iter_next (&iter, &key, NULL)) {
+ GtkUIManager *manager = key;
+ plugin_ui_disable_manager (hook, manager, NULL, FALSE);
}
-
- /* Save merge ID's for later use. */
- plugin_ui_registry_insert (hook, manager, merge_id);
}
static void
plugin_ui_hook_finalize (GObject *object)
{
EPluginUIHookPrivate *priv;
+ GHashTableIter iter;
+ gpointer manager;
priv = E_PLUGIN_UI_HOOK_GET_PRIVATE (object);
+ /* Remove weak reference callbacks to GtkUIManagers. */
+ g_hash_table_iter_init (&iter, priv->registry);
+ while (g_hash_table_iter_next (&iter, &manager, NULL))
+ g_object_weak_unref (
+ G_OBJECT (manager), (GWeakNotify)
+ plugin_ui_hook_unregister_manager, object);
+
g_hash_table_destroy (priv->ui_definitions);
+ g_hash_table_destroy (priv->registry);
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (parent_class)->dispose (object);
@@ -298,9 +413,9 @@ plugin_ui_hook_enable (EPluginHook *hook,
gint state)
{
if (state)
- plugin_ui_hook_merge_ui (E_PLUGIN_UI_HOOK (hook));
+ plugin_ui_enable_hook (E_PLUGIN_UI_HOOK (hook));
else
- plugin_ui_hook_unmerge_ui (E_PLUGIN_UI_HOOK (hook));
+ plugin_ui_disable_hook (E_PLUGIN_UI_HOOK (hook));
}
static void
@@ -319,25 +434,24 @@ plugin_ui_hook_class_init (EPluginUIHookClass *class)
plugin_hook_class->id = E_PLUGIN_UI_HOOK_CLASS_ID;
plugin_hook_class->construct = plugin_ui_hook_construct;
plugin_hook_class->enable = plugin_ui_hook_enable;
-
- registry = g_hash_table_new_full (
- g_direct_hash, g_direct_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) g_hash_table_destroy);
}
static void
plugin_ui_hook_init (EPluginUIHook *hook)
{
GHashTable *ui_definitions;
+ GHashTable *registry;
ui_definitions = g_hash_table_new_full (
g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) g_free);
+ registry = g_hash_table_new (g_direct_hash, g_direct_equal);
+
hook->priv = E_PLUGIN_UI_HOOK_GET_PRIVATE (hook);
hook->priv->ui_definitions = ui_definitions;
+ hook->priv->registry = registry;
}
GType
@@ -367,17 +481,14 @@ e_plugin_ui_hook_get_type (void)
}
void
-e_plugin_ui_register_manager (const gchar *id,
- GtkUIManager *manager,
+e_plugin_ui_register_manager (GtkUIManager *manager,
+ const gchar *id,
gpointer user_data)
{
- const gchar *key = E_PLUGIN_UI_MANAGER_ID_KEY;
GSList *plugin_list;
- g_return_if_fail (id != NULL);
g_return_if_fail (GTK_IS_UI_MANAGER (manager));
-
- g_object_set_data (G_OBJECT (manager), key, (gpointer) id);
+ g_return_if_fail (id != NULL);
/* Loop over all installed plugins. */
plugin_list = e_plugin_list_plugins ();
@@ -385,36 +496,84 @@ e_plugin_ui_register_manager (const gchar *id,
EPlugin *plugin = plugin_list->data;
GSList *iter;
+ plugin_list = g_slist_next (plugin_list);
+
/* Look for hooks of type EPluginUIHook. */
for (iter = plugin->hooks; iter != NULL; iter = iter->next) {
EPluginUIHook *hook = iter->data;
- const gchar *ui_definition;
+ GHashTable *hash_table;
if (!E_IS_PLUGIN_UI_HOOK (hook))
continue;
+ hash_table = hook->priv->ui_definitions;
+
/* Check if the hook has a UI definition
* for the GtkUIManager being registered. */
- ui_definition = g_hash_table_lookup (
- hook->priv->ui_definitions, id);
- if (ui_definition == NULL)
+ if (g_hash_table_lookup (hash_table, id) == NULL)
continue;
/* Register the manager with the hook. */
plugin_ui_hook_register_manager (
- hook, manager, ui_definition, user_data);
+ hook, manager, user_data);
}
+ }
+}
+
+void
+e_plugin_ui_enable_manager (GtkUIManager *manager,
+ const gchar *id)
+{
+ GSList *plugin_list;
+
+ g_return_if_fail (GTK_IS_UI_MANAGER (manager));
+ g_return_if_fail (id != NULL);
+
+ /* Loop over all installed plugins. */
+ plugin_list = e_plugin_list_plugins ();
+ while (plugin_list != NULL) {
+ EPlugin *plugin = plugin_list->data;
+ GSList *iter;
plugin_list = g_slist_next (plugin_list);
+
+ /* Look for hooks of type EPluginUIHook. */
+ for (iter = plugin->hooks; iter != NULL; iter = iter->next) {
+ EPluginUIHook *hook = iter->data;
+
+ if (!E_IS_PLUGIN_UI_HOOK (hook))
+ continue;
+
+ plugin_ui_enable_manager (hook, manager, id);
+ }
}
}
-const gchar *
-e_plugin_ui_get_manager_id (GtkUIManager *manager)
+void
+e_plugin_ui_disable_manager (GtkUIManager *manager,
+ const gchar *id)
{
- const gchar *key = E_PLUGIN_UI_MANAGER_ID_KEY;
+ GSList *plugin_list;
+
+ g_return_if_fail (GTK_IS_UI_MANAGER (manager));
+ g_return_if_fail (id != NULL);
+
+ /* Loop over all installed plugins. */
+ plugin_list = e_plugin_list_plugins ();
+ while (plugin_list != NULL) {
+ EPlugin *plugin = plugin_list->data;
+ GSList *iter;
- g_return_val_if_fail (GTK_IS_UI_MANAGER (manager), NULL);
+ plugin_list = g_slist_next (plugin_list);
+
+ /* Look for hooks of type EPluginUIHook. */
+ for (iter = plugin->hooks; iter != NULL; iter = iter->next) {
+ EPluginUIHook *hook = iter->data;
- return g_object_get_data (G_OBJECT (manager), key);
+ if (!E_IS_PLUGIN_UI_HOOK (hook))
+ continue;
+
+ plugin_ui_disable_manager (hook, manager, id, TRUE);
+ }
+ }
}
diff --git a/e-util/e-plugin-ui.h b/e-util/e-plugin-ui.h
index 00e6ed5fcf..d1a380d91e 100644
--- a/e-util/e-plugin-ui.h
+++ b/e-util/e-plugin-ui.h
@@ -62,10 +62,13 @@ typedef gboolean (*EPluginUIInitFunc) (GtkUIManager *manager,
GType e_plugin_ui_hook_get_type (void);
-void e_plugin_ui_register_manager (const gchar *id,
- GtkUIManager *manager,
+void e_plugin_ui_register_manager (GtkUIManager *manager,
+ const gchar *id,
gpointer user_data);
-const gchar * e_plugin_ui_get_manager_id (GtkUIManager *manager);
+void e_plugin_ui_enable_manager (GtkUIManager *manager,
+ const gchar *id);
+void e_plugin_ui_disable_manager (GtkUIManager *manager,
+ const gchar *id);
G_END_DECLS
diff --git a/e-util/e-signature-utils.c b/e-util/e-signature-utils.c
new file mode 100644
index 0000000000..0114ce6e06
--- /dev/null
+++ b/e-util/e-signature-utils.c
@@ -0,0 +1,347 @@
+/*
+ * e-signature-utils.c
+ *
+ * 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 <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#include "e-signature-utils.h"
+
+#include <errno.h>
+#include <glib/gstdio.h>
+#include <gconf/gconf-client.h>
+#include <camel/camel-stream.h>
+#include <camel/camel-stream-fs.h>
+#include <camel/camel-stream-mem.h>
+#include <camel/camel-stream-filter.h>
+#include <camel/camel-mime-filter-charset.h>
+#include <camel/camel-mime-filter-tohtml.h>
+
+#ifndef G_OS_WIN32
+#include <sys/wait.h>
+#endif
+
+#include "e-util/e-util.h"
+
+static ESignatureList *global_signature_list;
+
+ESignatureList *
+e_get_signature_list (void)
+{
+ if (G_UNLIKELY (global_signature_list == NULL)) {
+ GConfClient *client;
+
+ client = gconf_client_get_default ();
+ global_signature_list = e_signature_list_new (client);
+ g_object_unref (client);
+ }
+
+ g_return_val_if_fail (global_signature_list != NULL, NULL);
+
+ return global_signature_list;
+}
+
+ESignature *
+e_get_signature_by_name (const gchar *name)
+{
+ ESignatureList *signature_list;
+ const ESignature *signature;
+ e_signature_find_t find;
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+ find = E_SIGNATURE_FIND_NAME;
+ signature_list = e_get_signature_list ();
+ signature = e_signature_list_find (signature_list, find, name);
+
+ /* XXX ESignatureList misuses const. */
+ return (ESignature *) signature;
+}
+
+ESignature *
+e_get_signature_by_uid (const gchar *uid)
+{
+ ESignatureList *signature_list;
+ const ESignature *signature;
+ e_signature_find_t find;
+
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ find = E_SIGNATURE_FIND_UID;
+ signature_list = e_get_signature_list ();
+ signature = e_signature_list_find (signature_list, find, uid);
+
+ /* XXX ESignatureList misuses const. */
+ return (ESignature *) signature;
+}
+
+gchar *
+e_create_signature_file (GError **error)
+{
+ const gchar *data_dir;
+ gchar basename[32];
+ gchar *filename;
+ gchar *pathname;
+ gint32 ii;
+
+ data_dir = e_get_user_data_dir ();
+ pathname = g_build_filename (data_dir, "signatures", NULL);
+ filename = NULL;
+
+ if (g_mkdir_with_parents (pathname, 0700) < 0) {
+ g_set_error (
+ error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "%s: %s", pathname, g_strerror (errno));
+ g_free (pathname);
+ return NULL;
+ }
+
+ for (ii = 0; ii < G_MAXINT32; ii++) {
+
+ g_snprintf (
+ basename, sizeof (basename),
+ "signature-%" G_GINT32_FORMAT, ii);
+
+ g_free (filename);
+ filename = g_build_filename (pathname, basename, NULL);
+
+ if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
+ gint fd;
+
+ fd = g_creat (filename, 0600);
+ if (fd >= 0) {
+ close (fd);
+ break;
+ }
+
+ /* If we failed once we're probably going
+ * to continue failing, so just give up. */
+ g_set_error (
+ error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "%s: %s", filename, g_strerror (errno));
+ g_free (filename);
+ filename = NULL;
+ break;
+ }
+ }
+
+ /* If there are actually G_MAXINT32 signature files, the
+ * most recent signature file we be overwritten. Sorry. */
+
+ return filename;
+}
+
+gchar *
+e_read_signature_file (ESignature *signature,
+ gboolean convert_to_html,
+ GError **error)
+{
+ CamelStream *input_stream;
+ CamelStream *output_stream;
+ GByteArray *buffer;
+ gchar *content;
+ gsize length;
+ gint fd;
+
+ g_return_val_if_fail (E_IS_SIGNATURE (signature), NULL);
+
+ fd = g_open (signature->filename, O_RDONLY, 0);
+ if (fd < 0) {
+ g_set_error (
+ error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "%s: %s", signature->filename,
+ g_strerror (errno));
+ return NULL;
+ }
+
+ input_stream = camel_stream_fs_new_with_fd (fd);
+
+ if (!signature->html && convert_to_html) {
+ CamelStreamFilter *filtered_stream;
+ CamelMimeFilter *filter;
+ gint32 flags;
+
+ filtered_stream =
+ camel_stream_filter_new_with_stream (input_stream);
+ camel_object_unref (input_stream);
+
+ flags =
+ CAMEL_MIME_FILTER_TOHTML_PRESERVE_8BIT |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES;
+ filter = camel_mime_filter_tohtml_new (flags, 0);
+ camel_stream_filter_add (filtered_stream, filter);
+ camel_object_unref (filter);
+
+ input_stream = (CamelStream *) filtered_stream;
+ }
+
+ buffer = g_byte_array_new ();
+ output_stream = camel_stream_mem_new ();
+ camel_stream_mem_set_byte_array (
+ CAMEL_STREAM_MEM (output_stream), buffer);
+ camel_stream_write_to_stream (input_stream, output_stream);
+ camel_object_unref (output_stream);
+ camel_object_unref (input_stream);
+
+ /* Make sure the buffer is nul-terminated. */
+ length = (gsize) buffer->len;
+ g_byte_array_append (buffer, (guint8 *) "", 1);
+ content = (gchar *) g_byte_array_free (buffer, FALSE);
+
+ /* Signatures are saved as UTF-8, but we still need to check that
+ * the signature is valid UTF-8 because the user may be opening
+ * a signature file that is in his/her locale character set. If
+ * it's not in UTF-8 then try converting from the current locale. */
+ if (!g_utf8_validate (content, length, NULL)) {
+ gchar *utf8;
+
+ utf8 = g_locale_to_utf8 (content, length, NULL, NULL, error);
+ g_free (content);
+ content = utf8;
+ }
+
+ return content;
+}
+
+gchar *
+e_run_signature_script (const gchar *filename)
+{
+ /* FIXME Make this cross-platform, prefer GLib functions over
+ * POSIX, and report errors via GError instead of dumping
+ * messages to the terminal where users won't see them. */
+
+#ifndef G_OS_WIN32
+ gint in_fds[2];
+ pid_t pid;
+
+ g_return_val_if_fail (filename != NULL, NULL);
+
+ if (pipe (in_fds) == -1) {
+ g_warning (
+ "Failed to create pipe to '%s': %s",
+ filename, g_strerror (errno));
+ return NULL;
+ }
+
+ pid = fork ();
+
+ /* Child Process */
+ if (pid == 0) {
+ gint maxfd, ii;
+
+ close (in_fds[0]);
+ if (dup2 (in_fds[1], STDOUT_FILENO) < 0)
+ _exit (255);
+ close (in_fds[1]);
+
+ setsid ();
+
+ maxfd = sysconf (_SC_OPEN_MAX);
+ for (ii = 3; ii < maxfd; ii++) {
+ if (ii == STDIN_FILENO)
+ continue;
+ if (ii == STDOUT_FILENO)
+ continue;
+ if (ii == STDERR_FILENO)
+ continue;
+ fcntl (ii, F_SETFD, FD_CLOEXEC);
+ }
+
+ execlp ("/bin/sh", "/bin/sh", "-c", filename, NULL);
+
+ g_warning (
+ "Could not execute '%s': %s",
+ filename, g_strerror (errno));
+
+ _exit (255);
+
+ /* Parent Process */
+ } else if (pid > 0) {
+ CamelStream *output_stream;
+ CamelStream *input_stream;
+ GByteArray *buffer;
+ gchar *content;
+ gsize length;
+ gint result;
+ gint status;
+
+ close (in_fds[1]);
+
+ buffer = g_byte_array_new ();
+ output_stream = camel_stream_mem_new ();
+ camel_stream_mem_set_byte_array (
+ CAMEL_STREAM_MEM (output_stream), buffer);
+
+ input_stream = camel_stream_fs_new_with_fd (in_fds[0]);
+ camel_stream_write_to_stream (input_stream, output_stream);
+ camel_object_unref (input_stream);
+
+ camel_object_unref (output_stream);
+
+ /* Make sure the buffer is nul-terminated. */
+ length = (gsize) buffer->len;
+ g_byte_array_append (buffer, (guchar *) "", 1);
+ content = (gchar *) g_byte_array_free (buffer, FALSE);
+
+ /* Signature scripts are supposed to generate UTF-8 content,
+ * but because users are known to never read the manual, we
+ * try to do our best if the content isn't valid UTF-8 by
+ * assuming that the content is in the user's locale
+ * character set. */
+ if (!g_utf8_validate (content, length, NULL)) {
+ gchar *utf8;
+
+ /* XXX Should pass a GError here. */
+ utf8 = g_locale_to_utf8 (
+ content, length, NULL, NULL, NULL);
+ g_free (content);
+ content = utf8;
+ }
+
+ /* Wait for the script process to terminate. */
+ result = waitpid (pid, &status, 0);
+
+ if (result == -1 && errno == EINTR) {
+ /* Child process is hanging... */
+ kill (pid, SIGTERM);
+ sleep (1);
+ result = waitpid (pid, &status, WNOHANG);
+ if (result == 0) {
+ /* ...still hanging, set phasers to KILL. */
+ kill (pid, SIGKILL);
+ sleep (1);
+ result = waitpid (pid, &status, WNOHANG);
+ }
+ }
+
+ return content;
+
+ /* Forking Failed */
+ } else {
+ g_warning (
+ "Failed to create child process '%s': %s",
+ filename, g_strerror (errno));
+ close (in_fds[0]);
+ close (in_fds[1]);
+ }
+#endif
+
+ return NULL;
+}
diff --git a/e-util/e-gui-utils.h b/e-util/e-signature-utils.h
index d7552d5379..41472f45d0 100644
--- a/e-util/e-gui-utils.h
+++ b/e-util/e-signature-utils.h
@@ -1,4 +1,6 @@
/*
+ * e-signature-utils.h
+ *
* 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
@@ -12,18 +14,27 @@
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
- *
- * Authors:
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
*/
-#ifndef E_GUI_UTILS_H
-#define E_GUI_UTILS_H
+#ifndef E_SIGNATURE_UTILS_H
+#define E_SIGNATURE_UTILS_H
#include <gtk/gtk.h>
+#include <e-util/e-signature.h>
+#include <e-util/e-signature-list.h>
+
+G_BEGIN_DECLS
+
+ESignatureList *e_get_signature_list (void);
+ESignature * e_get_signature_by_name (const gchar *name);
+ESignature * e_get_signature_by_uid (const gchar *uid);
+gchar * e_create_signature_file (GError **error);
+gchar * e_read_signature_file (ESignature *signature,
+ gboolean convert_to_html,
+ GError **error);
+gchar * e_run_signature_script (const gchar *filename);
-GdkPixbuf *e_icon_for_mime_type (const char *mime_type, int size);
+G_END_DECLS
-#endif /* E_GUI_UTILS_H */
+#endif /* E_SIGNATURE_UTILS_H */
diff --git a/e-util/e-util-labels.c b/e-util/e-util-labels.c
deleted file mode 100644
index 85984da59c..0000000000
--- a/e-util/e-util-labels.c
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-
-#include <stdio.h>
-#include <string.h>
-
-#include <gconf/gconf-client.h>
-
-#include <camel/camel-utf8.h>
-
-#include "e-util.h"
-#include "e-util-labels.h"
-#include "e-dialog-utils.h"
-#include "filter/filter-option.h"
-
-/* Note, the first element of each EUtilLabel must NOT be translated */
-EUtilLabel label_defaults[LABEL_DEFAULTS_NUM] = {
- { "$Labelimportant", N_("I_mportant"), "#EF2929" }, /* red */
- { "$Labelwork", N_("_Work"), "#F57900" }, /* orange */
- { "$Labelpersonal", N_("_Personal"), "#4E9A06" }, /* green */
- { "$Labeltodo", N_("_To Do"), "#3465A4" }, /* blue */
- { "$Labellater", N_("_Later"), "#75507B" } /* purple */
-};
-
-/**
- * e_util_labels_parse
- * Reads the setup from client and parses it to list of EUtilLabel objects.
- *
- * @param client The config client to be used for reading setup.
- * Can be NULL, in that case it will use the default client.
- * @return Newly allocated list of labels, should be freed with @ref e_util_labels_free.
- **/
-GSList *
-e_util_labels_parse (GConfClient *client)
-{
- GSList *labels, *list, *head;
- EUtilLabel *label;
- char *buf;
- int num = 0;
- gboolean unref_client = client == NULL;
-
- labels = NULL;
-
- if (!client)
- client = gconf_client_get_default ();
-
- head = gconf_client_get_list (client, E_UTIL_LABELS_GCONF_KEY, GCONF_VALUE_STRING, NULL);
-
- for (list = head; list; list = list->next) {
- char *color, *name, *tag;
- name = buf = list->data;
- color = strrchr (buf, ':');
- if (color == NULL) {
- g_free (buf);
- continue;
- }
-
- *color++ = '\0';
- tag = strchr (color, '|');
- if (tag)
- *tag++ = '\0';
-
- label = g_new (EUtilLabel, 1);
-
- /* Needed for Backward Compatibility */
- if (num < LABEL_DEFAULTS_NUM) {
- label->name = g_strdup ((buf && *buf) ? buf : _(label_defaults[num].name));
- label->tag = g_strdup (label_defaults[num].tag);
- num++;
- } else if (!tag) {
- g_free (buf);
- g_free (label);
- continue;
- } else {
- label->name = g_strdup (name);
- label->tag = g_strdup (tag);
- }
-
- label->colour = g_strdup (color);
- labels = g_slist_prepend (labels, label);
-
- g_free (buf);
- }
-
- if (head)
- g_slist_free (head);
-
- while (num < LABEL_DEFAULTS_NUM) {
- /* complete the list with defaults */
- label = g_new (EUtilLabel, 1);
- label->tag = g_strdup (label_defaults[num].tag);
- label->name = g_strdup (_(label_defaults[num].name));
- label->colour = g_strdup (label_defaults[num].colour);
-
- labels = g_slist_prepend (labels, label);
-
- num++;
- }
-
- if (unref_client)
- g_object_unref (client);
-
- return g_slist_reverse (labels);
-}
-
-static void
-free_label_struct (EUtilLabel *label)
-{
- if (!label)
- return;
-
- g_free (label->tag);
- g_free (label->name);
- g_free (label->colour);
- g_free (label);
-}
-
-/**
- * e_util_labels_free
- * Frees memory previously allocated by @ref e_util_labels_parse
- *
- * @param labels Labels list, previously allocated by @ref e_util_labels_parse
- * It is safe to call with NULL.
- **/
-void
-e_util_labels_free (GSList *labels)
-{
- if (!labels)
- return;
-
- g_slist_foreach (labels, (GFunc)free_label_struct, NULL);
- g_slist_free (labels);
-}
-
-/* stores the actual cache to gconf */
-static gboolean
-flush_labels_cache (GSList *labels, gboolean free_labels)
-{
- GSList *l, *text_labels;
- GConfClient *client;
-
- if (!labels)
- return FALSE;
-
- text_labels = NULL;
-
- for (l = labels; l; l = l->next) {
- EUtilLabel *label = l->data;
-
- if (label && label->tag && label->name && label->colour)
- text_labels = g_slist_prepend (text_labels, g_strdup_printf ("%s:%s|%s", label->name, label->colour, label->tag));
- }
-
- if (!text_labels) {
- if (free_labels)
- e_util_labels_free (labels);
-
- return FALSE;
- }
-
- text_labels = g_slist_reverse (text_labels);
-
- client = gconf_client_get_default ();
- gconf_client_set_list (client, E_UTIL_LABELS_GCONF_KEY, GCONF_VALUE_STRING, text_labels, NULL);
- g_object_unref (client);
-
- g_slist_foreach (text_labels, (GFunc)g_free, NULL);
- g_slist_free (text_labels);
-
- if (free_labels)
- e_util_labels_free (labels);
-
- /* not true if gconf failed to write; who cares */
- return TRUE;
-}
-
-/**
- * find_label
- *
- * Looks for label in labels cache by tag and returns actual pointer to cache.
- * @param labels The cache of labels; comes from @ref e_util_labels_parse
- * @param tag Tag of label you are looking for.
- * @return Pointer to cache data if label with such tag exists or NULL. Do not free it!
- **/
-static EUtilLabel *
-find_label (GSList *labels, const char *tag)
-{
- GSList *l;
-
- g_return_val_if_fail (tag != NULL, NULL);
-
- for (l = labels; l; l = l->next) {
- EUtilLabel *label = l->data;
-
- if (label && label->tag && !strcmp (tag, label->tag))
- return label;
- }
-
- return NULL;
-}
-
-
-static char *
-tag_from_name (const char *name)
-{
- /* this does thunderbird, just do not ask */
- char *s1, *s2, *p;
- const char *bads = " ()/{%*<>\\\"";
-
- if (!name || !*name)
- return NULL;
-
- s1 = g_strdup (name);
- for (p = s1; p && *p; p++) {
- if (strchr (bads, *p))
- *p = '_';
- }
-
- s2 = camel_utf8_utf7 (s1);
- g_free (s1);
-
- s1 = g_ascii_strdown (s2, -1);
- g_free (s2);
-
- return s1;
-}
-
-/**
- * e_util_labels_add
- * Creates new label at the end of actual list of labels.
- *
- * @param name User readable name of this label. Should not be NULL.
- * @param color Color assigned to this label. Should not be NULL.
- * @return If succeeded then new label tag, NULL otherwise.
- * Returned pointer should be freed with g_free.
- * It will return NULL when the tag will be same as already existed.
- * Tag name is generated in similar way as in Thunderbird.
- **/
-char *
-e_util_labels_add (const char *name, const GdkColor *color)
-{
- EUtilLabel *label;
- GSList *labels;
- char *tag;
-
- g_return_val_if_fail (name != NULL, NULL);
- g_return_val_if_fail (color != NULL, NULL);
-
- labels = e_util_labels_parse (NULL);
- tag = tag_from_name (name);
-
- if (!tag || find_label (labels, tag) != NULL) {
- g_free (tag);
- e_util_labels_free (labels);
- return NULL;
- }
-
- label = g_new0 (EUtilLabel, 1);
- label->tag = g_strdup (tag);
- label->name = g_strdup (name);
- label->colour = gdk_color_to_string (color);
-
- labels = g_slist_append (labels, label);
-
- flush_labels_cache (labels, TRUE);
-
- return tag;
-}
-
-/**
- * e_util_labels_add_with_dlg
- * This will open a dialog to add or edit label.
- *
- * @param parent Parent widget for the dialog.
- * @param tag A tag for existing label to edit or NULL to add new label.
- * @return Tag for newly added label or NULL, if something failed.
- * Returned value should be freed with g_free.
- **/
-char *
-e_util_labels_add_with_dlg (GtkWindow *parent, const char *tag)
-{
- GtkWidget *table, *dialog, *l, *e, *c;
- const char *name;
- GdkColor color;
- gboolean is_edit = FALSE;
- char *new_tag = NULL;
- GSList *labels;
-
- table = gtk_table_new (2, 2, FALSE);
-
- labels = e_util_labels_parse (NULL);
- name = tag ? e_util_labels_get_name (labels, tag) : NULL;
-
- l = gtk_label_new_with_mnemonic (_("Label _Name:"));
- e = gtk_entry_new ();
- c = gtk_color_button_new ();
-
- if (!tag || !e_util_labels_get_color (labels, tag, &color))
- memset (&color, 0xCD, sizeof (GdkColor));
- else
- is_edit = TRUE;
-
- if (name)
- gtk_entry_set_text (GTK_ENTRY (e), name);
-
- gtk_entry_set_activates_default (GTK_ENTRY (e), TRUE);
- gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
- gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.0);
- gtk_color_button_set_color (GTK_COLOR_BUTTON (c), &color);
-
- gtk_table_attach (GTK_TABLE (table), l, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
- gtk_table_attach (GTK_TABLE (table), e, 0, 1, 1, 2, 0, 0, 0, 0);
- gtk_table_attach (GTK_TABLE (table), c, 1, 2, 1, 2, 0, 0, 0, 0);
- gtk_container_set_border_width (GTK_CONTAINER (table), 10);
- gtk_widget_show_all (table);
-
- dialog = gtk_dialog_new_with_buttons (is_edit ? _("Edit Label") : _("Add Label"),
- parent,
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
- GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
- NULL);
-
- gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, TRUE, TRUE, 0);
-
- while (!new_tag) {
- const char *error = NULL;
-
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
- name = gtk_entry_get_text (GTK_ENTRY (e));
- gtk_color_button_get_color (GTK_COLOR_BUTTON (c), &color);
-
- if (!name || !*name)
- error = _("Label name cannot be empty.");
- else if (is_edit) {
- e_util_labels_set_data (tag, name, &color);
- break;
- } else if (!(new_tag = e_util_labels_add (name, &color)))
- error = _("A label having the same tag already exists on the server. Please rename your label.");
- else
- break;
- } else
- break;
-
- if (error)
- e_notice (parent, GTK_MESSAGE_ERROR, error);
- }
-
- gtk_widget_destroy (dialog);
- e_util_labels_free (labels);
-
- return new_tag;
-}
-
-/**
- * e_util_labels_remove
- *
- * @param tag Tag of the label to remove.
- * @return Whether was removed.
- **/
-gboolean
-e_util_labels_remove (const char *tag)
-{
- EUtilLabel *label;
- GSList *labels;
-
- g_return_val_if_fail (tag != NULL, FALSE);
-
- labels = e_util_labels_parse (NULL);
- label = find_label (labels, tag);
-
- if (!label) {
- e_util_labels_free (labels);
- return FALSE;
- }
-
- labels = g_slist_remove (labels, label);
-
- free_label_struct (label);
-
- return flush_labels_cache (labels, TRUE);
-}
-
-/**
- * e_util_labels_set_data
- *
- * @param tag Tag of the label of our interest.
- * @param name New name for the label.
- * @param color New color for the label.
- * @return Whether successfully saved.
- **/
-gboolean
-e_util_labels_set_data (const char *tag, const char *name, const GdkColor *color)
-{
- EUtilLabel *label;
- GSList *labels;
-
- g_return_val_if_fail (tag != NULL, FALSE);
- g_return_val_if_fail (name != NULL, FALSE);
- g_return_val_if_fail (color != NULL, FALSE);
-
- labels = e_util_labels_parse (NULL);
- label = find_label (labels, tag);
-
- if (!label) {
- e_util_labels_free (labels);
- return FALSE;
- }
-
- g_free (label->name);
- label->name = g_strdup (name);
-
- g_free (label->colour);
- label->colour = gdk_color_to_string (color);
-
- return flush_labels_cache (labels, TRUE);
-}
-
-/**
- * e_util_labels_is_system
- *
- * @return Whether the tag is one of default/system labels or not.
- **/
-gboolean
-e_util_labels_is_system (const char *tag)
-{
- int i;
-
- if (!tag)
- return FALSE;
-
- for (i = 0; i < LABEL_DEFAULTS_NUM; i++) {
- if (strcmp (tag, label_defaults[i].tag) == 0)
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- * e_util_labels_get_new_tag
- *
- * @param old_tag Tag of the label from old version of Evolution.
- * @return New tag name equivalent with the old tag, or NULL if no such name existed before.
- **/
-const char *
-e_util_labels_get_new_tag (const char *old_tag)
-{
- int i;
-
- if (!old_tag)
- return NULL;
-
- for (i = 0; i < LABEL_DEFAULTS_NUM; i++) {
- /* default labels have same name as those old, only with prefix "$Label" */
- if (!strcmp (old_tag, label_defaults[i].tag + 6))
- return label_defaults[i].tag;
- }
-
- return NULL;
-}
-
-/**
- * e_util_labels_get_name
- *
- * @param labels Cache of labels from call of @ref e_util_labels_parse.
- * The returned pointer will be taken from this list, so it's alive as long as the list.
- * @param tag Tag of the label of our interest.
- * @return Name of the label with that tag or NULL, if no such label exists.
- **/
-const char *
-e_util_labels_get_name (GSList *labels, const char *tag)
-{
- EUtilLabel *label;
-
- g_return_val_if_fail (tag != NULL, NULL);
-
- label = find_label (labels, tag);
- if (!label)
- return NULL;
-
- return label->name;
-}
-
-/**
- * e_util_labels_get_color
- *
- * @param labels Cache of labels from call of @ref e_util_labels_parse.
- * @param tag Tag of the label of our interest.
- * @param color [out] Actual color of the label with that tag, or unchanged if failed.
- * @return Whether found such label and color has been set.
- **/
-gboolean
-e_util_labels_get_color (GSList *labels, const char *tag, GdkColor *color)
-{
- EUtilLabel *label;
-
- g_return_val_if_fail (tag != NULL, FALSE);
- g_return_val_if_fail (color != NULL, FALSE);
-
- label = find_label (labels, tag);
- if (!label)
- return FALSE;
-
- return gdk_color_parse (label->colour, color);
-}
-
-/**
- * e_util_labels_get_color_str
- *
- * @param labels Cache of labels from call of @ref e_util_labels_parse.
- * The returned pointer will be taken from this list, so it's alive as long as the list.
- * @param tag Tag of the label of our interest.
- * @return String representation of that label, or NULL, is no such label exists.
- **/
-const char *
-e_util_labels_get_color_str (GSList *labels, const char *tag)
-{
- EUtilLabel *label;
-
- g_return_val_if_fail (tag != NULL, FALSE);
-
- label = find_label (labels, tag);
- if (!label)
- return FALSE;
-
- return label->colour;
-}
-
-/**
- * e_util_labels_get_filter_options:
- * Returns list of newly allocated struct _filter_option-s, to be used in filters.
- **/
-GSList *
-e_util_labels_get_filter_options (void)
-{
- GSList *known = e_util_labels_parse (NULL), *l;
- GSList *res = NULL;
-
- for (l = known; l; l = l->next) {
- EUtilLabel *label = l->data;
- const char *tag;
- struct _filter_option *fo;
-
- if (!label)
- continue;
-
- tag = label->tag;
-
- if (tag && strncmp (tag, "$Label", 6) == 0)
- tag += 6;
-
- fo = g_new0 (struct _filter_option, 1);
- fo->title = e_str_without_underscores (label->name);
- fo->value = g_strdup (tag);
-
- res = g_slist_prepend (res, fo);
- }
-
- e_util_labels_free (known);
-
- return g_slist_reverse (res);
-}
diff --git a/e-util/e-util-labels.h b/e-util/e-util-labels.h
deleted file mode 100644
index 26520ff226..0000000000
--- a/e-util/e-util-labels.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_UTIL_LABELS_H
-#define _E_UTIL_LABELS_H
-
-#include <gtk/gtk.h>
-
-struct _GtkWindow;
-struct _GConfClient;
-
-typedef struct {
- char *tag;
- char *name;
- char *colour;
-} EUtilLabel;
-
-#define E_UTIL_LABELS_GCONF_KEY "/apps/evolution/mail/labels"
-
-#define LABEL_DEFAULTS_NUM 5
-extern EUtilLabel label_defaults[LABEL_DEFAULTS_NUM];
-
-GSList * e_util_labels_parse (struct _GConfClient *client);
-void e_util_labels_free (GSList *labels);
-
-char * e_util_labels_add (const char *name, const GdkColor *color);
-char * e_util_labels_add_with_dlg (struct _GtkWindow *parent, const char *tag);
-gboolean e_util_labels_remove (const char *tag);
-gboolean e_util_labels_set_data (const char *tag, const char *name, const GdkColor *color);
-
-gboolean e_util_labels_is_system (const char *tag);
-const char *e_util_labels_get_new_tag (const char *old_tag);
-
-const char *e_util_labels_get_name (GSList *labels, const char *tag);
-gboolean e_util_labels_get_color (GSList *labels, const char *tag, GdkColor *color);
-const char *e_util_labels_get_color_str (GSList *labels, const char *tag);
-
-GSList * e_util_labels_get_filter_options (void);
-
-#endif /* _E_UTIL_LABELS_H */
diff --git a/e-util/e-util.c b/e-util/e-util.c
index 0b28404c82..071f5e58b8 100644
--- a/e-util/e-util.c
+++ b/e-util/e-util.c
@@ -186,6 +186,183 @@ exit:
}
/**
+ * 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_definition:
+ * @ui_manager: a #GtkUIManager
+ * @basename: basename of the UI definition file
+ *
+ * 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.
+ *
+ * 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_definition (GtkUIManager *ui_manager,
+ const gchar *basename)
+{
+ gchar *filename;
+ guint merge_id;
+ GError *error = NULL;
+
+ 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);
+ merge_id = gtk_ui_manager_add_ui_from_file (
+ ui_manager, filename, &error);
+ g_free (filename);
+
+ if (error != NULL) {
+ g_error ("%s: %s", basename, error->message);
+ g_assert_not_reached ();
+ }
+
+ return merge_id;
+}
+
+/**
+ * e_action_compare_by_label:
+ * @action1: a #GtkAction
+ * @action2: a #GtkAction
+ *
+ * Compares the labels for @action1 and @action2 using g_utf8_collate().
+ *
+ * Returns: &lt; 0 if @action1 compares before @action2, 0 if they
+ * compare equal, &gt; 0 if @action1 compares after @action2
+ **/
+gint
+e_action_compare_by_label (GtkAction *action1,
+ GtkAction *action2)
+{
+ gchar *label1;
+ gchar *label2;
+ gint result;
+
+ /* XXX This is horribly inefficient but will generally only be
+ * used on short lists of actions during UI construction. */
+
+ if (action1 == action2)
+ return 0;
+
+ g_object_get (action1, "label", &label1, NULL);
+ g_object_get (action2, "label", &label2, NULL);
+
+ result = g_utf8_collate (label1, label2);
+
+ g_free (label1);
+ g_free (label2);
+
+ return result;
+}
+
+/**
+ * e_action_group_remove_all_actions:
+ * @action_group: a #GtkActionGroup
+ *
+ * Removes all actions from the action group.
+ **/
+void
+e_action_group_remove_all_actions (GtkActionGroup *action_group)
+{
+ GList *list, *iter;
+
+ /* XXX I've proposed this function for inclusion in GTK+.
+ * GtkActionGroup stores actions in an internal hash
+ * table and can do this more efficiently by calling
+ * g_hash_table_remove_all().
+ *
+ * http://bugzilla.gnome.org/show_bug.cgi?id=550485 */
+
+ g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
+
+ list = gtk_action_group_list_actions (action_group);
+ for (iter = list; iter != NULL; iter = iter->next)
+ gtk_action_group_remove_action (action_group, iter->data);
+ g_list_free (list);
+}
+
+/**
* e_str_without_underscores:
* @s: the string to strip underscores from.
*
@@ -335,6 +512,30 @@ e_write_file_uri (const gchar *filename, const gchar *data)
return res;
}
+/**
+ * e_color_to_value:
+ * color: a #GdkColor
+ *
+ * Converts a #GdkColor to a 24-bit RGB color value.
+ *
+ * Returns: a 24-bit color value
+ **/
+guint32
+e_color_to_value (GdkColor *color)
+{
+ guint16 red;
+ guint16 green;
+ guint16 blue;
+
+ g_return_val_if_fail (color != NULL, 0);
+
+ red = color->red >> 8;
+ green = color->green >> 8;
+ blue = color->blue >> 8;
+
+ return (guint32) (((red << 16) | (green << 8) | blue) & 0xffffff);
+}
+
static gint
epow10 (gint number)
{
@@ -1301,23 +1502,32 @@ e_util_read_file (const char *filename, gboolean filename_is_uri, char **buffer,
return res;
}
-GSList *
-e_util_get_category_filter_options (void)
+static gpointer
+e_camel_object_copy (gpointer camel_object)
{
- GSList *res = NULL;
- GList *clist, *l;
+ if (CAMEL_IS_OBJECT (camel_object))
+ camel_object_ref (camel_object);
+
+ return camel_object;
+}
- clist = e_categories_get_list ();
- for (l = clist; l; l = l->next) {
- const char *cname = l->data;
- struct _filter_option *fo = g_new0 (struct _filter_option, 1);
+static void
+e_camel_object_free (gpointer camel_object)
+{
+ if (CAMEL_IS_OBJECT (camel_object))
+ camel_object_unref (camel_object);
+}
- fo->title = g_strdup (cname);
- fo->value = g_strdup (cname);
- res = g_slist_prepend (res, fo);
- }
+GType
+e_camel_object_get_type (void)
+{
+ static GType type = 0;
- g_list_free (clist);
+ if (G_UNLIKELY (type == 0))
+ type = g_boxed_type_register_static (
+ "ECamelObject",
+ (GBoxedCopyFunc) e_camel_object_copy,
+ (GBoxedFreeFunc) e_camel_object_free);
- return g_slist_reverse (res);
+ return type;
}
diff --git a/e-util/e-util.h b/e-util/e-util.h
index 021e3286c7..84ec411516 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -27,6 +27,7 @@
#include <gtk/gtk.h>
#include <limits.h>
#include <gconf/gconf-client.h>
+#include <camel/camel-object.h>
#include <cairo.h>
#include <e-util/e-marshal.h>
@@ -46,6 +47,16 @@ void e_show_uri (GtkWindow *parent,
const gchar *uri);
void e_display_help (GtkWindow *parent,
const gchar *link_id);
+GtkAction * e_lookup_action (GtkUIManager *ui_manager,
+ const gchar *action_name);
+GtkActionGroup *e_lookup_action_group (GtkUIManager *ui_manager,
+ const gchar *group_name);
+guint e_load_ui_definition (GtkUIManager *ui_manager,
+ const gchar *basename);
+gint e_action_compare_by_label (GtkAction *action1,
+ GtkAction *action2);
+void e_action_group_remove_all_actions
+ (GtkActionGroup *action_group);
char * e_str_without_underscores (const char *s);
gint e_str_compare (gconstpointer x,
@@ -58,6 +69,7 @@ gint e_int_compare (gconstpointer x,
gconstpointer y);
gboolean e_write_file_uri (const gchar *filename,
const gchar *data);
+guint32 e_color_to_value (GdkColor *color);
/* This only makes a filename safe for usage as a filename.
* It still may have shell meta-characters in it. */
@@ -118,7 +130,8 @@ gboolean e_file_lock_create (void);
void e_file_lock_destroy (void);
gboolean e_file_lock_exists (void);
-gchar * e_util_guess_mime_type (const gchar *filename, gboolean localfile);
+gchar * e_util_guess_mime_type (const gchar *filename,
+ gboolean localfile);
gchar * e_util_filename_to_uri (const gchar *filename);
gchar * e_util_uri_to_filename (const gchar *uri);
@@ -128,7 +141,10 @@ gboolean e_util_read_file (const gchar *filename,
gsize *read,
GError **error);
-GSList *e_util_get_category_filter_options (void);
+/* Camel uses its own object system, so we have to box
+ * CamelObjects to safely use them as GObject properties. */
+#define E_TYPE_CAMEL_OBJECT (e_camel_object_get_type ())
+GType e_camel_object_get_type (void);
G_END_DECLS
diff --git a/e-util/gconf-bridge.c b/e-util/gconf-bridge.c
index 66dcbc7ea2..4ab0f59646 100644
--- a/e-util/gconf-bridge.c
+++ b/e-util/gconf-bridge.c
@@ -1082,17 +1082,17 @@ gconf_bridge_bind_string_list_store (GConfBridge *bridge,
(list_store_binding_store_changed_cb),
binding);
binding->row_changed_id =
- g_signal_connect_swapped (list_store, "row-inserted",
+ g_signal_connect_swapped (list_store, "row-changed",
G_CALLBACK
(list_store_binding_store_changed_cb),
binding);
binding->row_deleted_id =
- g_signal_connect_swapped (list_store, "row-inserted",
+ g_signal_connect_swapped (list_store, "row-deleted",
G_CALLBACK
(list_store_binding_store_changed_cb),
binding);
binding->rows_reordered_id =
- g_signal_connect_swapped (list_store, "row-inserted",
+ g_signal_connect_swapped (list_store, "rows-reordered",
G_CALLBACK
(list_store_binding_store_changed_cb),
binding);