aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--composer/e-msg-composer.c3
-rw-r--r--e-util/e-signature-utils.c130
-rw-r--r--e-util/e-signature-utils.h1
-rw-r--r--mail/em-composer-prefs.c126
-rw-r--r--mail/mail-config.c126
-rw-r--r--mail/mail-config.h4
-rw-r--r--widgets/misc/Makefile.am2
-rw-r--r--widgets/misc/e-signature-preview.c344
-rw-r--r--widgets/misc/e-signature-preview.h81
-rw-r--r--widgets/misc/e-signature-tree-view.c46
10 files changed, 615 insertions, 248 deletions
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 65a372d0d0..b495474882 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -76,7 +76,6 @@
#include "mail/em-popup.h"
#include "mail/em-utils.h"
-#include "mail/mail-config.h"
#include "mail/mail-crypto.h"
#include "mail/mail-tools.h"
@@ -1180,7 +1179,7 @@ get_signature_html (EMsgComposer *composer)
format_html = signature->html;
if (signature->script)
- text = mail_config_signature_run_script (
+ text = e_run_signature_script (
signature->filename);
else
text = e_read_signature_file (
diff --git a/e-util/e-signature-utils.c b/e-util/e-signature-utils.c
index 5565ef9faf..0114ce6e06 100644
--- a/e-util/e-signature-utils.c
+++ b/e-util/e-signature-utils.c
@@ -29,6 +29,10 @@
#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;
@@ -215,3 +219,129 @@ e_read_signature_file (ESignature *signature,
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-signature-utils.h b/e-util/e-signature-utils.h
index d4fdfd97f4..41472f45d0 100644
--- a/e-util/e-signature-utils.h
+++ b/e-util/e-signature-utils.h
@@ -33,6 +33,7 @@ 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);
G_END_DECLS
diff --git a/mail/em-composer-prefs.c b/mail/em-composer-prefs.c
index ef73c23355..9b81935e90 100644
--- a/mail/em-composer-prefs.c
+++ b/mail/em-composer-prefs.c
@@ -49,6 +49,7 @@
#include "misc/e-charset-picker.h"
#include "misc/e-signature-manager.h"
+#include "misc/e-signature-preview.h"
#include "e-util/e-error.h"
#include "e-util/e-util-private.h"
@@ -213,49 +214,6 @@ em_composer_prefs_get_type (void)
return type;
}
-static void
-sig_load_preview (EMComposerPrefs *prefs,
- ESignature *signature)
-{
- GtkHTML *html;
- gchar *str;
-
- html = prefs->sig_preview;
-
- if (signature == NULL) {
- gtk_html_load_from_string (html, " ", 1);
- return;
- }
-
- if (signature->script)
- str = mail_config_signature_run_script (signature->filename);
- else
- /* FIXME Show an error in the preview area. */
- str = e_read_signature_file (signature, FALSE, NULL);
- if (!str || !*str) {
- /* make html stream happy and write at least one character */
- g_free (str);
- str = g_strdup (" ");
- }
-
- if (signature->html) {
- gtk_html_load_from_string (html, str, strlen (str));
- } else {
- GtkHTMLStream *stream;
- int len;
-
- len = strlen (str);
- stream = gtk_html_begin_content (html, "text/html; charset=utf-8");
- gtk_html_write (html, stream, "<PRE>", 5);
- if (len)
- gtk_html_write (html, stream, str, len);
- gtk_html_write (html, stream, "</PRE>", 6);
- gtk_html_end (html, stream, GTK_HTML_STREAM_OK);
- }
-
- g_free (str);
-}
-
void
em_composer_prefs_new_signature (GtkWindow *parent,
gboolean html_mode)
@@ -269,59 +227,6 @@ em_composer_prefs_new_signature (GtkWindow *parent,
}
static void
-sig_selection_changed (GtkTreeSelection *selection,
- EMComposerPrefs *prefs)
-{
- ESignature *signature;
- GtkTreeView *tree_view;
-
- tree_view = gtk_tree_selection_get_tree_view (selection);
-
- signature = e_signature_tree_view_get_selected (
- E_SIGNATURE_TREE_VIEW (tree_view));
-
- sig_load_preview (prefs, signature);
-
- if (signature != NULL)
- g_object_unref (signature);
-}
-
-static void
-url_requested (GtkHTML *html,
- const gchar *url,
- GtkHTMLStream *handle)
-{
- GtkHTMLStreamStatus status;
- gchar buf[128];
- gssize size;
- gint fd;
- gchar *filename;
-
- if (strncmp (url, "file:", 5) == 0)
- filename = g_filename_from_uri (url, NULL, NULL);
- else
- filename = g_strdup (url);
- fd = g_open (filename, O_RDONLY | O_BINARY, 0);
- g_free (filename);
-
- status = GTK_HTML_STREAM_OK;
- if (fd != -1) {
- while ((size = read (fd, buf, sizeof (buf)))) {
- if (size == -1) {
- status = GTK_HTML_STREAM_ERROR;
- break;
- } else
- gtk_html_write (html, handle, buf, size);
- }
- } else
- status = GTK_HTML_STREAM_ERROR;
-
- gtk_html_end (html, handle, status);
- if (fd > 0)
- close (fd);
-}
-
-static void
spell_language_toggled_cb (GtkCellRendererToggle *renderer,
const gchar *path_string,
EMComposerPrefs *prefs)
@@ -383,10 +288,8 @@ spell_setup (EMComposerPrefs *prefs)
{
const GList *available_languages;
GList *active_languages;
- GConfClient *client;
GtkListStore *store;
- client = mail_config_get_gconf_client ();
store = GTK_LIST_STORE (prefs->language_model);
available_languages = gtkhtml_spell_language_get_available ();
@@ -681,22 +584,19 @@ em_composer_prefs_construct (EMComposerPrefs *prefs,
signature_tree_view = e_signature_manager_get_tree_view (
E_SIGNATURE_MANAGER (widget));
- selection = gtk_tree_view_get_selection (
- GTK_TREE_VIEW (signature_tree_view));
- g_signal_connect (
- selection, "changed",
- G_CALLBACK (sig_selection_changed), prefs);
- /* preview GtkHTML widget */
- widget = glade_xml_get_widget (gui, "scrolled-sig");
- prefs->sig_preview = (GtkHTML *) gtk_html_new ();
- g_signal_connect (
- prefs->sig_preview, "url_requested",
- G_CALLBACK (url_requested), NULL);
- gtk_widget_show (GTK_WIDGET (prefs->sig_preview));
- gtk_container_add (
- GTK_CONTAINER (widget),
- GTK_WIDGET (prefs->sig_preview));
+ container = glade_xml_get_widget (gui, "scrolled-sig");
+ widget = e_signature_preview_new ();
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ e_binding_new_with_negation (
+ G_OBJECT (shell_settings), "disable-command-line",
+ G_OBJECT (widget), "allow-scripts");
+
+ e_binding_new (
+ G_OBJECT (signature_tree_view), "selected",
+ G_OBJECT (widget), "signature");
/* get our toplevel widget */
target = em_config_target_new_prefs (ec, client);
diff --git a/mail/mail-config.c b/mail/mail-config.c
index a7e8bb908c..3c39791dfa 100644
--- a/mail/mail-config.c
+++ b/mail/mail-config.c
@@ -39,10 +39,6 @@
#include <glib/gstdio.h>
#include <glib/gi18n-lib.h>
-#ifndef G_OS_WIN32
-#include <sys/wait.h>
-#endif
-
#include <gtkhtml/gtkhtml.h>
#include <glade/glade.h>
@@ -983,125 +979,3 @@ mail_config_get_lookup_book_local_only (void)
return config->book_lookup_local_only;
}
-
-char *
-mail_config_signature_run_script (const char *script)
-{
-#ifndef G_OS_WIN32
- int result, status;
- int in_fds[2];
- pid_t pid;
-
- if (config == NULL)
- mail_config_init ();
-
- if (config->scripts_disabled)
- return NULL;
-
- if (pipe (in_fds) == -1) {
- g_warning ("Failed to create pipe to '%s': %s", script, g_strerror (errno));
- return NULL;
- }
-
- if (!(pid = fork ())) {
- /* child process */
- int maxfd, i;
-
- 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 (i = 3; i < maxfd; i++) {
- if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO)
- fcntl (i, F_SETFD, FD_CLOEXEC);
- }
-
- execlp("/bin/sh", "/bin/sh", "-c", script, NULL);
- g_warning ("Could not execute %s: %s\n", script, g_strerror (errno));
- _exit (255);
- } else if (pid < 0) {
- g_warning ("Failed to create create child process '%s': %s", script, g_strerror (errno));
- close (in_fds [0]);
- close (in_fds [1]);
- return NULL;
- } else {
- CamelStreamFilter *filtered_stream;
- CamelStreamMem *memstream;
- CamelMimeFilter *charenc;
- CamelStream *stream;
- GByteArray *buffer;
- char *charset;
- char *content;
-
- /* parent process */
- close (in_fds[1]);
-
- stream = camel_stream_fs_new_with_fd (in_fds[0]);
-
- memstream = (CamelStreamMem *) camel_stream_mem_new ();
- buffer = g_byte_array_new ();
- camel_stream_mem_set_byte_array (memstream, buffer);
-
- camel_stream_write_to_stream (stream, (CamelStream *) memstream);
- camel_object_unref (stream);
-
- /* signature scripts are supposed to generate UTF-8 content, but because users
- are known to not ever 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
- preferred charset. */
- if (!g_utf8_validate ((char *)buffer->data, buffer->len, NULL)) {
- stream = (CamelStream *) memstream;
- memstream = (CamelStreamMem *) camel_stream_mem_new ();
- camel_stream_mem_set_byte_array (memstream, g_byte_array_new ());
-
- filtered_stream = camel_stream_filter_new_with_stream (stream);
- camel_object_unref (stream);
-
- charset = gconf_client_get_string (config->gconf, "/apps/evolution/mail/composer/charset", NULL);
- if (charset && *charset) {
- if ((charenc = (CamelMimeFilter *) camel_mime_filter_charset_new_convert (charset, "utf-8"))) {
- camel_stream_filter_add (filtered_stream, charenc);
- camel_object_unref (charenc);
- }
- }
- g_free (charset);
-
- camel_stream_write_to_stream ((CamelStream *) filtered_stream, (CamelStream *) memstream);
- camel_object_unref (filtered_stream);
- g_byte_array_free (buffer, TRUE);
-
- buffer = memstream->buffer;
- }
-
- camel_object_unref (memstream);
-
- g_byte_array_append (buffer, (const unsigned char *)"", 1);
- content = (char *)buffer->data;
- g_byte_array_free (buffer, FALSE);
-
- /* 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;
- }
-#else
- return NULL;
-#endif
-}
diff --git a/mail/mail-config.h b/mail/mail-config.h
index ecbdb198ea..6c4683113f 100644
--- a/mail/mail-config.h
+++ b/mail/mail-config.h
@@ -110,10 +110,6 @@ gboolean mail_config_get_enable_magic_spacebar (void);
struct _EAccountService *mail_config_get_default_transport (void);
-/* signatures */
-char *mail_config_signature_run_script (const char *script);
-
-
/* uri's got changed by the store, etc */
void mail_config_uri_renamed (GCompareFunc uri_cmp, const char *old, const char *new);
void mail_config_uri_deleted (GCompareFunc uri_cmp, const char *uri);
diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am
index a1d555085b..589bd1083e 100644
--- a/widgets/misc/Makefile.am
+++ b/widgets/misc/Makefile.am
@@ -80,6 +80,7 @@ widgetsinclude_HEADERS = \
e-signature-combo-box.h \
e-signature-editor.h \
e-signature-manager.h \
+ e-signature-preview.h \
e-signature-script-dialog.h \
e-signature-tree-view.h \
e-unicode.h \
@@ -131,6 +132,7 @@ libemiscwidgets_la_SOURCES = \
e-signature-combo-box.c \
e-signature-editor.c \
e-signature-manager.c \
+ e-signature-preview.c \
e-signature-script-dialog.c \
e-signature-tree-view.c \
e-unicode.c \
diff --git a/widgets/misc/e-signature-preview.c b/widgets/misc/e-signature-preview.c
new file mode 100644
index 0000000000..d618e05daa
--- /dev/null
+++ b/widgets/misc/e-signature-preview.c
@@ -0,0 +1,344 @@
+/*
+ * e-signature-preview.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-preview.h"
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib/gstdio.h>
+#include "e-util/e-signature-utils.h"
+
+#define E_SIGNATURE_PREVIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SIGNATURE_PREVIEW, ESignaturePreviewPrivate))
+
+enum {
+ PROP_0,
+ PROP_ALLOW_SCRIPTS,
+ PROP_SIGNATURE
+};
+
+enum {
+ REFRESH,
+ LAST_SIGNAL
+};
+
+struct _ESignaturePreviewPrivate {
+ ESignature *signature;
+ guint allow_scripts : 1;
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+signature_preview_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ALLOW_SCRIPTS:
+ e_signature_preview_set_allow_scripts (
+ E_SIGNATURE_PREVIEW (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SIGNATURE:
+ e_signature_preview_set_signature (
+ E_SIGNATURE_PREVIEW (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_preview_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ALLOW_SCRIPTS:
+ g_value_set_boolean (
+ value, e_signature_preview_get_allow_scripts (
+ E_SIGNATURE_PREVIEW (object)));
+ return;
+
+ case PROP_SIGNATURE:
+ g_value_set_object (
+ value, e_signature_preview_get_signature (
+ E_SIGNATURE_PREVIEW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_preview_dispose (GObject *object)
+{
+ ESignaturePreviewPrivate *priv;
+
+ priv = E_SIGNATURE_PREVIEW_GET_PRIVATE (object);
+
+ if (priv->signature != NULL) {
+ g_object_unref (priv->signature);
+ priv->signature = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+signature_preview_url_requested (GtkHTML *html,
+ const gchar *url,
+ GtkHTMLStream *handle)
+{
+ GtkHTMLStreamStatus status;
+ gchar buffer[128];
+ gchar *filename;
+ gssize size;
+ gint fd;
+
+ /* FIXME Use GInputStream for this. */
+
+ if (g_str_has_prefix (url, "file:"))
+ filename = g_filename_from_uri (url, NULL, NULL);
+ else
+ filename = g_strdup (url);
+ fd = g_open (filename, O_RDONLY, 0);
+ g_free (filename);
+
+ status = GTK_HTML_STREAM_OK;
+ if (fd != -1) {
+ while ((size = read (fd, buffer, sizeof (buffer)))) {
+ if (size == -1) {
+ status = GTK_HTML_STREAM_ERROR;
+ break;
+ } else
+ gtk_html_write (html, handle, buffer, size);
+ }
+ } else
+ status = GTK_HTML_STREAM_ERROR;
+
+ gtk_html_end (html, handle, status);
+
+ if (fd > 0)
+ close (fd);
+}
+
+static void
+signature_preview_refresh (ESignaturePreview *preview)
+{
+ GtkHTML *html;
+ ESignature *signature;
+ gchar *content = NULL;
+ gsize length;
+
+ /* XXX We should show error messages in the preview. */
+
+ html = GTK_HTML (preview);
+ signature = e_signature_preview_get_signature (preview);
+
+ if (signature == NULL)
+ goto clear;
+
+ if (signature->script && !preview->priv->allow_scripts)
+ goto clear;
+
+ if (signature->script)
+ content = e_run_signature_script (signature->filename);
+ else
+ content = e_read_signature_file (signature, FALSE, NULL);
+
+ if (content == NULL || *content == '\0')
+ goto clear;
+
+ length = strlen (content);
+
+ if (signature->html)
+ gtk_html_load_from_string (html, content, length);
+ else {
+ GtkHTMLStream *stream;
+
+ stream = gtk_html_begin_content (
+ html, "text/html; charset=utf-8");
+ gtk_html_write (html, stream, "<PRE>", 5);
+ if (length > 0)
+ gtk_html_write (html, stream, content, length);
+ gtk_html_write (html, stream, "</PRE>", 6);
+ gtk_html_end (html, stream, GTK_HTML_STREAM_OK);
+ }
+
+ g_free (content);
+ return;
+
+clear:
+ gtk_html_load_from_string (html, " ", 1);
+ g_free (content);
+}
+
+static void
+signature_preview_class_init (ESignaturePreviewClass *class)
+{
+ GObjectClass *object_class;
+ GtkHTMLClass *html_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ESignaturePreviewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = signature_preview_set_property;
+ object_class->get_property = signature_preview_get_property;
+ object_class->dispose = signature_preview_dispose;
+
+ html_class = GTK_HTML_CLASS (class);
+ html_class->url_requested = signature_preview_url_requested;
+
+ class->refresh = signature_preview_refresh;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ALLOW_SCRIPTS,
+ g_param_spec_boolean (
+ "allow-scripts",
+ "Allow Scripts",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SIGNATURE,
+ g_param_spec_object (
+ "signature",
+ "Signature",
+ NULL,
+ E_TYPE_SIGNATURE,
+ G_PARAM_READWRITE));
+
+ signals[REFRESH] = g_signal_new (
+ "refresh",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ESignaturePreviewClass, refresh),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+signature_preview_init (ESignaturePreview *preview)
+{
+ preview->priv = E_SIGNATURE_PREVIEW_GET_PRIVATE (preview);
+}
+
+GType
+e_signature_preview_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ESignaturePreviewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) signature_preview_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ESignaturePreview),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) signature_preview_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_HTML, "ESignaturePreview", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_signature_preview_new (void)
+{
+ return g_object_new (E_TYPE_SIGNATURE_PREVIEW, NULL);
+}
+
+void
+e_signature_preview_refresh (ESignaturePreview *preview)
+{
+ g_return_if_fail (E_IS_SIGNATURE_PREVIEW (preview));
+
+ g_signal_emit (preview, signals[REFRESH], 0);
+}
+
+gboolean
+e_signature_preview_get_allow_scripts (ESignaturePreview *preview)
+{
+ g_return_val_if_fail (E_IS_SIGNATURE_PREVIEW (preview), FALSE);
+
+ return preview->priv->allow_scripts;
+}
+
+void
+e_signature_preview_set_allow_scripts (ESignaturePreview *preview,
+ gboolean allow_scripts)
+{
+ g_return_if_fail (E_IS_SIGNATURE_PREVIEW (preview));
+
+ preview->priv->allow_scripts = allow_scripts;
+ g_object_notify (G_OBJECT (preview), "allow-scripts");
+}
+
+ESignature *
+e_signature_preview_get_signature (ESignaturePreview *preview)
+{
+ g_return_val_if_fail (E_IS_SIGNATURE_PREVIEW (preview), NULL);
+
+ return preview->priv->signature;
+}
+
+void
+e_signature_preview_set_signature (ESignaturePreview *preview,
+ ESignature *signature)
+{
+ g_return_if_fail (E_IS_SIGNATURE_PREVIEW (preview));
+
+ if (signature != NULL) {
+ g_return_if_fail (E_IS_SIGNATURE (signature));
+ g_object_ref (signature);
+ }
+
+ if (preview->priv->signature != NULL)
+ g_object_unref (preview->priv->signature);
+
+ preview->priv->signature = signature;
+ g_object_notify (G_OBJECT (preview), "signature");
+
+ e_signature_preview_refresh (preview);
+}
diff --git a/widgets/misc/e-signature-preview.h b/widgets/misc/e-signature-preview.h
new file mode 100644
index 0000000000..2cedcc1d2f
--- /dev/null
+++ b/widgets/misc/e-signature-preview.h
@@ -0,0 +1,81 @@
+/*
+ * e-signature-preview.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
+ * 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_SIGNATURE_PREVIEW_H
+#define E_SIGNATURE_PREVIEW_H
+
+#include <gtkhtml/gtkhtml.h>
+#include <e-util/e-signature.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SIGNATURE_PREVIEW \
+ (e_signature_preview_get_type ())
+#define E_SIGNATURE_PREVIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SIGNATURE_PREVIEW, ESignaturePreview))
+#define E_SIGNATURE_PREVIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SIGNATURE_PREVIEW, ESignaturePreviewClass))
+#define E_IS_SIGNATURE_PREVIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SIGNATURE_PREVIEW))
+#define E_IS_SIGNATURE_PREVIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SIGNATURE_PREVIEW))
+#define E_SIGNATURE_PREVIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SIGNATURE_PREVIEW, ESignaturePreview))
+
+G_BEGIN_DECLS
+
+typedef struct _ESignaturePreview ESignaturePreview;
+typedef struct _ESignaturePreviewClass ESignaturePreviewClass;
+typedef struct _ESignaturePreviewPrivate ESignaturePreviewPrivate;
+
+struct _ESignaturePreview {
+ GtkHTML parent;
+ ESignaturePreviewPrivate *priv;
+};
+
+struct _ESignaturePreviewClass {
+ GtkHTMLClass parent_class;
+
+ /* Signals */
+ void (*refresh) (ESignaturePreview *preview);
+};
+
+GType e_signature_preview_get_type (void);
+GtkWidget * e_signature_preview_new (void);
+void e_signature_preview_refresh (ESignaturePreview *preview);
+gboolean e_signature_preview_get_allow_scripts
+ (ESignaturePreview *preview);
+void e_signature_preview_set_allow_scripts
+ (ESignaturePreview *preview,
+ gboolean allow_scripts);
+ESignature * e_signature_preview_get_signature
+ (ESignaturePreview *preview);
+void e_signature_preview_set_signature
+ (ESignaturePreview *preview,
+ ESignature *signature);
+
+G_END_DECLS
+
+#endif /* E_SIGNATURE_PREVIEW_H */
diff --git a/widgets/misc/e-signature-tree-view.c b/widgets/misc/e-signature-tree-view.c
index ef1cc36b14..1f6d75b5b5 100644
--- a/widgets/misc/e-signature-tree-view.c
+++ b/widgets/misc/e-signature-tree-view.c
@@ -32,6 +32,7 @@ enum {
enum {
PROP_0,
+ PROP_SELECTED,
PROP_SIGNATURE_LIST
};
@@ -46,7 +47,7 @@ struct _ESignatureTreeViewPrivate {
};
static gpointer parent_class;
-static guint signal_ids[LAST_SIGNAL];
+static guint signals[LAST_SIGNAL];
static void
signature_tree_view_refresh_cb (ESignatureList *signature_list,
@@ -117,7 +118,13 @@ skip:
if (signature != NULL)
g_object_unref (signature);
- g_signal_emit (tree_view, signal_ids[REFRESHED], 0);
+ g_signal_emit (tree_view, signals[REFRESHED], 0);
+}
+
+static void
+signature_tree_view_selection_changed_cb (ESignatureTreeView *tree_view)
+{
+ g_object_notify (G_OBJECT (tree_view), "selected");
}
static GObject *
@@ -154,6 +161,12 @@ signature_tree_view_set_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_SELECTED:
+ e_signature_tree_view_set_selected (
+ E_SIGNATURE_TREE_VIEW (object),
+ g_value_get_object (value));
+ return;
+
case PROP_SIGNATURE_LIST:
e_signature_tree_view_set_signature_list (
E_SIGNATURE_TREE_VIEW (object),
@@ -171,6 +184,13 @@ signature_tree_view_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_SELECTED:
+ g_value_set_object (
+ value,
+ e_signature_tree_view_get_selected (
+ E_SIGNATURE_TREE_VIEW (object)));
+ return;
+
case PROP_SIGNATURE_LIST:
g_value_set_object (
value,
@@ -233,6 +253,16 @@ signature_tree_view_class_init (ESignatureTreeViewClass *class)
g_object_class_install_property (
object_class,
+ PROP_SELECTED,
+ g_param_spec_object (
+ "selected",
+ "Selected Signature",
+ NULL,
+ E_TYPE_SIGNATURE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
PROP_SIGNATURE_LIST,
g_param_spec_object (
"signature-list",
@@ -242,7 +272,7 @@ signature_tree_view_class_init (ESignatureTreeViewClass *class)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
- signal_ids[REFRESHED] = g_signal_new (
+ signals[REFRESHED] = g_signal_new (
"refreshed",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
@@ -255,6 +285,7 @@ static void
signature_tree_view_init (ESignatureTreeView *tree_view)
{
GHashTable *index;
+ GtkTreeSelection *selection;
/* Reverse-lookup index */
index = g_hash_table_new_full (
@@ -264,6 +295,13 @@ signature_tree_view_init (ESignatureTreeView *tree_view)
tree_view->priv = E_SIGNATURE_TREE_VIEW_GET_PRIVATE (tree_view);
tree_view->priv->index = index;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (signature_tree_view_selection_changed_cb),
+ tree_view);
}
GType
@@ -401,5 +439,7 @@ e_signature_tree_view_set_selected (ESignatureTreeView *tree_view,
gtk_tree_selection_select_path (selection, path);
gtk_tree_path_free (path);
+ g_object_notify (G_OBJECT (tree_view), "selected");
+
return TRUE;
}