aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--addressbook/gui/merging/Makefile.am1
-rw-r--r--addressbook/gui/widgets/Makefile.am2
-rw-r--r--addressbook/gui/widgets/eab-contact-display.c157
-rw-r--r--addressbook/gui/widgets/eab-contact-display.h6
-rw-r--r--calendar/Makefile.am2
-rw-r--r--calendar/gui/Makefile.am4
-rw-r--r--calendar/gui/alarm-notify/Makefile.am31
-rw-r--r--calendar/gui/e-cal-component-preview.c84
-rw-r--r--calendar/gui/e-cal-component-preview.h7
-rw-r--r--calendar/idl/Makefile.am7
-rw-r--r--calendar/idl/evolution-calendar.idl52
-rw-r--r--configure.ac16
-rw-r--r--e-util/e-marshal.list2
-rw-r--r--e-util/e-plugin.c112
-rw-r--r--e-util/e-util.c41
-rw-r--r--e-util/e-util.h5
-rw-r--r--evolution-shell.pc.in2
-rw-r--r--mail/e-mail-browser.c19
-rw-r--r--mail/e-mail-display.c753
-rw-r--r--mail/e-mail-display.h36
-rw-r--r--mail/e-mail-reader.c80
-rw-r--r--mail/e-mail-search-bar.c96
-rw-r--r--mail/e-mail-search-bar.h6
-rw-r--r--mail/em-utils.c92
-rw-r--r--mail/em-utils.h3
-rw-r--r--modules/addressbook/e-book-shell-backend.c29
-rw-r--r--modules/calendar/e-memo-shell-content.c11
-rw-r--r--modules/calendar/e-memo-shell-view-actions.c2
-rw-r--r--modules/calendar/e-memo-shell-view-private.c25
-rw-r--r--modules/calendar/e-memo-shell-view.c2
-rw-r--r--modules/calendar/e-task-shell-content.c11
-rw-r--r--modules/calendar/e-task-shell-view-actions.c2
-rw-r--r--modules/calendar/e-task-shell-view-private.c29
-rw-r--r--modules/calendar/e-task-shell-view.c2
-rw-r--r--modules/mail/e-mail-shell-content.c10
-rw-r--r--modules/mail/e-mail-shell-view-actions.c4
-rw-r--r--modules/mail/e-mail-shell-view-private.h1
-rw-r--r--plugins/vcard-inline/Makefile.am5
-rw-r--r--po/POTFILES.in3
-rw-r--r--shell/e-shell-view.c10
-rw-r--r--shell/e-shell-window-private.c16
-rw-r--r--shell/e-shell.c34
-rw-r--r--widgets/misc/Makefile.am2
-rw-r--r--widgets/misc/e-attachment-view.c44
-rw-r--r--widgets/misc/e-signature-preview.c71
-rw-r--r--widgets/misc/e-signature-preview.h6
-rw-r--r--widgets/misc/e-web-view.c1110
-rw-r--r--widgets/misc/e-web-view.h119
49 files changed, 1708 insertions, 1458 deletions
diff --git a/Makefile.am b/Makefile.am
index f79d67fbd8..53b463b10c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -53,8 +53,8 @@ SUBDIRS = \
shell \
$(SMIME_SUBDIR) \
em-format \
- composer \
addressbook \
+ composer \
mail \
calendar \
art \
diff --git a/addressbook/gui/merging/Makefile.am b/addressbook/gui/merging/Makefile.am
index fd13c9779e..e399c19747 100644
--- a/addressbook/gui/merging/Makefile.am
+++ b/addressbook/gui/merging/Makefile.am
@@ -2,6 +2,7 @@ AM_CPPFLAGS = \
-DG_LOG_DOMAIN=\"eab-contact-merging\" \
-DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
-I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
-I$(top_srcdir)/addressbook \
$(EVOLUTION_ADDRESSBOOK_CFLAGS)
diff --git a/addressbook/gui/widgets/Makefile.am b/addressbook/gui/widgets/Makefile.am
index 58d1e1b1d1..b642fde5c2 100644
--- a/addressbook/gui/widgets/Makefile.am
+++ b/addressbook/gui/widgets/Makefile.am
@@ -1,7 +1,7 @@
ruledir = $(privdatadir)
rule_DATA = addresstypes.xml
-AM_CPPFLAGS = \
+AM_CPPFLAGS = \
-DG_LOG_DOMAIN=\"eab-widgets\" \
-DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
-DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \
diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c
index d47b3e1866..0ade284323 100644
--- a/addressbook/gui/widgets/eab-contact-display.c
+++ b/addressbook/gui/widgets/eab-contact-display.c
@@ -240,71 +240,6 @@ contact_display_selection_clear_event (EABContactDisplay *display,
}
static void
-contact_display_on_url_requested (GtkHTML *html,
- const gchar *url,
- GtkHTMLStream *handle,
- EABContactDisplay *display)
-{
- if (!strcmp (url, "internal-contact-photo:")) {
- EContactPhoto *photo;
-
- photo = e_contact_get (display->priv->contact, E_CONTACT_PHOTO);
- if (!photo)
- photo = e_contact_get (display->priv->contact, E_CONTACT_LOGO);
-
- gtk_html_stream_write (handle, (gchar *)photo->data.inlined.data, photo->data.inlined.length);
-
- gtk_html_end (html, handle, GTK_HTML_STREAM_OK);
-
- e_contact_photo_free (photo);
- }
- else if (!strncmp (url, "evo-icon:", strlen ("evo-icon:"))) {
- gchar *data;
- gsize data_length;
- gchar *filename;
-
- filename = e_icon_factory_get_icon_filename (url + strlen ("evo-icon:"), GTK_ICON_SIZE_MENU);
- if (g_file_get_contents (filename, &data, &data_length, NULL)) {
- gtk_html_stream_write (handle, data, data_length);
- g_free (data);
- }
-
- gtk_html_stream_close (handle, GTK_HTML_STREAM_OK);
-
- g_free (filename);
- }
-}
-
-static void
-contact_display_on_link_clicked (GtkHTML *html,
- const gchar *uri,
- EABContactDisplay *display)
-{
-#ifdef HANDLE_MAILTO_INTERNALLY
- if (!strncmp (uri, "internal-mailto:", strlen ("internal-mailto:"))) {
- EDestination *destination;
- EContact *contact;
- gint email_num;
-
- email_num = atoi (uri + strlen ("internal-mailto:"));
- if (email_num == -1)
- return;
-
- destination = e_destination_new ();
- contact = eab_contact_display_get_contact (display);
- e_destination_set_contact (destination, contact, email_num);
- g_signal_emit (display, signals[SEND_MESSAGE], 0, destination);
- g_object_unref (destination);
-
- return;
- }
-#endif
-
- /* FIXME Pass a parent window. */
- e_show_uri (NULL, uri);
-}
-
-static void
render_name_value (GtkHTMLStream *html_stream, const gchar *label, const gchar *str, const gchar *icon, guint html_flags)
{
gchar *value = e_text_to_html (str, html_flags);
@@ -1033,9 +968,89 @@ contact_display_finalize (GObject *object)
}
static void
+contact_display_url_requested (GtkHTML *html,
+ const gchar *url,
+ GtkHTMLStream *handle)
+{
+ EABContactDisplayPrivate *priv;
+
+ priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (html);
+
+ if (strcmp (url, "internal-contact-photo:") == 0) {
+ EContactPhoto *photo;
+
+ photo = e_contact_get (priv->contact, E_CONTACT_PHOTO);
+ if (!photo)
+ photo = e_contact_get (priv->contact, E_CONTACT_LOGO);
+
+ gtk_html_stream_write (handle, (gchar *)photo->data.inlined.data, photo->data.inlined.length);
+
+ gtk_html_end (html, handle, GTK_HTML_STREAM_OK);
+
+ e_contact_photo_free (photo);
+
+ return;
+ }
+
+ if (strncmp (url, "evo-icon:", strlen ("evo-icon:")) == 0) {
+ gchar *data;
+ gsize data_length;
+ gchar *filename;
+
+ filename = e_icon_factory_get_icon_filename (url + strlen ("evo-icon:"), GTK_ICON_SIZE_MENU);
+ if (g_file_get_contents (filename, &data, &data_length, NULL)) {
+ gtk_html_stream_write (handle, data, data_length);
+ g_free (data);
+ }
+
+ gtk_html_stream_close (handle, GTK_HTML_STREAM_OK);
+
+ g_free (filename);
+
+ return;
+ }
+
+ /* Chain up to parent's url_requested() method. */
+ GTK_HTML_CLASS (parent_class)->url_requested (html, url, handle);
+}
+
+static void
+contact_display_link_clicked (GtkHTML *html,
+ const gchar *uri)
+{
+ EABContactDisplay *display;
+
+ display = EAB_CONTACT_DISPLAY (html);
+
+#ifdef HANDLE_MAILTO_INTERNALLY
+ if (!strncmp (uri, "internal-mailto:", strlen ("internal-mailto:"))) {
+ EDestination *destination;
+ EContact *contact;
+ gint email_num;
+
+ email_num = atoi (uri + strlen ("internal-mailto:"));
+ if (email_num == -1)
+ return;
+
+ destination = e_destination_new ();
+ contact = eab_contact_display_get_contact (display);
+ e_destination_set_contact (destination, contact, email_num);
+ g_signal_emit (display, signals[SEND_MESSAGE], 0, destination);
+ g_object_unref (destination);
+
+ return;
+ }
+#endif
+
+ /* Chain up to parent's link_clicked() method. */
+ GTK_HTML_CLASS (parent_class)->link_clicked (html, uri);
+}
+
+static void
eab_contact_display_class_init (EABContactDisplayClass *class)
{
GObjectClass *object_class;
+ GtkHTMLClass *html_class;
parent_class = g_type_class_peek_parent (class);
g_type_class_add_private (class, sizeof (EABContactDisplayPrivate));
@@ -1046,6 +1061,10 @@ eab_contact_display_class_init (EABContactDisplayClass *class)
object_class->dispose = contact_display_dispose;
object_class->finalize = contact_display_finalize;
+ html_class = GTK_HTML_CLASS (class);
+ html_class->url_requested = contact_display_url_requested;
+ html_class->link_clicked = contact_display_link_clicked;
+
g_object_class_install_property (
object_class,
PROP_CONTACT,
@@ -1123,12 +1142,6 @@ eab_contact_display_init (EABContactDisplay *display)
gtk_html_set_default_content_type (html, "text/html; charset=utf-8");
g_signal_connect (
- display, "url-requested",
- G_CALLBACK (contact_display_on_url_requested), display);
- g_signal_connect (
- display, "link-clicked",
- G_CALLBACK (contact_display_on_link_clicked), display);
- g_signal_connect (
display, "button-press-event",
G_CALLBACK (contact_display_button_press_event), display);
@@ -1170,7 +1183,7 @@ eab_contact_display_get_type (void)
};
type = g_type_register_static (
- GTK_TYPE_HTML, "EABContactDisplay", &type_info, 0);
+ E_TYPE_WEB_VIEW, "EABContactDisplay", &type_info, 0);
}
return type;
diff --git a/addressbook/gui/widgets/eab-contact-display.h b/addressbook/gui/widgets/eab-contact-display.h
index 5a6902fc20..7b9707e0af 100644
--- a/addressbook/gui/widgets/eab-contact-display.h
+++ b/addressbook/gui/widgets/eab-contact-display.h
@@ -23,9 +23,9 @@
#ifndef EAB_CONTACT_DISPLAY_H
#define EAB_CONTACT_DISPLAY_H
-#include <gtkhtml/gtkhtml.h>
#include <libebook/e-contact.h>
#include <libebook/e-destination.h>
+#include <misc/e-web-view.h>
/* Standard GObject macros */
#define EAB_TYPE_CONTACT_DISPLAY \
@@ -58,12 +58,12 @@ typedef enum {
} EABContactDisplayMode;
struct _EABContactDisplay {
- GtkHTML parent;
+ EWebView parent;
EABContactDisplayPrivate *priv;
};
struct _EABContactDisplayClass {
- GtkHTMLClass parent_class;
+ EWebViewClass parent_class;
/* Signals */
void (*send_message) (EABContactDisplay *display,
diff --git a/calendar/Makefile.am b/calendar/Makefile.am
index 87057a4d3a..ecdd2d2cc6 100644
--- a/calendar/Makefile.am
+++ b/calendar/Makefile.am
@@ -4,7 +4,7 @@ else
CONDUIT_DIR =
endif
-SUBDIRS = idl common importers gui $(CONDUIT_DIR)
+SUBDIRS = common importers gui $(CONDUIT_DIR)
error_DATA = calendar.error
errordir = $(privdatadir)/errors
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index ede213e1ff..f05a038624 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -2,7 +2,9 @@ if OS_WIN32
WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libevolution-mail.la
endif
-SUBDIRS = alarm-notify dialogs
+# KILL-BONOBO: Temporarily disabled alarm-notify
+#SUBDIRS = alarm-notify dialogs
+SUBDIRS = dialogs
privsolib_LTLIBRARIES = libevolution-calendar.la
diff --git a/calendar/gui/alarm-notify/Makefile.am b/calendar/gui/alarm-notify/Makefile.am
index ea1c36e0d9..d8a68387fe 100644
--- a/calendar/gui/alarm-notify/Makefile.am
+++ b/calendar/gui/alarm-notify/Makefile.am
@@ -1,19 +1,3 @@
-CORBA_GENERATED_H = \
- evolution-calendar.h
-CORBA_GENERATED_C = \
- evolution-calendar-common.c \
- evolution-calendar-skels.c \
- evolution-calendar-stubs.c
-CORBA_GENERATED = $(CORBA_GENERATED_C) $(CORBA_GENERATED_H)
-
-idls = $(top_srcdir)/calendar/idl/evolution-calendar.idl
-idl_flags = $(IDL_INCLUDES)
-
-$(CORBA_GENERATED_H): $(idls)
- $(ORBIT_IDL) $(idl_flags) $(top_srcdir)/calendar/idl/evolution-calendar.idl
-$(CORBA_GENERATED_C): $(CORBA_GENERATED_H)
-
-
privlibexec_PROGRAMS = evolution-alarm-notify
@@ -59,19 +43,6 @@ if OS_WIN32
evolution_alarm_notify_LDFLAGS = -mwindows
endif
-server_in_files = GNOME_Evolution_Calendar_AlarmNotify.server.in.in
-server_DATA = $(server_in_files:.server.in.in=.server)
-@EVO_SERVER_RULE@
-@INTLTOOL_SERVER_RULE@
-
-EXTRA_DIST = \
- $(server_in_files) \
- $(glade_DATA)
-
-BUILT_SOURCES = $(CORBA_GENERATED) $(server_DATA)
-CLEANFILES = $(BUILT_SOURCES)
-
-dist-hook:
- cd $(distdir); rm -f $(BUILT_SOURCES)
+EXTRA_DIST = $(glade_DATA)
-include $(top_srcdir)/git.mk
diff --git a/calendar/gui/e-cal-component-preview.c b/calendar/gui/e-cal-component-preview.c
index 633eb5678e..b0ba329286 100644
--- a/calendar/gui/e-cal-component-preview.c
+++ b/calendar/gui/e-cal-component-preview.c
@@ -271,83 +271,10 @@ cal_component_preview_write_html (GtkHTMLStream *stream,
}
static void
-cal_component_preview_url_requested (GtkHTML *html,
- const gchar *url,
- GtkHTMLStream *html_stream)
-{
- GFile *file;
- GFileInputStream *input_stream;
- gchar buffer[4096];
- gssize bytes_read;
- GError *error = NULL;
-
- file = g_file_new_for_uri (url);
-
- /* XXX We only handle native files, which I guess minimizes
- * the damage from doing blocking reads here. Annoying
- * that GtkHTML does not handle this itself. */
- if (!g_file_is_native (file))
- goto exit;
-
- input_stream = g_file_read (file, NULL, &error);
-
- if (error != NULL)
- goto fail;
-
- do {
- bytes_read = g_input_stream_read (
- G_INPUT_STREAM (input_stream),
- buffer, sizeof (buffer), NULL, &error);
-
- if (bytes_read > 0)
- gtk_html_stream_write (
- html_stream, buffer, bytes_read);
-
- } while (bytes_read > 0);
-
- if (error != NULL)
- goto fail;
-
- gtk_html_stream_close (html_stream, GTK_HTML_STREAM_OK);
-
- goto exit;
-
-fail:
- g_warning ("%s", error->message);
- g_error_free (error);
-
- gtk_html_stream_close (html_stream, GTK_HTML_STREAM_ERROR);
-
-exit:
- if (input_stream != NULL)
- g_object_unref (input_stream);
-
- g_object_unref (file);
-}
-
-static void
-cal_component_preview_link_clicked (GtkHTML *html,
- const gchar *uri)
-{
- gpointer parent;
-
- parent = gtk_widget_get_toplevel (GTK_WIDGET (html));
- parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
-
- e_show_uri (parent, uri);
-}
-
-static void
cal_component_preview_class_init (ECalComponentPreviewClass *class)
{
- GtkHTMLClass *gtkhtml_class;
-
parent_class = g_type_class_peek_parent (class);
g_type_class_add_private (class, sizeof (ECalComponentPreviewPrivate));
-
- gtkhtml_class = GTK_HTML_CLASS (class);
- gtkhtml_class->url_requested = cal_component_preview_url_requested;
- gtkhtml_class->link_clicked = cal_component_preview_link_clicked;
}
static void
@@ -384,7 +311,8 @@ e_cal_component_preview_get_type (void)
};
type = g_type_register_static (
- GTK_TYPE_HTML, "ECalComponentPreview", &type_info, 0);
+ E_TYPE_WEB_VIEW, "ECalComponentPreview",
+ &type_info, 0);
}
return type;
@@ -429,11 +357,3 @@ e_cal_component_preview_display (ECalComponentPreview *preview,
stream, ecal, comp, preview->priv->zone);
gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
}
-
-void
-e_cal_component_preview_clear (ECalComponentPreview *preview)
-{
- g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview));
-
- gtk_html_load_empty (GTK_HTML (preview));
-}
diff --git a/calendar/gui/e-cal-component-preview.h b/calendar/gui/e-cal-component-preview.h
index 8b2b0acd18..78567f06ec 100644
--- a/calendar/gui/e-cal-component-preview.h
+++ b/calendar/gui/e-cal-component-preview.h
@@ -26,7 +26,7 @@
#include <gtk/gtk.h>
#include <libecal/e-cal.h>
-#include <gtkhtml/gtkhtml.h>
+#include <misc/e-web-view.h>
/* Standard GObject macros */
#define E_TYPE_CAL_COMPONENT_PREVIEW \
@@ -54,12 +54,12 @@ typedef struct _ECalComponentPreviewClass ECalComponentPreviewClass;
typedef struct _ECalComponentPreviewPrivate ECalComponentPreviewPrivate;
struct _ECalComponentPreview {
- GtkHTML parent;
+ EWebView parent;
ECalComponentPreviewPrivate *priv;
};
struct _ECalComponentPreviewClass {
- GtkHTMLClass parent_class;
+ EWebViewClass parent_class;
/* Notification signals */
void (* selection_changed) (ECalComponentPreview *preview, gint n_selected);
@@ -75,7 +75,6 @@ void e_cal_component_preview_set_default_timezone
void e_cal_component_preview_display (ECalComponentPreview *preview,
ECal *ecal,
ECalComponent *comp);
-void e_cal_component_preview_clear (ECalComponentPreview *preview);
G_END_DECLS
diff --git a/calendar/idl/Makefile.am b/calendar/idl/Makefile.am
deleted file mode 100644
index 1d393a8f9d..0000000000
--- a/calendar/idl/Makefile.am
+++ /dev/null
@@ -1,7 +0,0 @@
-idl_DATA = \
- evolution-calendar.idl
-
-EXTRA_DIST = \
- $(idl_DATA)
-
--include $(top_srcdir)/git.mk
diff --git a/calendar/idl/evolution-calendar.idl b/calendar/idl/evolution-calendar.idl
deleted file mode 100644
index 48f7281ab3..0000000000
--- a/calendar/idl/evolution-calendar.idl
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Evolution calendar interface
- *
- * Copyright (C) 2000 Eskil Heyn Olsen
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Eskil Heyn Olsen <deity@eskil.dk>
- * Federico Mena-Quintero <federico@ximian.com>
- */
-
-#ifndef _EVOLUTION_CALENDAR_IDL_
-#define _EVOLUTION_CALENDAR_IDL_
-
-#include <Bonobo.idl>
-#include <Evolution-DataServer-Calendar.idl>
-
-module GNOME {
-module Evolution {
-
-module Calendar {
- /* Factory to centralize calendar component editor dialogs */
- interface CompEditorFactory : Bonobo::Unknown {
- exception InvalidURI {};
- exception BackendContactError {};
- exception UnsupportedType {};
-
- typedef long CompEditorMode;
- const CompEditorMode EDITOR_MODE_EVENT = 1 << 0;
- const CompEditorMode EDITOR_MODE_ALLDAY_EVENT = 1 << 1;
- const CompEditorMode EDITOR_MODE_MEETING = 1 << 2;
- const CompEditorMode EDITOR_MODE_TODO = 1 << 3;
-
- /* Loads a calendar and opens an editor for the specified object */
- /* FIXME Its nasty to use CompEditorMode to pass event/todo source type
- but it saves adding yet another corba type - only MODE_EVENT or
- MODE_TODO should be passed here */
- void editExisting (in string uri, in CalObjUID uid, in CompEditorMode mode)
- raises (InvalidURI, BackendContactError);
-
- /* Loads a calendar and creates a new component of the specified type */
- void editNew (in string uri, in CompEditorMode mode)
- raises (InvalidURI, BackendContactError, UnsupportedType);
- };
-
- interface AlarmNotify : Bonobo::Unknown {
- };
-};
-
-};
-};
-
-#endif
diff --git a/configure.ac b/configure.ac
index 1f709dc44e..1ac2923ce6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -52,7 +52,6 @@ m4_define([gtk_minimum_version], [2.16.0])
m4_define([eds_minimum_version], [evo_version])
m4_define([gnome_icon_theme_minimum_version], [2.19.91])
m4_define([gnome_desktop_minimum_version], [2.26.0])
-m4_define([libbonobo_minimum_version], [2.20.3])
m4_define([libgtkhtml_minimum_version], [3.27.90])
m4_define([gconf_minimum_version], [2.0.0]) dnl XXX Just a Guess
m4_define([libglade_minimum_version], [2.0.0]) dnl XXX Just a Guess
@@ -238,7 +237,6 @@ PKG_CHECK_MODULES([GNOME_PLATFORM],
[glib-2.0 >= glib_minimum_version
gtk+-2.0 >= gtk_minimum_version
gconf-2.0 >= gconf_minimum_version
- libbonobo-2.0 >= libbonobo_minimum_version
libglade-2.0 >= libglade_minimum_version
libgnomecanvas-2.0 >= libgnomecanvas_minimum_version
libgnomeui-2.0 >= libgnomeui_minimum_version
@@ -1383,11 +1381,6 @@ dnl Orbit / Bonobo
dnl *************************
AM_PATH_ORBIT2(2.9.8)
-AC_MSG_CHECKING([for CORBA include paths])
-IDL_INCLUDES="-I "`${PKG_CONFIG} --variable=idldir libbonobo-2.0`" -I "`${PKG_CONFIG} --variable=idldir bonobo-activation-2.0`" -I "`${PKG_CONFIG} --variable=idldir evolution-data-server-1.2`
-AC_MSG_RESULT([$IDL_INCLUDES])
-AC_SUBST(IDL_INCLUDES)
-
dnl *****************************************************************
dnl Utility macro to set compiler flags for a specific lib.
dnl EVO_SET_COMPILE_FLAGS(VAR-PREFIX, DEPS, EXTRA-CFLAGS, EXTRA-LIBS)
@@ -1611,7 +1604,7 @@ fi
dnl **********
dnl Mail Flags
dnl **********
-EVO_SET_COMPILE_FLAGS(EVOLUTION_MAIL, camel-provider-$EDS_PACKAGE libgnomeui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE gtkhtml-editor bonobo-activation-2.0 $mozilla_nss libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE unique-1.0)
+EVO_SET_COMPILE_FLAGS(EVOLUTION_MAIL, camel-provider-$EDS_PACKAGE libgnomeui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE gtkhtml-editor $mozilla_nss libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE unique-1.0)
AC_SUBST(EVOLUTION_MAIL_CFLAGS)
AC_SUBST(EVOLUTION_MAIL_LIBS)
@@ -1672,12 +1665,6 @@ AC_SUBST(componentdir)
moduledir="$privlibdir/modules"
AC_SUBST(moduledir)
-idldir='${datadir}'/idl/evolution-$BASE_VERSION
-AC_SUBST(idldir)
-
-serverdir="$libdir/bonobo/servers"
-AC_SUBST(serverdir)
-
evolutionuidir="$privdatadir/ui"
AC_SUBST(evolutionuidir)
@@ -1999,7 +1986,6 @@ widgets/table/Makefile
calendar/Makefile
calendar/importers/Makefile
calendar/common/Makefile
-calendar/idl/Makefile
calendar/conduits/Makefile
calendar/conduits/common/Makefile
calendar/conduits/todo/Makefile
diff --git a/e-util/e-marshal.list b/e-util/e-marshal.list
index d6a3f0cb55..c4426d46d7 100644
--- a/e-util/e-marshal.list
+++ b/e-util/e-marshal.list
@@ -1,4 +1,4 @@
-BOOLEAN:BOXED,POINTER,POINTER
+BOOLEAN:BOXED,STRING
BOOLEAN:INT,INT,OBJECT,INT,INT,UINT
BOOLEAN:INT,POINTER,INT,OBJECT,INT,INT,UINT
BOOLEAN:NONE
diff --git a/e-util/e-plugin.c b/e-util/e-plugin.c
index 5d77decfd9..49a15da651 100644
--- a/e-util/e-plugin.c
+++ b/e-util/e-plugin.c
@@ -31,6 +31,7 @@
#include "e-plugin.h"
#include "e-util-private.h"
+#include "e-util.h"
/* plugin debug */
#define pd(x)
@@ -487,79 +488,50 @@ e_plugin_add_load_path(const gchar *path)
}
static void
-plugin_load_subclasses (void)
+plugin_load_subclass (GType type,
+ GHashTable *hash_table)
{
- GType *children;
- guint n_children, ii;
-
- ep_types = g_hash_table_new (g_str_hash, g_str_equal);
- eph_types = g_hash_table_new (g_str_hash, g_str_equal);
- ep_plugins = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* Load EPlugin subclasses. */
-
- children = g_type_children (E_TYPE_PLUGIN, &n_children);
-
- for (ii = 0; ii < n_children; ii++) {
- EPluginClass *class;
-
- class = g_type_class_ref (children[ii]);
- g_hash_table_insert (ep_types, (gpointer) class->type, class);
- }
+ EPluginClass *class;
- g_free (children);
+ class = g_type_class_ref (type);
+ g_hash_table_insert (hash_table, (gpointer) class->type, class);
}
static void
-plugin_load_hook_subclasses (GType parent_type)
+plugin_hook_load_subclass (GType type,
+ GHashTable *hash_table)
{
- GType *children;
- guint n_children, ii;
-
- children = g_type_children (parent_type, &n_children);
-
- for (ii = 0; ii < n_children; ii++) {
- EPluginHookClass *hook_class;
- EPluginHookClass *dupe_class;
- gpointer key;
-
- /* First load the child's children. */
- plugin_load_hook_subclasses (children[ii]);
-
- /* Skip abstract types. */
- if (G_TYPE_IS_ABSTRACT (children[ii]))
- continue;
-
- hook_class = g_type_class_ref (children[ii]);
-
- /* Sanity check the hook class. */
- if (hook_class->id == NULL || *hook_class->id == '\0') {
- g_warning (
- "%s has no hook ID, so skipping",
- G_OBJECT_CLASS_NAME (hook_class));
- g_type_class_unref (hook_class);
- continue;
- }
-
- /* Check for class ID collisions. */
- dupe_class = g_hash_table_lookup (eph_types, hook_class->id);
- if (dupe_class != NULL) {
- g_warning (
- "%s and %s have the same hook "
- "ID ('%s'), so skipping %s",
- G_OBJECT_CLASS_NAME (dupe_class),
- G_OBJECT_CLASS_NAME (hook_class),
- hook_class->id,
- G_OBJECT_CLASS_NAME (hook_class));
- g_type_class_unref (hook_class);
- continue;
- }
+ EPluginHookClass *hook_class;
+ EPluginHookClass *dupe_class;
+ gpointer key;
+
+ hook_class = g_type_class_ref (type);
+
+ /* Sanity check the hook class. */
+ if (hook_class->id == NULL || *hook_class->id == '\0') {
+ g_warning (
+ "%s has no hook ID, so skipping",
+ G_OBJECT_CLASS_NAME (hook_class));
+ g_type_class_unref (hook_class);
+ return;
+ }
- key = (gpointer) hook_class->id;
- g_hash_table_insert (eph_types, key, hook_class);
+ /* Check for class ID collisions. */
+ dupe_class = g_hash_table_lookup (hash_table, hook_class->id);
+ if (dupe_class != NULL) {
+ g_warning (
+ "%s and %s have the same hook "
+ "ID ('%s'), so skipping %s",
+ G_OBJECT_CLASS_NAME (dupe_class),
+ G_OBJECT_CLASS_NAME (hook_class),
+ hook_class->id,
+ G_OBJECT_CLASS_NAME (hook_class));
+ g_type_class_unref (hook_class);
+ return;
}
- g_free (children);
+ key = (gpointer) hook_class->id;
+ g_hash_table_insert (hash_table, key, hook_class);
}
/**
@@ -580,11 +552,19 @@ e_plugin_load_plugins(void)
if (eph_types != NULL)
return 0;
+ ep_types = g_hash_table_new (g_str_hash, g_str_equal);
+ eph_types = g_hash_table_new (g_str_hash, g_str_equal);
+ ep_plugins = g_hash_table_new (g_str_hash, g_str_equal);
+
/* We require that all GTypes for EPlugin and EPluginHook
* subclasses be registered prior to loading any plugins.
* It greatly simplifies the loading process. */
- plugin_load_subclasses ();
- plugin_load_hook_subclasses (E_TYPE_PLUGIN_HOOK);
+ e_type_traverse (
+ E_TYPE_PLUGIN, (ETypeFunc)
+ plugin_load_subclass, ep_types);
+ e_type_traverse (
+ E_TYPE_PLUGIN_HOOK, (ETypeFunc)
+ plugin_hook_load_subclass, eph_types);
client = gconf_client_get_default ();
ep_disabled = gconf_client_get_list (
diff --git a/e-util/e-util.c b/e-util/e-util.c
index 57ec251c55..3c004e57cb 100644
--- a/e-util/e-util.c
+++ b/e-util/e-util.c
@@ -407,6 +407,47 @@ e_radio_action_get_current_action (GtkRadioAction *radio_action)
}
/**
+ * e_type_traverse:
+ * @parent_type: the root #GType to traverse from
+ * @func: the function to call for each visited #GType
+ * @user_data: user data to pass to the function
+ *
+ * Calls @func for all instantiable subtypes of @parent_type.
+ *
+ * This is often useful for extending functionality by way of #EModule.
+ * A module may register a subtype of @parent_type in its e_module_load()
+ * function. Then later on the application will call e_type_traverse()
+ * to instantiate all registered subtypes of @parent_type.
+ **/
+void
+e_type_traverse (GType parent_type,
+ ETypeFunc func,
+ gpointer user_data)
+{
+ GType *children;
+ guint n_children, ii;
+
+ g_return_if_fail (func != NULL);
+
+ children = g_type_children (parent_type, &n_children);
+
+ for (ii = 0; ii < n_children; ii++) {
+ GType type = children[ii];
+
+ /* Recurse over the child's children. */
+ e_type_traverse (type, func, user_data);
+
+ /* Skip abstract types. */
+ if (G_TYPE_IS_ABSTRACT (type))
+ continue;
+
+ func (type, user_data);
+ }
+
+ g_free (children);
+}
+
+/**
* e_str_without_underscores:
* @s: the string to strip underscores from.
*
diff --git a/e-util/e-util.h b/e-util/e-util.h
index 33bc940df7..1e2320914e 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -41,6 +41,8 @@ typedef enum {
E_FOCUS_END
} EFocus;
+typedef void (*ETypeFunc) (GType type, gpointer user_data);
+
const gchar * e_get_user_data_dir (void);
const gchar * e_get_accels_filename (void);
void e_show_uri (GtkWindow *parent,
@@ -59,6 +61,9 @@ void e_action_group_remove_all_actions
(GtkActionGroup *action_group);
GtkRadioAction *e_radio_action_get_current_action
(GtkRadioAction *radio_action);
+void e_type_traverse (GType parent_type,
+ ETypeFunc func,
+ gpointer user_data);
gchar * e_str_without_underscores (const gchar *s);
gint e_str_compare (gconstpointer x,
diff --git a/evolution-shell.pc.in b/evolution-shell.pc.in
index b94dd8512f..c9e4ade8c3 100644
--- a/evolution-shell.pc.in
+++ b/evolution-shell.pc.in
@@ -17,8 +17,6 @@ imagesdir=@imagesdir@
execversion=@BASE_VERSION@
-IDL_INCLUDES=-I ${idldir} @IDL_INCLUDES@
-
Name: evolution-shell
Description: libraries needed for Evolution shell components
Version: @VERSION@
diff --git a/mail/e-mail-browser.c b/mail/e-mail-browser.c
index ea860c016f..69199bfa1a 100644
--- a/mail/e-mail-browser.c
+++ b/mail/e-mail-browser.c
@@ -123,22 +123,20 @@ static GtkActionEntry mail_browser_entries[] = {
static void
mail_browser_menu_item_select_cb (EMailBrowser *browser,
- GtkWidget *menu_item)
+ GtkWidget *widget)
{
GtkAction *action;
GtkStatusbar *statusbar;
- gchar *tooltip = NULL;
+ const gchar *tooltip;
guint context_id;
gpointer data;
- action = g_object_get_data (G_OBJECT (menu_item), "action");
- g_return_if_fail (GTK_IS_ACTION (action));
+ action = gtk_widget_get_action (widget);
+ tooltip = gtk_action_get_tooltip (action);
- data = g_object_get_data (G_OBJECT (menu_item), "context-id");
+ data = g_object_get_data (G_OBJECT (widget), "context-id");
context_id = GPOINTER_TO_UINT (data);
- g_object_get (action, "tooltip", &tooltip, NULL);
-
if (tooltip == NULL)
return;
@@ -175,11 +173,6 @@ mail_browser_connect_proxy_cb (EMailBrowser *browser,
statusbar = GTK_STATUSBAR (browser->priv->statusbar);
context_id = gtk_statusbar_get_context_id (statusbar, G_STRFUNC);
- g_object_set_data_full (
- G_OBJECT (proxy),
- "action", g_object_ref (action),
- (GDestroyNotify) g_object_unref);
-
g_object_set_data (
G_OBJECT (proxy), "context-id",
GUINT_TO_POINTER (context_id));
@@ -440,7 +433,7 @@ mail_browser_constructed (GObject *object)
priv->statusbar = g_object_ref (widget);
gtk_widget_show (widget);
- widget = e_mail_search_bar_new (EM_FORMAT_HTML (html_display)->html);
+ widget = e_mail_search_bar_new (E_WEB_VIEW (html));
gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
priv->search_bar = g_object_ref (widget);
gtk_widget_hide (widget);
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
index c29328b36b..df65c256f7 100644
--- a/mail/e-mail-display.c
+++ b/mail/e-mail-display.c
@@ -22,7 +22,6 @@
#include "e-mail-display.h"
#include <config.h>
-#include <string.h>
#include <glib/gi18n.h>
#include "e-util/e-util.h"
@@ -36,162 +35,30 @@
struct _EMailDisplayPrivate {
EMFormatHTML *formatter;
- GtkUIManager *ui_manager;
- gchar *selected_uri;
};
enum {
PROP_0,
- PROP_ANIMATE,
- PROP_CARET_MODE,
- PROP_FORMATTER,
- PROP_SELECTED_URI
-};
-
-enum {
- POPUP_EVENT,
- STATUS_MESSAGE,
- LAST_SIGNAL
+ PROP_FORMATTER
};
static gpointer parent_class;
-static guint signals[LAST_SIGNAL];
static const gchar *ui =
"<ui>"
" <popup name='context'>"
-" <menuitem action='http-open'/>"
-" <menuitem action='send-message'/>"
-" <menuitem action='uri-copy'/>"
-" <menuitem action='add-to-address-book'/>"
-" <menuitem action='mailto-copy'/>"
-" <menu action='search-folder-menu'>"
-" <menuitem action='search-folder-sender'/>"
-" <menuitem action='search-folder-recipient'/>"
-" </menu>"
+" <placeholder name='custom-actions-1'>"
+" <menuitem action='add-to-address-book'/>"
+" </placeholder>"
+" <placeholder name='custom-actions-3'>"
+" <menu action='search-folder-menu'>"
+" <menuitem action='search-folder-recipient'/>"
+" <menuitem action='search-folder-sender'/>"
+" </menu>"
+" </placeholder>"
" </popup>"
"</ui>";
-static void
-action_add_to_address_book_cb (GtkAction *action,
- EMailDisplay *display)
-{
- CamelURL *curl;
- const gchar *uri;
- gpointer parent;
-
- parent = gtk_widget_get_toplevel (GTK_WIDGET (display));
- parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
-
- uri = e_mail_display_get_selected_uri (display);
- g_return_if_fail (uri != NULL);
-
- /* This should work because we checked it in update_actions(). */
- curl = camel_url_new (uri, NULL);
- g_return_if_fail (curl != NULL);
-
- if (curl->path != NULL && *curl->path != '\0')
- em_utils_add_address (parent, curl->path);
-
- camel_url_free (curl);
-}
-
-static void
-action_http_open_cb (GtkAction *action,
- EMailDisplay *display)
-{
- const gchar *uri;
- gpointer parent;
-
- parent = gtk_widget_get_toplevel (GTK_WIDGET (display));
- parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
-
- uri = e_mail_display_get_selected_uri (display);
- g_return_if_fail (uri != NULL);
-
- e_show_uri (parent, uri);
-}
-
-static void
-action_mailto_copy_cb (GtkAction *action,
- EMailDisplay *display)
-{
- CamelURL *curl;
- CamelInternetAddress *inet_addr;
- GtkClipboard *clipboard;
- const gchar *uri;
- gchar *text;
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- uri = e_mail_display_get_selected_uri (display);
- g_return_if_fail (uri != NULL);
-
- /* This should work because we checked it in update_actions(). */
- curl = camel_url_new (uri, NULL);
- g_return_if_fail (curl != NULL);
-
- inet_addr = camel_internet_address_new ();
- camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
- text = camel_address_encode (CAMEL_ADDRESS (inet_addr));
- if (text == NULL || *text == '\0')
- text = g_strdup (uri + strlen ("mailto:"));
-
- camel_object_unref (inet_addr);
- camel_url_free (curl);
-
- gtk_clipboard_set_text (clipboard, text, -1);
- gtk_clipboard_store (clipboard);
-
- g_free (text);
-}
-
-static void
-action_send_message_cb (GtkAction *action,
- EMailDisplay *display)
-{
- const gchar *uri;
-
- uri = e_mail_display_get_selected_uri (display);
- g_return_if_fail (uri != NULL);
-
- em_utils_compose_new_message_with_mailto (uri, NULL);
-}
-
-static void
-action_uri_copy_cb (GtkAction *action,
- EMailDisplay *display)
-{
- GtkClipboard *clipboard;
- const gchar *uri;
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- uri = e_mail_display_get_selected_uri (display);
- g_return_if_fail (uri != NULL);
-
- gtk_clipboard_set_text (clipboard, uri, -1);
- gtk_clipboard_store (clipboard);
-}
-
-static GtkActionEntry uri_entries[] = {
-
- { "uri-copy",
- GTK_STOCK_COPY,
- N_("_Copy Link Location"),
- NULL,
- NULL, /* XXX Add a tooltip! */
- G_CALLBACK (action_uri_copy_cb) },
-};
-
-static GtkActionEntry http_entries[] = {
-
- { "http-open",
- "emblem-web",
- N_("_Open Link in Browser"),
- NULL,
- NULL, /* XXX Add a tooltip! */
- G_CALLBACK (action_http_open_cb) },
-};
-
static GtkActionEntry mailto_entries[] = {
{ "add-to-address-book",
@@ -199,14 +66,7 @@ static GtkActionEntry mailto_entries[] = {
N_("_Add to Address Book..."),
NULL,
NULL, /* XXX Add a tooltip! */
- G_CALLBACK (action_add_to_address_book_cb) },
-
- { "mailto-copy",
- GTK_STOCK_COPY,
- N_("_Copy Email Address"),
- NULL,
- NULL, /* XXX Add a tooltip! */
- G_CALLBACK (action_mailto_copy_cb) },
+ NULL /* Handled by EMailReader */ },
{ "search-folder-recipient",
NULL,
@@ -222,13 +82,6 @@ static GtkActionEntry mailto_entries[] = {
NULL, /* XXX Add a tooltip! */
NULL /* Handled by EMailReader */ },
- { "send-message",
- "mail-message-new",
- N_("_Send New Message To..."),
- NULL,
- NULL, /* XXX Add a tooltip! */
- G_CALLBACK (action_send_message_cb) },
-
/*** Menus ***/
{ "search-folder-menu",
@@ -239,123 +92,6 @@ static GtkActionEntry mailto_entries[] = {
NULL }
};
-static gboolean
-mail_display_emit_popup_event (EMailDisplay *display,
- GdkEventButton *event,
- const gchar *uri,
- EMFormatPURI *puri)
-{
- CamelMimePart *mime_part;
- gboolean stop_handlers = FALSE;
-
- mime_part = (puri != NULL) ? puri->part : NULL;
-
- g_signal_emit (
- display, signals[POPUP_EVENT], 0,
- event, uri, mime_part, &stop_handlers);
-
- return stop_handlers;
-}
-
-static void
-mail_display_emit_status_message (EMailDisplay *display,
- const gchar *status_message)
-{
- g_signal_emit (display, signals[STATUS_MESSAGE], 0, status_message);
-}
-
-static void
-mail_display_get_uri_puri (EMailDisplay *display,
- GdkEventButton *event,
- GtkHTML *html,
- gchar **uri,
- EMFormatPURI **puri)
-{
- EMFormat *formatter;
- gchar *text_uri;
- gchar *image_uri;
- gboolean is_cid;
-
- formatter = EM_FORMAT (display->priv->formatter);
-
- if (event != NULL) {
- text_uri = gtk_html_get_url_at (html, event->x, event->y);
- image_uri = gtk_html_get_image_src_at (html, event->x, event->y);
- } else {
- text_uri = gtk_html_get_cursor_url (html);
- image_uri = gtk_html_get_cursor_image_src (html);
- }
-
- is_cid = (image_uri != NULL) &&
- (g_ascii_strncasecmp (image_uri, "cid:", 4) == 0);
-
- if (image_uri != NULL) {
- if (strstr (image_uri, "://") == NULL && !is_cid) {
- gchar *temp;
-
- temp = g_strconcat ("file://", image_uri, NULL);
- g_free (image_uri);
- image_uri = temp;
- }
- }
-
- if (puri != NULL) {
- if (text_uri != NULL)
- *puri = em_format_find_puri (formatter, text_uri);
-
- if (*puri == NULL && image_uri != NULL)
- *puri = em_format_find_puri (formatter, image_uri);
- }
-
- if (uri != NULL) {
- *uri = NULL;
- if (is_cid) {
- if (text_uri != NULL)
- *uri = g_strdup_printf (
- "%s\n%s", text_uri, image_uri);
- else {
- *uri = image_uri;
- image_uri = NULL;
- }
- } else {
- *uri = text_uri;
- text_uri = NULL;
- }
- }
-
- g_free (text_uri);
- g_free (image_uri);
-}
-
-static gboolean
-mail_display_button_press_event_cb (EMailDisplay *display,
- GdkEventButton *event,
- GtkHTML *html)
-{
- EMFormatPURI *puri = NULL;
- gboolean finished = TRUE;
- gchar *uri = NULL;
-
- /* The GtkHTML object may be the EMailDisplay itself
- * or an inner iframe. */
-
- if (event->button != 3)
- return FALSE;
-
- mail_display_get_uri_puri (display, event, html, &uri, &puri);
-
- if (uri == NULL || g_str_has_prefix (uri, "##")) {
- g_free (uri);
- return FALSE;
- }
-
- finished = mail_display_emit_popup_event (display, event, uri, puri);
-
- g_free (uri);
-
- return finished;
-}
-
static void
mail_display_update_formatter_colors (EMailDisplay *display)
{
@@ -404,29 +140,11 @@ mail_display_set_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
- case PROP_ANIMATE:
- e_mail_display_set_animate (
- E_MAIL_DISPLAY (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_CARET_MODE:
- e_mail_display_set_caret_mode (
- E_MAIL_DISPLAY (object),
- g_value_get_boolean (value));
- return;
-
case PROP_FORMATTER:
e_mail_display_set_formatter (
E_MAIL_DISPLAY (object),
g_value_get_object (value));
return;
-
- case PROP_SELECTED_URI:
- e_mail_display_set_selected_uri (
- E_MAIL_DISPLAY (object),
- g_value_get_string (value));
- return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -439,29 +157,11 @@ mail_display_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
- case PROP_ANIMATE:
- g_value_set_boolean (
- value, e_mail_display_get_animate (
- E_MAIL_DISPLAY (object)));
- return;
-
- case PROP_CARET_MODE:
- g_value_set_boolean (
- value, e_mail_display_get_caret_mode (
- E_MAIL_DISPLAY (object)));
- return;
-
case PROP_FORMATTER:
g_value_set_object (
value, e_mail_display_get_formatter (
E_MAIL_DISPLAY (object)));
return;
-
- case PROP_SELECTED_URI:
- g_value_set_string (
- value, e_mail_display_get_selected_uri (
- E_MAIL_DISPLAY (object)));
- return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -479,11 +179,6 @@ mail_display_dispose (GObject *object)
priv->formatter = NULL;
}
- if (priv->ui_manager) {
- g_object_unref (priv->ui_manager);
- priv->ui_manager = NULL;
- }
-
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -512,39 +207,13 @@ mail_display_style_set (GtkWidget *widget,
em_format_redraw (EM_FORMAT (priv->formatter));
}
-static gboolean
-mail_display_button_press_event (GtkWidget *widget,
- GdkEventButton *event)
-{
- EMailDisplay *display = E_MAIL_DISPLAY (widget);
- GtkHTML *html = GTK_HTML (widget);
-
- if (mail_display_button_press_event_cb (display, event, html))
- return TRUE;
-
- /* Chain up to parent's button_press_event() method. */
- return GTK_WIDGET_CLASS (parent_class)->
- button_press_event (widget, event);
-}
-
-static gboolean
-mail_display_scroll_event (GtkWidget *widget,
- GdkEventScroll *event)
+static void
+mail_display_url_requested (GtkHTML *html,
+ const gchar *uri,
+ GtkHTMLStream *stream)
{
- if (event->state & GDK_CONTROL_MASK) {
- switch (event->direction) {
- case GDK_SCROLL_UP:
- gtk_html_zoom_in (GTK_HTML (widget));
- return TRUE;
- case GDK_SCROLL_DOWN:
- gtk_html_zoom_out (GTK_HTML (widget));
- return TRUE;
- default:
- break;
- }
- }
-
- return FALSE;
+ /* XXX Sadly, we must block the default method
+ * until EMFormatHTML is made asynchronous. */
}
static void
@@ -591,89 +260,12 @@ mail_display_link_clicked (GtkHTML *html,
/* ignore */ ;
else {
- gpointer parent;
-
- parent = gtk_widget_get_toplevel (GTK_WIDGET (html));
- parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
-
- e_show_uri (parent, uri);
+ /* Chain up to parent's link_clicked() method. */
+ GTK_HTML_CLASS (parent_class)->link_clicked (html, uri);
}
}
static void
-mail_display_on_url (GtkHTML *html,
- const gchar *uri)
-{
- EMailDisplay *display;
- CamelInternetAddress *address;
- CamelURL *curl;
- const gchar *format = NULL;
- gchar *message = NULL;
- gchar *who;
-
- display = E_MAIL_DISPLAY (html);
-
- if (uri == NULL || *uri == '\0')
- goto exit;
-
- if (g_str_has_prefix (uri, "mailto:"))
- format = _("Click to mail %s");
- else if (g_str_has_prefix (uri, "callto:"))
- format = _("Click to call %s");
- else if (g_str_has_prefix (uri, "h323:"))
- format = _("Click to call %s");
- else if (g_str_has_prefix (uri, "sip:"))
- format = _("Click to call %s");
- else if (g_str_has_prefix (uri, "##"))
- message = g_strdup (_("Click to hide/unhide addresses"));
- else
- message = g_strdup_printf (_("Click to open %s"), uri);
-
- if (format == NULL)
- goto exit;
-
- curl = camel_url_new (uri, NULL);
- address = camel_internet_address_new ();
- camel_address_decode (CAMEL_ADDRESS (address), curl->path);
- who = camel_address_format (CAMEL_ADDRESS (address));
- camel_object_unref (address);
- camel_url_free (curl);
-
- if (who == NULL)
- who = g_strdup (strchr (uri, ':') + 1);
-
- message = g_strdup_printf (format, who);
-
- g_free (who);
-
-exit:
- mail_display_emit_status_message (display, message);
-
- g_free (message);
-}
-
-static void
-mail_display_iframe_created (GtkHTML *html,
- GtkHTML *iframe)
-{
- g_signal_connect_swapped (
- iframe, "button-press-event",
- G_CALLBACK (mail_display_button_press_event_cb), html);
-}
-
-static gboolean
-mail_display_popup_event (EMailDisplay *display,
- GdkEventButton *event,
- const gchar *uri,
- EMFormatPURI *puri)
-{
- e_mail_display_set_selected_uri (display, uri);
- e_mail_display_show_popup_menu (display, event, NULL, NULL);
-
- return TRUE;
-}
-
-static void
mail_display_class_init (EMailDisplayClass *class)
{
GObjectClass *object_class;
@@ -691,35 +283,10 @@ mail_display_class_init (EMailDisplayClass *class)
widget_class = GTK_WIDGET_CLASS (class);
widget_class->realize = mail_display_realize;
widget_class->style_set = mail_display_style_set;
- widget_class->button_press_event = mail_display_button_press_event;
- widget_class->scroll_event = mail_display_scroll_event;
html_class = GTK_HTML_CLASS (class);
+ html_class->url_requested = mail_display_url_requested;
html_class->link_clicked = mail_display_link_clicked;
- html_class->on_url = mail_display_on_url;
- html_class->iframe_created = mail_display_iframe_created;
-
- class->popup_event = mail_display_popup_event;
-
- g_object_class_install_property (
- object_class,
- PROP_ANIMATE,
- g_param_spec_boolean (
- "animate",
- "Animate Images",
- NULL,
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (
- object_class,
- PROP_CARET_MODE,
- g_param_spec_boolean (
- "caret-mode",
- "Caret Mode",
- NULL,
- FALSE,
- G_PARAM_READWRITE));
g_object_class_install_property (
object_class,
@@ -730,67 +297,27 @@ mail_display_class_init (EMailDisplayClass *class)
NULL,
EM_TYPE_FORMAT_HTML,
G_PARAM_READWRITE));
-
- g_object_class_install_property (
- object_class,
- PROP_SELECTED_URI,
- g_param_spec_string (
- "selected-uri",
- "Selected URI",
- NULL,
- NULL,
- G_PARAM_READWRITE));
-
- signals[POPUP_EVENT] = g_signal_new (
- "popup-event",
- G_TYPE_FROM_CLASS (class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EMailDisplayClass, popup_event),
- g_signal_accumulator_true_handled, NULL,
- e_marshal_BOOLEAN__BOXED_POINTER_POINTER,
- G_TYPE_BOOLEAN, 3,
- GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
- G_TYPE_POINTER,
- G_TYPE_POINTER);
-
- signals[STATUS_MESSAGE] = g_signal_new (
- "status-message",
- G_TYPE_FROM_CLASS (class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMailDisplayClass, status_message),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
}
static void
mail_display_init (EMailDisplay *display)
{
+ EWebView *web_view;
GtkUIManager *ui_manager;
GtkActionGroup *action_group;
- const gchar *id;
GError *error = NULL;
- display->priv = E_MAIL_DISPLAY_GET_PRIVATE (display);
-
- ui_manager = gtk_ui_manager_new ();
- display->priv->ui_manager = ui_manager;
-
- action_group = e_mail_display_add_action_group (display, "uri");
+ web_view = E_WEB_VIEW (display);
- gtk_action_group_add_actions (
- action_group, uri_entries,
- G_N_ELEMENTS (uri_entries), display);
-
- action_group = e_mail_display_add_action_group (display, "http");
-
- gtk_action_group_add_actions (
- action_group, http_entries,
- G_N_ELEMENTS (http_entries), display);
+ display->priv = E_MAIL_DISPLAY_GET_PRIVATE (display);
- action_group = e_mail_display_add_action_group (display, "mailto");
+ /* EWebView's action groups are added during its instance
+ * initialization function (like what we're in now), so it
+ * is safe to fetch them this early in construction. */
+ action_group = e_web_view_get_action_group (web_view, "mailto");
+ /* We don't actually handle the actions we're adding.
+ * EMailReader handles them. How devious is that? */
gtk_action_group_add_actions (
action_group, mailto_entries,
G_N_ELEMENTS (mailto_entries), display);
@@ -798,13 +325,10 @@ mail_display_init (EMailDisplay *display)
/* Because we are loading from a hard-coded string, there is
* no chance of I/O errors. Failure here implies a malformed
* UI definition. Full stop. */
+ ui_manager = e_web_view_get_ui_manager (web_view);
gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
if (error != NULL)
g_error ("%s", error->message);
-
- id = "org.gnome.evolution.mail.display";
- e_plugin_ui_register_manager (ui_manager, id, display);
- e_plugin_ui_enable_manager (ui_manager, id);
}
GType
@@ -827,64 +351,12 @@ e_mail_display_get_type (void)
};
type = g_type_register_static (
- GTK_TYPE_HTML, "EMailDisplay", &type_info, 0);
+ E_TYPE_WEB_VIEW, "EMailDisplay", &type_info, 0);
}
return type;
}
-gboolean
-e_mail_display_get_animate (EMailDisplay *display)
-{
- /* XXX This is just here to maintain symmetry
- * with e_mail_display_set_animate(). */
-
- g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), FALSE);
-
- return gtk_html_get_animate (GTK_HTML (display));
-}
-
-void
-e_mail_display_set_animate (EMailDisplay *display,
- gboolean animate)
-{
- /* XXX GtkHTML does not utilize GObject properties as well
- * as it could. This just wraps gtk_html_set_animate()
- * so we can get a "notify::animate" signal. */
-
- g_return_if_fail (E_IS_MAIL_DISPLAY (display));
-
- gtk_html_set_animate (GTK_HTML (display), animate);
-
- g_object_notify (G_OBJECT (display), "animate");
-}
-
-gboolean
-e_mail_display_get_caret_mode (EMailDisplay *display)
-{
- /* XXX This is just here to maintain symmetry
- * with e_mail_display_set_caret_mode(). */
-
- g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), FALSE);
-
- return gtk_html_get_caret_mode (GTK_HTML (display));
-}
-
-void
-e_mail_display_set_caret_mode (EMailDisplay *display,
- gboolean caret_mode)
-{
- /* XXX GtkHTML does not utilize GObject properties as well
- * as it could. This just wraps gtk_html_set_caret_mode()
- * so we can get a "notify::caret-mode" signal. */
-
- g_return_if_fail (E_IS_MAIL_DISPLAY (display));
-
- gtk_html_set_caret_mode (GTK_HTML (display), caret_mode);
-
- g_object_notify (G_OBJECT (display), "caret-mode");
-}
-
EMFormatHTML *
e_mail_display_get_formatter (EMailDisplay *display)
{
@@ -907,166 +379,3 @@ e_mail_display_set_formatter (EMailDisplay *display,
g_object_notify (G_OBJECT (display), "formatter");
}
-
-const gchar *
-e_mail_display_get_selected_uri (EMailDisplay *display)
-{
- g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
-
- return display->priv->selected_uri;
-}
-
-void
-e_mail_display_set_selected_uri (EMailDisplay *display,
- const gchar *selected_uri)
-{
- g_return_if_fail (E_IS_MAIL_DISPLAY (display));
-
- g_free (display->priv->selected_uri);
- display->priv->selected_uri = g_strdup (selected_uri);
-
- g_object_notify (G_OBJECT (display), "selected-uri");
-}
-
-GtkAction *
-e_mail_display_get_action (EMailDisplay *display,
- const gchar *action_name)
-{
- GtkUIManager *ui_manager;
-
- g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
- g_return_val_if_fail (action_name != NULL, NULL);
-
- ui_manager = e_mail_display_get_ui_manager (display);
-
- return e_lookup_action (ui_manager, action_name);
-}
-
-GtkActionGroup *
-e_mail_display_add_action_group (EMailDisplay *display,
- const gchar *group_name)
-{
- GtkActionGroup *action_group;
- GtkUIManager *ui_manager;
- const gchar *domain;
-
- g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
- g_return_val_if_fail (group_name != NULL, NULL);
-
- ui_manager = e_mail_display_get_ui_manager (display);
- domain = GETTEXT_PACKAGE;
-
- action_group = gtk_action_group_new (group_name);
- gtk_action_group_set_translation_domain (action_group, domain);
- gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
- g_object_unref (action_group);
-
- return action_group;
-}
-
-GtkActionGroup *
-e_mail_display_get_action_group (EMailDisplay *display,
- const gchar *group_name)
-{
- GtkUIManager *ui_manager;
-
- g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
- g_return_val_if_fail (group_name != NULL, NULL);
-
- ui_manager = e_mail_display_get_ui_manager (display);
-
- return e_lookup_action_group (ui_manager, group_name);
-}
-
-GtkWidget *
-e_mail_display_get_popup_menu (EMailDisplay *display)
-{
- GtkUIManager *ui_manager;
- GtkWidget *menu;
-
- g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
-
- ui_manager = e_mail_display_get_ui_manager (display);
- menu = gtk_ui_manager_get_widget (ui_manager, "/context");
- g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
-
- return menu;
-}
-
-GtkUIManager *
-e_mail_display_get_ui_manager (EMailDisplay *display)
-{
- EMailDisplayPrivate *priv;
-
- g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
-
- priv = E_MAIL_DISPLAY_GET_PRIVATE (display);
-
- return priv->ui_manager;
-}
-
-void
-e_mail_display_show_popup_menu (EMailDisplay *display,
- GdkEventButton *event,
- GtkMenuPositionFunc func,
- gpointer user_data)
-{
- GtkWidget *menu;
-
- g_return_if_fail (E_IS_MAIL_DISPLAY (display));
-
- e_mail_display_update_actions (display);
-
- menu = e_mail_display_get_popup_menu (display);
-
- if (event != NULL)
- gtk_menu_popup (
- GTK_MENU (menu), NULL, NULL, func,
- user_data, event->button, event->time);
- else
- gtk_menu_popup (
- GTK_MENU (menu), NULL, NULL, func,
- user_data, 0, gtk_get_current_event_time ());
-}
-
-void
-e_mail_display_update_actions (EMailDisplay *display)
-{
- CamelURL *curl;
- GtkActionGroup *action_group;
- gboolean scheme_is_http;
- gboolean scheme_is_mailto;
- gboolean uri_is_valid;
- gboolean visible;
- const gchar *uri;
-
- g_return_if_fail (E_IS_MAIL_DISPLAY (display));
-
- uri = e_mail_display_get_selected_uri (display);
- g_return_if_fail (uri != NULL);
-
- /* Parse the URI early so we know if the actions will work. */
- curl = camel_url_new (uri, NULL);
- uri_is_valid = (curl != NULL);
- camel_url_free (curl);
-
- scheme_is_http =
- (g_ascii_strncasecmp (uri, "http:", 5) == 0) ||
- (g_ascii_strncasecmp (uri, "https:", 6) == 0);
-
- scheme_is_mailto =
- (g_ascii_strncasecmp (uri, "mailto:", 7) == 0);
-
- /* Allow copying the URI even if it's malformed. */
- visible = !scheme_is_mailto;
- action_group = e_mail_display_get_action_group (display, "uri");
- gtk_action_group_set_visible (action_group, visible);
-
- visible = uri_is_valid && scheme_is_http;
- action_group = e_mail_display_get_action_group (display, "http");
- gtk_action_group_set_visible (action_group, visible);
-
- visible = uri_is_valid && scheme_is_mailto;
- action_group = e_mail_display_get_action_group (display, "mailto");
- gtk_action_group_set_visible (action_group, visible);
-}
diff --git a/mail/e-mail-display.h b/mail/e-mail-display.h
index 9f273fb26f..1b71a9db7f 100644
--- a/mail/e-mail-display.h
+++ b/mail/e-mail-display.h
@@ -22,8 +22,8 @@
#ifndef E_MAIL_DISPLAY_H
#define E_MAIL_DISPLAY_H
-#include <gtkhtml/gtkhtml.h>
#include <mail/em-format-html.h>
+#include <misc/e-web-view.h>
/* Standard GObject macros */
#define E_TYPE_MAIL_DISPLAY \
@@ -51,48 +51,18 @@ typedef struct _EMailDisplayClass EMailDisplayClass;
typedef struct _EMailDisplayPrivate EMailDisplayPrivate;
struct _EMailDisplay {
- GtkHTML parent;
+ EWebView parent;
EMailDisplayPrivate *priv;
};
struct _EMailDisplayClass {
- GtkHTMLClass parent_class;
-
- /* Signals */
- gboolean (*popup_event) (EMailDisplay *display,
- GdkEventButton *event,
- const gchar *uri,
- EMFormatPURI *puri);
- void (*status_message) (EMailDisplay *display,
- const gchar *status_message);
+ EWebViewClass parent_class;
};
GType e_mail_display_get_type (void);
-gboolean e_mail_display_get_animate (EMailDisplay *display);
-void e_mail_display_set_animate (EMailDisplay *display,
- gboolean animate);
-gboolean e_mail_display_get_caret_mode (EMailDisplay *display);
-void e_mail_display_set_caret_mode (EMailDisplay *display,
- gboolean caret_mode);
EMFormatHTML * e_mail_display_get_formatter (EMailDisplay *display);
void e_mail_display_set_formatter (EMailDisplay *display,
EMFormatHTML *formatter);
-const gchar * e_mail_display_get_selected_uri (EMailDisplay *display);
-void e_mail_display_set_selected_uri (EMailDisplay *display,
- const gchar *uri);
-GtkAction * e_mail_display_get_action (EMailDisplay *display,
- const gchar *action_name);
-GtkActionGroup *e_mail_display_add_action_group (EMailDisplay *display,
- const gchar *group_name);
-GtkActionGroup *e_mail_display_get_action_group (EMailDisplay *display,
- const gchar *group_name);
-GtkWidget * e_mail_display_get_popup_menu (EMailDisplay *display);
-GtkUIManager * e_mail_display_get_ui_manager (EMailDisplay *display);
-void e_mail_display_show_popup_menu (EMailDisplay *display,
- GdkEventButton *event,
- GtkMenuPositionFunc func,
- gpointer user_data);
-void e_mail_display_update_actions (EMailDisplay *display);
G_END_DECLS
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
index 72f79181f8..d3a845c125 100644
--- a/mail/e-mail-reader.c
+++ b/mail/e-mail-reader.c
@@ -67,15 +67,16 @@ static void
action_mail_add_sender_cb (GtkAction *action,
EMailReader *reader)
{
+ EShell *shell;
+ EShellBackend *shell_backend;
MessageList *message_list;
CamelMessageInfo *info;
CamelFolder *folder;
- GtkWindow *window;
GPtrArray *uids;
const gchar *address;
message_list = e_mail_reader_get_message_list (reader);
- window = e_mail_reader_get_window (reader);
+ shell_backend = e_mail_reader_get_shell_backend (reader);
folder = message_list->folder;
uids = message_list_get_selected (message_list);
@@ -91,13 +92,52 @@ action_mail_add_sender_cb (GtkAction *action,
if (address == NULL || *address == '\0')
goto exit;
- em_utils_add_address (window, address);
+ /* XXX EBookShellBackend should be listening for this
+ * event. Kind of kludgey, but works for now. */
+ shell = e_shell_backend_get_shell (shell_backend);
+ e_shell_event (shell, "contact-quick-add-email", (gpointer) address);
exit:
em_utils_uids_free (uids);
}
static void
+action_add_to_address_book_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EMFormatHTMLDisplay *html_display;
+ EWebView *web_view;
+ CamelURL *curl;
+ const gchar *uri;
+
+ /* This action is defined in EMailDisplay. */
+
+ html_display = e_mail_reader_get_html_display (reader);
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+
+ web_view = E_WEB_VIEW (EM_FORMAT_HTML (html_display)->html);
+
+ uri = e_web_view_get_selected_uri (web_view);
+ g_return_if_fail (uri != NULL);
+
+ curl = camel_url_new (uri, NULL);
+ g_return_if_fail (curl != NULL);
+
+ if (curl->path == NULL || *curl->path == '\0')
+ goto exit;
+
+ /* XXX EBookShellBackend should be listening for this
+ * event. Kind of kludgey, but works for now. */
+ shell = e_shell_backend_get_shell (shell_backend);
+ e_shell_event (shell, "contact-quick-add-email", curl->path);
+
+exit:
+ camel_url_free (curl);
+}
+
+static void
action_mail_charset_cb (GtkRadioAction *action,
GtkRadioAction *current,
EMailReader *reader)
@@ -955,7 +995,7 @@ action_search_folder_recipient_cb (GtkAction *action,
{
EMFormatHTMLDisplay *html_display;
MessageList *message_list;
- EMailDisplay *display;
+ EWebView *web_view;
CamelURL *curl;
const gchar *uri;
@@ -964,9 +1004,9 @@ action_search_folder_recipient_cb (GtkAction *action,
html_display = e_mail_reader_get_html_display (reader);
message_list = e_mail_reader_get_message_list (reader);
- display = E_MAIL_DISPLAY (EM_FORMAT_HTML (html_display)->html);
+ web_view = E_WEB_VIEW (EM_FORMAT_HTML (html_display)->html);
- uri = e_mail_display_get_selected_uri (display);
+ uri = e_web_view_get_selected_uri (web_view);
g_return_if_fail (uri != NULL);
curl = camel_url_new (uri, NULL);
@@ -996,7 +1036,7 @@ action_search_folder_sender_cb (GtkAction *action,
{
EMFormatHTMLDisplay *html_display;
MessageList *message_list;
- EMailDisplay *display;
+ EWebView *web_view;
CamelURL *curl;
const gchar *uri;
@@ -1005,9 +1045,9 @@ action_search_folder_sender_cb (GtkAction *action,
html_display = e_mail_reader_get_html_display (reader);
message_list = e_mail_reader_get_message_list (reader);
- display = E_MAIL_DISPLAY (EM_FORMAT_HTML (html_display)->html);
+ web_view = E_WEB_VIEW (EM_FORMAT_HTML (html_display)->html);
- uri = e_mail_display_get_selected_uri (display);
+ uri = e_web_view_get_selected_uri (web_view);
g_return_if_fail (uri != NULL);
curl = camel_url_new (uri, NULL);
@@ -2252,7 +2292,7 @@ e_mail_reader_init (EMailReader *reader)
EShellBackend *shell_backend;
EShellSettings *shell_settings;
EMFormatHTMLDisplay *html_display;
- EMailDisplay *display;
+ EWebView *web_view;
GtkActionGroup *action_group;
MessageList *message_list;
GConfBridge *bridge;
@@ -2270,7 +2310,7 @@ e_mail_reader_init (EMailReader *reader)
shell = e_shell_backend_get_shell (shell_backend);
shell_settings = e_shell_get_shell_settings (shell);
- display = E_MAIL_DISPLAY (EM_FORMAT_HTML (html_display)->html);
+ web_view = E_WEB_VIEW (EM_FORMAT_HTML (html_display)->html);
gtk_action_group_add_actions (
action_group, mail_reader_entries,
@@ -2320,14 +2360,20 @@ e_mail_reader_init (EMailReader *reader)
action = e_mail_reader_get_action (reader, action_name);
g_object_set (action, "short-label", _("Reply"), NULL);
+ action_name = "add-to-address-book";
+ action = e_web_view_get_action (web_view, action_name);
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (action_add_to_address_book_cb), reader);
+
action_name = "search-folder-recipient";
- action = e_mail_display_get_action (display, action_name);
+ action = e_web_view_get_action (web_view, action_name);
g_signal_connect (
action, "activate",
G_CALLBACK (action_search_folder_recipient_cb), reader);
action_name = "search-folder-sender";
- action = e_mail_display_get_action (display, action_name);
+ action = e_web_view_get_action (web_view, action_name);
g_signal_connect (
action, "activate",
G_CALLBACK (action_search_folder_sender_cb), reader);
@@ -2350,7 +2396,7 @@ e_mail_reader_init (EMailReader *reader)
e_binding_new (
shell_settings, "mail-show-animated-images",
- display, "animate");
+ web_view, "animate");
e_binding_new (
shell_settings, "mail-show-sender-photo",
@@ -2361,16 +2407,16 @@ e_mail_reader_init (EMailReader *reader)
e_mutual_binding_new (
action, "active",
- display, "caret-mode");
+ web_view, "caret-mode");
/* Connect signals. */
g_signal_connect_swapped (
- display, "button-release-event",
+ web_view, "button-release-event",
G_CALLBACK (mail_reader_button_release_event_cb), reader);
g_signal_connect_swapped (
- display, "key-press-event",
+ web_view, "key-press-event",
G_CALLBACK (mail_reader_key_press_event_cb), reader);
g_signal_connect_swapped (
diff --git a/mail/e-mail-search-bar.c b/mail/e-mail-search-bar.c
index d068eb1123..bfd4270cb9 100644
--- a/mail/e-mail-search-bar.c
+++ b/mail/e-mail-search-bar.c
@@ -32,7 +32,7 @@
((obj), E_TYPE_MAIL_SEARCH_BAR, EMailSearchBarPrivate))
struct _EMailSearchBarPrivate {
- GtkHTML *html;
+ EWebView *web_view;
GtkWidget *entry;
GtkWidget *case_sensitive_button;
GtkWidget *wrapped_next_box;
@@ -48,8 +48,8 @@ struct _EMailSearchBarPrivate {
enum {
PROP_0,
PROP_CASE_SENSITIVE,
- PROP_HTML,
- PROP_TEXT
+ PROP_TEXT,
+ PROP_WEB_VIEW
};
enum {
@@ -108,14 +108,14 @@ static void
mail_search_bar_find (EMailSearchBar *search_bar,
gboolean search_forward)
{
- GtkHTML *html;
+ EWebView *web_view;
GtkWidget *widget;
gboolean case_sensitive;
gboolean new_search;
gboolean wrapped = FALSE;
gchar *text;
- html = e_mail_search_bar_get_html (search_bar);
+ web_view = e_mail_search_bar_get_web_view (search_bar);
case_sensitive = e_mail_search_bar_get_case_sensitive (search_bar);
text = e_mail_search_bar_get_text (search_bar);
@@ -146,20 +146,23 @@ mail_search_bar_find (EMailSearchBar *search_bar,
mail_search_bar_update_tokenizer (search_bar);
} else if (search_bar->priv->rerun_search) {
gtk_html_engine_search (
- html, search_bar->priv->active_search,
+ GTK_HTML (web_view),
+ search_bar->priv->active_search,
case_sensitive, search_forward, FALSE);
search_bar->priv->rerun_search = FALSE;
g_free (text);
} else {
- gtk_html_engine_search_set_forward (html, search_forward);
- if (!gtk_html_engine_search_next (html))
+ gtk_html_engine_search_set_forward (
+ GTK_HTML (web_view), search_forward);
+ if (!gtk_html_engine_search_next (GTK_HTML (web_view)))
wrapped = TRUE;
g_free (text);
}
if (new_search || wrapped)
gtk_html_engine_search (
- html, search_bar->priv->active_search,
+ GTK_HTML (web_view),
+ search_bar->priv->active_search,
case_sensitive, search_forward, FALSE);
/* Update wrapped label visibility. */
@@ -218,15 +221,17 @@ mail_search_bar_toggled_cb (EMailSearchBar *search_bar)
}
static void
-mail_search_bar_set_html (EMailSearchBar *search_bar,
- GtkHTML *html)
+mail_search_bar_set_web_view (EMailSearchBar *search_bar,
+ EWebView *web_view)
{
+ GtkHTML *html;
ESearchingTokenizer *tokenizer;
- g_return_if_fail (search_bar->priv->html == NULL);
+ g_return_if_fail (search_bar->priv->web_view == NULL);
- search_bar->priv->html = g_object_ref (html);
+ search_bar->priv->web_view = g_object_ref (web_view);
+ html = GTK_HTML (web_view);
tokenizer = e_mail_search_bar_get_tokenizer (search_bar);
gtk_html_set_tokenizer (html, HTML_TOKENIZER (tokenizer));
}
@@ -244,17 +249,17 @@ mail_search_bar_set_property (GObject *object,
g_value_get_boolean (value));
return;
- case PROP_HTML:
- mail_search_bar_set_html (
- E_MAIL_SEARCH_BAR (object),
- g_value_get_object (value));
- return;
-
case PROP_TEXT:
e_mail_search_bar_set_text (
E_MAIL_SEARCH_BAR (object),
g_value_get_string (value));
return;
+
+ case PROP_WEB_VIEW:
+ mail_search_bar_set_web_view (
+ E_MAIL_SEARCH_BAR (object),
+ g_value_get_object (value));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -273,17 +278,17 @@ mail_search_bar_get_property (GObject *object,
E_MAIL_SEARCH_BAR (object)));
return;
- case PROP_HTML:
- g_value_set_object (
- value, e_mail_search_bar_get_html (
- E_MAIL_SEARCH_BAR (object)));
- return;
-
case PROP_TEXT:
g_value_take_string (
value, e_mail_search_bar_get_text (
E_MAIL_SEARCH_BAR (object)));
return;
+
+ case PROP_WEB_VIEW:
+ g_value_set_object (
+ value, e_mail_search_bar_get_web_view (
+ E_MAIL_SEARCH_BAR (object)));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -296,9 +301,9 @@ mail_search_bar_dispose (GObject *object)
priv = E_MAIL_SEARCH_BAR_GET_PRIVATE (object);
- if (priv->html != NULL) {
- g_object_unref (priv->html);
- priv->html = NULL;
+ if (priv->web_view != NULL) {
+ g_object_unref (priv->web_view);
+ priv->web_view = NULL;
}
if (priv->entry != NULL) {
@@ -450,17 +455,6 @@ mail_search_bar_class_init (EMailSearchBarClass *class)
g_object_class_install_property (
object_class,
- PROP_HTML,
- g_param_spec_object (
- "html",
- "HTML Display",
- NULL,
- GTK_TYPE_HTML,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (
- object_class,
PROP_TEXT,
g_param_spec_string (
"text",
@@ -469,6 +463,17 @@ mail_search_bar_class_init (EMailSearchBarClass *class)
NULL,
G_PARAM_READWRITE));
+ g_object_class_install_property (
+ object_class,
+ PROP_WEB_VIEW,
+ g_param_spec_object (
+ "web-view",
+ "Web View",
+ NULL,
+ E_TYPE_WEB_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
signals[CHANGED] = g_signal_new (
"changed",
G_TYPE_FROM_CLASS (class),
@@ -676,11 +681,12 @@ e_mail_search_bar_get_type (void)
}
GtkWidget *
-e_mail_search_bar_new (GtkHTML *html)
+e_mail_search_bar_new (EWebView *web_view)
{
- g_return_val_if_fail (GTK_IS_HTML (html), NULL);
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
- return g_object_new (E_TYPE_MAIL_SEARCH_BAR, "html", html, NULL);
+ return g_object_new (
+ E_TYPE_MAIL_SEARCH_BAR, "web-view", web_view, NULL);
}
void
@@ -699,12 +705,12 @@ e_mail_search_bar_changed (EMailSearchBar *search_bar)
g_signal_emit (search_bar, signals[CHANGED], 0);
}
-GtkHTML *
-e_mail_search_bar_get_html (EMailSearchBar *search_bar)
+EWebView *
+e_mail_search_bar_get_web_view (EMailSearchBar *search_bar)
{
g_return_val_if_fail (E_IS_MAIL_SEARCH_BAR (search_bar), NULL);
- return search_bar->priv->html;
+ return search_bar->priv->web_view;
}
ESearchingTokenizer *
diff --git a/mail/e-mail-search-bar.h b/mail/e-mail-search-bar.h
index f4748c77ad..1ad343777b 100644
--- a/mail/e-mail-search-bar.h
+++ b/mail/e-mail-search-bar.h
@@ -23,8 +23,8 @@
#define E_MAIL_SEARCH_BAR_H
#include <gtk/gtk.h>
-#include <gtkhtml/gtkhtml.h>
#include <mail/e-searching-tokenizer.h>
+#include <misc/e-web-view.h>
/* Standard GObject macros */
#define E_TYPE_MAIL_SEARCH_BAR \
@@ -65,10 +65,10 @@ struct _EMailSearchBarClass {
};
GType e_mail_search_bar_get_type (void);
-GtkWidget * e_mail_search_bar_new (GtkHTML *html);
+GtkWidget * e_mail_search_bar_new (EWebView *web_view);
void e_mail_search_bar_clear (EMailSearchBar *search_bar);
void e_mail_search_bar_changed (EMailSearchBar *search_bar);
-GtkHTML * e_mail_search_bar_get_html (EMailSearchBar *search_bar);
+EWebView * e_mail_search_bar_get_web_view (EMailSearchBar *search_bar);
ESearchingTokenizer *
e_mail_search_bar_get_tokenizer (EMailSearchBar *search_bar);
gboolean e_mail_search_bar_get_case_sensitive
diff --git a/mail/em-utils.c b/mail/em-utils.c
index 0a55ea842d..4ee9110ae5 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -48,10 +48,6 @@
#include "em-filter-editor.h"
-#include <bonobo/bonobo-listener.h>
-#include <bonobo/bonobo-widget.h>
-#include <bonobo/bonobo-event-source.h>
-
#include <glib/gi18n.h>
#include <gio/gio.h>
@@ -661,94 +657,6 @@ em_utils_save_messages (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids)
}
/* ********************************************************************** */
-
-static void
-emu_add_address_cb(BonoboListener *listener, const gchar *name, const CORBA_any *any, CORBA_Environment *ev, gpointer data)
-{
- gchar *type = bonobo_event_subtype(name);
-
- if (!strcmp(type, "Destroy"))
- gtk_widget_destroy((GtkWidget *)data);
-
- g_free(type);
-}
-
-/* one of email or vcard should be always NULL, never both of them */
-static void
-emu_add_address_or_vcard (GtkWindow *parent, const gchar *email, const gchar *vcard)
-{
- GtkWidget *win;
- GtkWidget *control;
- /*GtkWidget *socket;*/
- gchar *email_buf = NULL;
-
- if (email) {
- CamelInternetAddress *cia;
-
- cia = camel_internet_address_new ();
- if (camel_address_decode ((CamelAddress *) cia, email) == -1) {
- camel_object_unref (cia);
- return;
- }
-
- email_buf = camel_address_format ((CamelAddress *) cia);
- camel_object_unref (cia);
- }
-
- win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title((GtkWindow *)win, _("Add address"));
-
- gtk_window_set_transient_for ((GtkWindow *)win, parent);
-
- gtk_window_set_position((GtkWindow *)win, GTK_WIN_POS_CENTER_ON_PARENT);
- gtk_window_set_type_hint((GtkWindow *)win, GDK_WINDOW_TYPE_HINT_DIALOG);
-
- control = bonobo_widget_new_control("OAFIID:GNOME_Evolution_Addressbook_AddressPopup:" BASE_VERSION, CORBA_OBJECT_NIL);
-
- if (email_buf)
- bonobo_widget_set_property ((BonoboWidget *) control, "email", TC_CORBA_string, email_buf, NULL);
- else
- bonobo_widget_set_property ((BonoboWidget *) control, "vcard", TC_CORBA_string, vcard, NULL);
-
- g_free (email_buf);
-
- bonobo_event_source_client_add_listener(bonobo_widget_get_objref((BonoboWidget *)control), emu_add_address_cb, NULL, NULL, win);
-
- /*socket = find_socket (GTK_CONTAINER (control));
- g_object_weak_ref ((GObject *) socket, (GWeakNotify) gtk_widget_destroy, win);*/
-
- gtk_container_add((GtkContainer *)win, control);
- gtk_widget_show_all(win);
-}
-
-/**
- * em_utils_add_address:
- * @parent:
- * @email:
- *
- * Add address @email to the addressbook.
- **/
-void
-em_utils_add_address (GtkWindow *parent, const gchar *email)
-{
- g_return_if_fail (GTK_IS_WINDOW (parent));
-
- emu_add_address_or_vcard (parent, email, NULL);
-}
-
-/**
- * em_utils_add_vcard:
- * Adds whole vCard to the addressbook.
- **/
-void
-em_utils_add_vcard (GtkWindow *parent, const gchar *vcard)
-{
- g_return_if_fail (GTK_IS_WINDOW (parent));
-
- emu_add_address_or_vcard (parent, NULL, vcard);
-}
-
-/* ********************************************************************** */
/* Flag-for-Followup... */
/**
diff --git a/mail/em-utils.h b/mail/em-utils.h
index 14dc8cef23..e1064c520a 100644
--- a/mail/em-utils.h
+++ b/mail/em-utils.h
@@ -56,9 +56,6 @@ void em_utils_save_part(GtkWindow *parent, const gchar *prompt, CamelMimePart *p
gboolean em_utils_save_part_to_file(GtkWindow *parent, const gchar *filename, CamelMimePart *part);
void em_utils_save_messages (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids);
-void em_utils_add_address(GtkWindow *parent, const gchar *email);
-void em_utils_add_vcard(GtkWindow *parent, const gchar *vcard);
-
void em_utils_flag_for_followup (EMailReader *reader, CamelFolder *folder, GPtrArray *uids);
void em_utils_flag_for_followup_clear (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids);
void em_utils_flag_for_followup_completed (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids);
diff --git a/modules/addressbook/e-book-shell-backend.c b/modules/addressbook/e-book-shell-backend.c
index 243ce3a848..a14b3bad16 100644
--- a/modules/addressbook/e-book-shell-backend.c
+++ b/modules/addressbook/e-book-shell-backend.c
@@ -37,6 +37,7 @@
#include "addressbook/gui/widgets/eab-gui-util.h"
#include "addressbook/gui/contact-editor/e-contact-editor.h"
+#include "addressbook/gui/contact-editor/e-contact-quick-add.h"
#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
#include "addressbook/importers/evolution-addressbook-importers.h"
@@ -379,6 +380,26 @@ book_shell_backend_init_preferences (EShell *shell)
return FALSE;
}
+static void
+book_shell_backend_quick_add_email_cb (EShell *shell,
+ const gchar *email)
+{
+ /* XXX This is an ugly hack but it's the only way I could think
+ * of to integrate this feature with other shell modules. */
+
+ e_contact_quick_add_free_form (email, NULL, NULL);
+}
+
+static void
+book_shell_backend_quick_add_vcard_cb (EShell *shell,
+ const gchar *vcard)
+{
+ /* XXX This is an ugly hack but it's the only way I could think
+ * of to integrate this feature with other shell modules. */
+
+ e_contact_quick_add_vcard (vcard, NULL, NULL);
+}
+
static gboolean
book_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
const gchar *uri)
@@ -518,6 +539,14 @@ book_shell_backend_constructed (GObject *object)
book_shell_backend_init_importers ();
book_shell_backend_ensure_sources (shell_backend);
+ g_signal_connect (
+ shell, "event::contact-quick-add-email",
+ G_CALLBACK (book_shell_backend_quick_add_email_cb), NULL);
+
+ g_signal_connect_swapped (
+ shell, "event::contact-quick-add-vcard",
+ G_CALLBACK (book_shell_backend_quick_add_vcard_cb), NULL);
+
g_signal_connect_swapped (
shell, "handle-uri",
G_CALLBACK (book_shell_backend_handle_uri_cb),
diff --git a/modules/calendar/e-memo-shell-content.c b/modules/calendar/e-memo-shell-content.c
index 027beec1cd..0e8d73bbe5 100644
--- a/modules/calendar/e-memo-shell-content.c
+++ b/modules/calendar/e-memo-shell-content.c
@@ -200,7 +200,7 @@ memo_shell_content_cursor_change_cb (EMemoShellContent *memo_shell_content,
memo_preview = e_memo_shell_content_get_memo_preview (memo_shell_content);
if (e_table_selected_count (table) != 1) {
- e_cal_component_preview_clear (memo_preview);
+ e_web_view_clear (E_WEB_VIEW (memo_preview));
return;
}
@@ -231,7 +231,7 @@ memo_shell_content_selection_change_cb (EMemoShellContent *memo_shell_content,
/* XXX Old code emits a "selection-changed" signal here. */
if (e_table_selected_count (table) != 1)
- e_cal_component_preview_clear (memo_preview);
+ e_web_view_clear (E_WEB_VIEW (memo_preview));
}
static void
@@ -391,6 +391,7 @@ memo_shell_content_constructed (GObject *object)
EShellSettings *shell_settings;
EShellBackend *shell_backend;
EShellContent *shell_content;
+ EShellTaskbar *shell_taskbar;
GalViewInstance *view_instance;
icaltimezone *timezone;
ETable *table;
@@ -407,6 +408,7 @@ memo_shell_content_constructed (GObject *object)
shell_content = E_SHELL_CONTENT (object);
shell_view = e_shell_content_get_shell_view (shell_content);
shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell_taskbar = e_shell_view_get_shell_taskbar (shell_view);
shell = e_shell_backend_get_shell (shell_backend);
shell_settings = e_shell_get_shell_settings (shell);
@@ -458,6 +460,11 @@ memo_shell_content_constructed (GObject *object)
priv->memo_preview = g_object_ref (widget);
gtk_widget_show (widget);
+ g_signal_connect_swapped (
+ widget, "status-message",
+ G_CALLBACK (e_shell_taskbar_set_message),
+ shell_taskbar);
+
/* Configure the memo table. */
widget = E_MEMO_TABLE (priv->memo_table)->etable;
diff --git a/modules/calendar/e-memo-shell-view-actions.c b/modules/calendar/e-memo-shell-view-actions.c
index 99761b2c74..463e01f71b 100644
--- a/modules/calendar/e-memo-shell-view-actions.c
+++ b/modules/calendar/e-memo-shell-view-actions.c
@@ -97,7 +97,7 @@ action_memo_delete_cb (GtkAction *action,
e_memo_table_delete_selected (memo_table);
e_memo_shell_view_set_status_message (memo_shell_view, NULL, -1.0);
- e_cal_component_preview_clear (memo_preview);
+ e_web_view_clear (E_WEB_VIEW (memo_preview));
}
static void
diff --git a/modules/calendar/e-memo-shell-view-private.c b/modules/calendar/e-memo-shell-view-private.c
index 0a96d29664..f1d331fab3 100644
--- a/modules/calendar/e-memo-shell-view-private.c
+++ b/modules/calendar/e-memo-shell-view-private.c
@@ -24,24 +24,6 @@
#include "widgets/menus/gal-view-factory-etable.h"
static void
-memo_shell_view_preview_on_url_cb (EShellView *shell_view,
- const gchar *url)
-{
- EShellTaskbar *shell_taskbar;
- gchar *message;
-
- shell_taskbar = e_shell_view_get_shell_taskbar (shell_view);
-
- if (url == NULL || *url == '\0')
- e_shell_taskbar_set_message (shell_taskbar, NULL);
- else {
- message = g_strdup_printf (_("Click to open %s"), url);
- e_shell_taskbar_set_message (shell_taskbar, message);
- g_free (message);
- }
-}
-
-static void
memo_shell_view_table_popup_event_cb (EShellView *shell_view,
GdkEventButton *event)
{
@@ -189,7 +171,6 @@ e_memo_shell_view_private_constructed (EMemoShellView *memo_shell_view)
EShellContent *shell_content;
EShellSidebar *shell_sidebar;
EShellWindow *shell_window;
- ECalComponentPreview *memo_preview;
EMemoTable *memo_table;
ECalModel *model;
ETable *table;
@@ -210,7 +191,6 @@ e_memo_shell_view_private_constructed (EMemoShellView *memo_shell_view)
priv->memo_shell_sidebar = g_object_ref (shell_sidebar);
memo_shell_content = E_MEMO_SHELL_CONTENT (shell_content);
- memo_preview = e_memo_shell_content_get_memo_preview (memo_shell_content);
memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
model = e_memo_table_get_model (memo_table);
table = e_memo_table_get_table (memo_table);
@@ -224,11 +204,6 @@ e_memo_shell_view_private_constructed (EMemoShellView *memo_shell_view)
memo_shell_view);
g_signal_connect_swapped (
- memo_preview, "on-url",
- G_CALLBACK (memo_shell_view_preview_on_url_cb),
- memo_shell_view);
-
- g_signal_connect_swapped (
memo_table, "open-component",
G_CALLBACK (e_memo_shell_view_open_memo),
memo_shell_view);
diff --git a/modules/calendar/e-memo-shell-view.c b/modules/calendar/e-memo-shell-view.c
index 54dea9c444..ea869b55c4 100644
--- a/modules/calendar/e-memo-shell-view.c
+++ b/modules/calendar/e-memo-shell-view.c
@@ -151,7 +151,7 @@ memo_shell_view_execute_search (EShellView *shell_view)
memo_preview =
e_memo_shell_content_get_memo_preview (memo_shell_content);
- e_cal_component_preview_clear (memo_preview);
+ e_web_view_clear (E_WEB_VIEW (memo_preview));
}
static void
diff --git a/modules/calendar/e-task-shell-content.c b/modules/calendar/e-task-shell-content.c
index f78f142d60..8dea4b840b 100644
--- a/modules/calendar/e-task-shell-content.c
+++ b/modules/calendar/e-task-shell-content.c
@@ -201,7 +201,7 @@ task_shell_content_cursor_change_cb (ETaskShellContent *task_shell_content,
task_preview = e_task_shell_content_get_task_preview (task_shell_content);
if (e_table_selected_count (table) != 1) {
- e_cal_component_preview_clear (task_preview);
+ e_web_view_clear (E_WEB_VIEW (task_preview));
return;
}
@@ -230,7 +230,7 @@ task_shell_content_selection_change_cb (ETaskShellContent *task_shell_content,
task_preview = e_task_shell_content_get_task_preview (task_shell_content);
if (e_table_selected_count (table) != 1)
- e_cal_component_preview_clear (task_preview);
+ e_web_view_clear (E_WEB_VIEW (task_preview));
}
static void
@@ -388,6 +388,7 @@ task_shell_content_constructed (GObject *object)
EShell *shell;
EShellSettings *shell_settings;
EShellContent *shell_content;
+ EShellTaskbar *shell_taskbar;
EShellWindow *shell_window;
EShellView *shell_view;
GalViewInstance *view_instance;
@@ -405,6 +406,7 @@ task_shell_content_constructed (GObject *object)
shell_content = E_SHELL_CONTENT (object);
shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_taskbar = e_shell_view_get_shell_taskbar (shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
shell = e_shell_window_get_shell (shell_window);
shell_settings = e_shell_get_shell_settings (shell);
@@ -456,6 +458,11 @@ task_shell_content_constructed (GObject *object)
priv->task_preview = g_object_ref (widget);
gtk_widget_show (widget);
+ g_signal_connect_swapped (
+ widget, "status-message",
+ G_CALLBACK (e_shell_taskbar_set_message),
+ shell_taskbar);
+
/* Configure the task table. */
widget = E_CALENDAR_TABLE (priv->task_table)->etable;
diff --git a/modules/calendar/e-task-shell-view-actions.c b/modules/calendar/e-task-shell-view-actions.c
index 7833873832..2592df2481 100644
--- a/modules/calendar/e-task-shell-view-actions.c
+++ b/modules/calendar/e-task-shell-view-actions.c
@@ -128,7 +128,7 @@ action_task_delete_cb (GtkAction *action,
e_calendar_table_delete_selected (task_table);
e_task_shell_view_set_status_message (task_shell_view, NULL, -1.0);
- e_cal_component_preview_clear (task_preview);
+ e_web_view_clear (E_WEB_VIEW (task_preview));
}
static void
diff --git a/modules/calendar/e-task-shell-view-private.c b/modules/calendar/e-task-shell-view-private.c
index 380d54ef3d..581ad88b47 100644
--- a/modules/calendar/e-task-shell-view-private.c
+++ b/modules/calendar/e-task-shell-view-private.c
@@ -47,24 +47,6 @@ task_shell_view_process_completed_tasks (ETaskShellView *task_shell_view)
}
static void
-task_shell_view_preview_on_url_cb (EShellView *shell_view,
- const gchar *url)
-{
- EShellTaskbar *shell_taskbar;
- gchar *message;
-
- shell_taskbar = e_shell_view_get_shell_taskbar (shell_view);
-
- if (url == NULL || *url == '\0')
- e_shell_taskbar_set_message (shell_taskbar, NULL);
- else {
- message = g_strdup_printf (_("Click to open %s"), url);
- e_shell_taskbar_set_message (shell_taskbar, message);
- g_free (message);
- }
-}
-
-static void
task_shell_view_table_popup_event_cb (EShellView *shell_view,
GdkEventButton *event)
{
@@ -235,10 +217,10 @@ e_task_shell_view_private_constructed (ETaskShellView *task_shell_view)
EShellView *shell_view;
EShellBackend *shell_backend;
EShellContent *shell_content;
- EShellSettings *shell_settings;
EShellSidebar *shell_sidebar;
+ EShellTaskbar *shell_taskbar;
+ EShellSettings *shell_settings;
EShellWindow *shell_window;
- ECalComponentPreview *task_preview;
ECalendarTable *task_table;
ECalModel *model;
ETable *table;
@@ -248,6 +230,7 @@ e_task_shell_view_private_constructed (ETaskShellView *task_shell_view)
shell_backend = e_shell_view_get_shell_backend (shell_view);
shell_content = e_shell_view_get_shell_content (shell_view);
shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ shell_taskbar = e_shell_view_get_shell_taskbar (shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
shell = e_shell_window_get_shell (shell_window);
@@ -262,7 +245,6 @@ e_task_shell_view_private_constructed (ETaskShellView *task_shell_view)
priv->task_shell_sidebar = g_object_ref (shell_sidebar);
task_shell_content = E_TASK_SHELL_CONTENT (shell_content);
- task_preview = e_task_shell_content_get_task_preview (task_shell_content);
task_table = e_task_shell_content_get_task_table (task_shell_content);
model = e_calendar_table_get_model (task_table);
table = e_calendar_table_get_table (task_table);
@@ -276,11 +258,6 @@ e_task_shell_view_private_constructed (ETaskShellView *task_shell_view)
task_shell_view);
g_signal_connect_swapped (
- task_preview, "on-url",
- G_CALLBACK (task_shell_view_preview_on_url_cb),
- task_shell_view);
-
- g_signal_connect_swapped (
task_table, "open-component",
G_CALLBACK (e_task_shell_view_open_task),
task_shell_view);
diff --git a/modules/calendar/e-task-shell-view.c b/modules/calendar/e-task-shell-view.c
index 7237b1cddd..650037b730 100644
--- a/modules/calendar/e-task-shell-view.c
+++ b/modules/calendar/e-task-shell-view.c
@@ -263,7 +263,7 @@ task_shell_view_execute_search (EShellView *shell_view)
task_preview =
e_task_shell_content_get_task_preview (task_shell_content);
- e_cal_component_preview_clear (task_preview);
+ e_web_view_clear (E_WEB_VIEW (task_preview));
}
static void
diff --git a/modules/mail/e-mail-shell-content.c b/modules/mail/e-mail-shell-content.c
index ac740fb6c5..60ddde7727 100644
--- a/modules/mail/e-mail-shell-content.c
+++ b/modules/mail/e-mail-shell-content.c
@@ -438,7 +438,7 @@ mail_shell_content_constructed (GObject *object)
GConfBridge *bridge;
GtkWidget *container;
GtkWidget *widget;
- GtkHTML *html;
+ EWebView *web_view;
GalViewCollection *view_collection;
const gchar *key;
@@ -454,7 +454,7 @@ mail_shell_content_constructed (GObject *object)
shell_backend = e_shell_view_get_shell_backend (shell_view);
view_collection = shell_view_class->view_collection;
- html = EM_FORMAT_HTML (priv->html_display)->html;
+ web_view = E_WEB_VIEW (EM_FORMAT_HTML (priv->html_display)->html);
/* Build content widgets. */
@@ -492,12 +492,12 @@ mail_shell_content_constructed (GObject *object)
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (
GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (html));
+ gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (web_view));
gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
- gtk_widget_show (GTK_WIDGET (html));
+ gtk_widget_show (GTK_WIDGET (web_view));
gtk_widget_show (widget);
- widget = e_mail_search_bar_new (html);
+ widget = e_mail_search_bar_new (web_view);
gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
priv->search_bar = g_object_ref (widget);
gtk_widget_hide (widget);
diff --git a/modules/mail/e-mail-shell-view-actions.c b/modules/mail/e-mail-shell-view-actions.c
index adb288d8fb..9c79164a35 100644
--- a/modules/mail/e-mail-shell-view-actions.c
+++ b/modules/mail/e-mail-shell-view-actions.c
@@ -681,7 +681,7 @@ action_mail_smart_backward_cb (GtkAction *action,
html = EM_FORMAT_HTML (html_display)->html;
- if (gtk_html_command (html, "scroll-backward"))
+ if (e_web_view_scroll_backward (E_WEB_VIEW (html)))
return;
if (caret_mode || !magic_spacebar)
@@ -744,7 +744,7 @@ action_mail_smart_forward_cb (GtkAction *action,
html = EM_FORMAT_HTML (html_display)->html;
- if (gtk_html_command (html, "scroll-forward"))
+ if (e_web_view_scroll_forward (E_WEB_VIEW (html)))
return;
if (caret_mode || !magic_spacebar)
diff --git a/modules/mail/e-mail-shell-view-private.h b/modules/mail/e-mail-shell-view-private.h
index 30724b26b5..5c52e1251c 100644
--- a/modules/mail/e-mail-shell-view-private.h
+++ b/modules/mail/e-mail-shell-view-private.h
@@ -36,6 +36,7 @@
#include "e-util/gconf-bridge.h"
#include "e-util/e-account-utils.h"
#include "filter/filter-part.h"
+#include "widgets/misc/e-web-view.h"
#include "widgets/misc/e-popup-action.h"
#include "widgets/menus/gal-view-instance.h"
diff --git a/plugins/vcard-inline/Makefile.am b/plugins/vcard-inline/Makefile.am
index dd8f92fd1a..a1267507ae 100644
--- a/plugins/vcard-inline/Makefile.am
+++ b/plugins/vcard-inline/Makefile.am
@@ -6,8 +6,9 @@ NO_UNDEFINED_REQUIRED_LIBS = \
endif
AM_CPPFLAGS = \
- -I$(top_srcdir) \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ $(EVOLUTION_ADDRESSBOOK_CFLAGS) \
$(EVOLUTION_MAIL_CFLAGS)
@EVO_PLUGIN_RULE@
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5d6310101e..ec74fd86e5 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -387,9 +387,9 @@ plugins/mail-notification/mail-notification.c
plugins/mail-notification/org-gnome-mail-notification.eplug.xml
plugins/mail-to-task/mail-to-task.c
plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml
+plugins/mailing-list-actions/mailing-list-actions.c
plugins/mailing-list-actions/org-gnome-mailing-list-actions.eplug.xml
plugins/mailing-list-actions/org-gnome-mailing-list-actions.error.xml
-plugins/mailing-list-actions/org-gnome-mailing-list-actions.xml
plugins/mark-all-read/mark-all-read.c
plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml
plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml
@@ -505,6 +505,7 @@ widgets/misc/e-signature-editor.c
widgets/misc/e-signature-manager.c
widgets/misc/e-signature-script-dialog.c
widgets/misc/e-url-entry.c
+widgets/misc/e-web-view.c
widgets/misc/ea-calendar-item.c
widgets/table/e-cell-combo.c
widgets/table/e-cell-date-edit.c
diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c
index f580b1aa4e..0bfa17c0cc 100644
--- a/shell/e-shell-view.c
+++ b/shell/e-shell-view.c
@@ -401,6 +401,12 @@ shell_view_constructed (GObject *object)
/* Invoke factory methods. */
+ /* Create the taskbar widget first so the content and
+ * sidebar widgets can access it during construction. */
+ widget = shell_view_class->new_shell_taskbar (shell_view);
+ shell_view->priv->shell_taskbar = g_object_ref_sink (widget);
+ gtk_widget_show (widget);
+
widget = shell_view_class->new_shell_content (shell_view);
shell_view->priv->shell_content = g_object_ref_sink (widget);
gtk_widget_show (widget);
@@ -409,10 +415,6 @@ shell_view_constructed (GObject *object)
shell_view->priv->shell_sidebar = g_object_ref_sink (widget);
gtk_widget_show (widget);
- widget = shell_view_class->new_shell_taskbar (shell_view);
- shell_view->priv->shell_taskbar = g_object_ref_sink (widget);
- gtk_widget_show (widget);
-
/* Size group should be safe to unreference now. */
g_object_unref (shell_view->priv->size_group);
shell_view->priv->size_group = NULL;
diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c
index 2cf24ba061..2934a82730 100644
--- a/shell/e-shell-window-private.c
+++ b/shell/e-shell-window-private.c
@@ -107,23 +107,20 @@ shell_window_init_switcher_style (EShellWindow *shell_window)
static void
shell_window_menu_item_select_cb (EShellWindow *shell_window,
- GtkWidget *menu_item)
+ GtkWidget *widget)
{
GtkAction *action;
GtkLabel *label;
- gchar *tooltip = NULL;
+ const gchar *tooltip;
- action = g_object_get_data (G_OBJECT (menu_item), "action");
- g_return_if_fail (GTK_IS_ACTION (action));
-
- g_object_get (action, "tooltip", &tooltip, NULL);
+ action = gtk_widget_get_action (widget);
+ tooltip = gtk_action_get_tooltip (action);
if (tooltip == NULL)
return;
label = GTK_LABEL (shell_window->priv->tooltip_label);
gtk_label_set_text (label, tooltip);
- g_free (tooltip);
gtk_widget_show (shell_window->priv->tooltip_label);
gtk_widget_hide (shell_window->priv->status_notebook);
@@ -144,11 +141,6 @@ shell_window_connect_proxy_cb (EShellWindow *shell_window,
if (!GTK_IS_MENU_ITEM (proxy))
return;
- g_object_set_data_full (
- G_OBJECT (proxy),
- "action", g_object_ref (action),
- (GDestroyNotify) g_object_unref);
-
g_signal_connect_swapped (
proxy, "select",
G_CALLBACK (shell_window_menu_item_select_cb),
diff --git a/shell/e-shell.c b/shell/e-shell.c
index d2a82675ae..bf664649fc 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -371,7 +371,7 @@ shell_load_modules (EShell *shell)
}
}
-/* Helper for shell_process_backend() */
+/* Helper for shell_add_backend() */
static void
shell_split_and_insert_items (GHashTable *hash_table,
const gchar *items,
@@ -392,14 +392,17 @@ shell_split_and_insert_items (GHashTable *hash_table,
}
static void
-shell_process_backend (EShell *shell,
- EShellBackend *shell_backend)
+shell_add_backend (GType type,
+ EShell *shell)
{
EShellBackendClass *class;
+ EShellBackend *shell_backend;
GHashTable *backends_by_name;
GHashTable *backends_by_scheme;
const gchar *string;
+ shell_backend = g_object_new (type, "shell", shell, NULL);
+
shell->priv->loaded_backends = g_list_insert_sorted (
shell->priv->loaded_backends, shell_backend,
(GCompareFunc) e_shell_backend_compare);
@@ -425,26 +428,6 @@ shell_process_backend (EShell *shell,
}
static void
-shell_create_backends (EShell *shell)
-{
- GType *children;
- guint ii, n_children;
-
- /* Create an instance of each EShellBackend subclass. */
- children = g_type_children (E_TYPE_SHELL_BACKEND, &n_children);
-
- for (ii = 0; ii < n_children; ii++) {
- EShellBackend *shell_backend;
- GType type = children[ii];
-
- shell_backend = g_object_new (type, "shell", shell, NULL);
- shell_process_backend (shell, shell_backend);
- }
-
- g_free (children);
-}
-
-static void
shell_sm_quit_requested_cb (EShell *shell,
EggSMClient *sm_client)
{
@@ -596,7 +579,10 @@ shell_constructed (GObject *object)
e_file_lock_create ();
shell_load_modules (E_SHELL (object));
- shell_create_backends (E_SHELL (object));
+
+ e_type_traverse (
+ E_TYPE_SHELL_BACKEND, (ETypeFunc)
+ shell_add_backend, object);
}
static gboolean
diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am
index 29607758e5..91906b0448 100644
--- a/widgets/misc/Makefile.am
+++ b/widgets/misc/Makefile.am
@@ -86,6 +86,7 @@ widgetsinclude_HEADERS = \
e-spinner.h \
e-timeout-activity.h \
e-url-entry.h \
+ e-web-view.h \
ea-calendar-cell.h \
ea-calendar-item.h \
ea-cell-table.h \
@@ -148,6 +149,7 @@ libemiscwidgets_la_SOURCES = \
e-signature-tree-view.c \
e-timeout-activity.c \
e-url-entry.c \
+ e-web-view.c \
ea-calendar-cell.c \
ea-calendar-item.c \
ea-cell-table.c \
diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c
index 17a2b6c9b4..cd5301a987 100644
--- a/widgets/misc/e-attachment-view.c
+++ b/widgets/misc/e-attachment-view.c
@@ -682,12 +682,30 @@ attachment_view_update_actions (EAttachmentView *view)
}
static void
+attachment_view_add_handler (GType type,
+ EAttachmentView *view)
+{
+ EAttachmentViewPrivate *priv;
+ EAttachmentHandler *handler;
+ const GtkTargetEntry *targets;
+ guint n_targets;
+
+ priv = e_attachment_view_get_private (view);
+
+ handler = g_object_new (type, "view", view, NULL);
+
+ targets = e_attachment_handler_get_target_table (handler, &n_targets);
+ gtk_target_list_add_table (priv->target_list, targets, n_targets);
+ priv->drag_actions = e_attachment_handler_get_drag_actions (handler);
+
+ g_ptr_array_add (priv->handlers, handler);
+}
+
+static void
attachment_view_init_handlers (EAttachmentView *view)
{
EAttachmentViewPrivate *priv;
GtkTargetList *target_list;
- GType *children;
- guint ii;
priv = e_attachment_view_get_private (view);
@@ -700,25 +718,9 @@ attachment_view_init_handlers (EAttachmentView *view)
priv->target_list = target_list;
priv->drag_actions = GDK_ACTION_COPY;
- children = g_type_children (E_TYPE_ATTACHMENT_HANDLER, NULL);
-
- for (ii = 0; children[ii] != G_TYPE_INVALID; ii++) {
- EAttachmentHandler *handler;
- const GtkTargetEntry *targets;
- guint n_targets;
-
- handler = g_object_new (children[ii], "view", view, NULL);
-
- targets = e_attachment_handler_get_target_table (
- handler, &n_targets);
- gtk_target_list_add_table (target_list, targets, n_targets);
- priv->drag_actions |=
- e_attachment_handler_get_drag_actions (handler);
-
- g_ptr_array_add (priv->handlers, handler);
- }
-
- g_free (children);
+ e_type_traverse (
+ E_TYPE_ATTACHMENT_HANDLER, (ETypeFunc)
+ attachment_view_add_handler, view);
}
static void
diff --git a/widgets/misc/e-signature-preview.c b/widgets/misc/e-signature-preview.c
index bbef65f39c..a9316e44ec 100644
--- a/widgets/misc/e-signature-preview.c
+++ b/widgets/misc/e-signature-preview.c
@@ -113,56 +113,17 @@ signature_preview_dispose (GObject *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;
+ EWebView *web_view;
ESignature *signature;
const gchar *filename;
gboolean is_script;
gchar *content = NULL;
- gsize length;
/* XXX We should show error messages in the preview. */
- html = GTK_HTML (preview);
+ web_view = E_WEB_VIEW (preview);
signature = e_signature_preview_get_signature (preview);
if (signature == NULL)
@@ -182,27 +143,23 @@ signature_preview_refresh (ESignaturePreview *preview)
if (content == NULL || *content == '\0')
goto clear;
- length = strlen (content);
-
if (e_signature_get_is_html (signature))
- gtk_html_load_from_string (html, content, length);
+ e_web_view_load_string (web_view, content);
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);
+ gchar *string;
+
+ string = g_strdup_printf ("<PRE>%s</PRE>", content);
+ e_web_view_load_string (web_view, string);
+ g_free (string);
}
g_free (content);
+
return;
clear:
- gtk_html_load_from_string (html, " ", 1);
+ e_web_view_clear (web_view);
+
g_free (content);
}
@@ -210,7 +167,6 @@ 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));
@@ -220,9 +176,6 @@ signature_preview_class_init (ESignaturePreviewClass *class)
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 (
@@ -282,7 +235,7 @@ e_signature_preview_get_type (void)
};
type = g_type_register_static (
- GTK_TYPE_HTML, "ESignaturePreview", &type_info, 0);
+ E_TYPE_WEB_VIEW, "ESignaturePreview", &type_info, 0);
}
return type;
diff --git a/widgets/misc/e-signature-preview.h b/widgets/misc/e-signature-preview.h
index a4221832c2..d0d5c22eff 100644
--- a/widgets/misc/e-signature-preview.h
+++ b/widgets/misc/e-signature-preview.h
@@ -22,8 +22,8 @@
#ifndef E_SIGNATURE_PREVIEW_H
#define E_SIGNATURE_PREVIEW_H
-#include <gtkhtml/gtkhtml.h>
#include <e-util/e-signature.h>
+#include <misc/e-web-view.h>
/* Standard GObject macros */
#define E_TYPE_SIGNATURE_PREVIEW \
@@ -51,12 +51,12 @@ typedef struct _ESignaturePreviewClass ESignaturePreviewClass;
typedef struct _ESignaturePreviewPrivate ESignaturePreviewPrivate;
struct _ESignaturePreview {
- GtkHTML parent;
+ EWebView parent;
ESignaturePreviewPrivate *priv;
};
struct _ESignaturePreviewClass {
- GtkHTMLClass parent_class;
+ EWebViewClass parent_class;
/* Signals */
void (*refresh) (ESignaturePreview *preview);
diff --git a/widgets/misc/e-web-view.c b/widgets/misc/e-web-view.c
new file mode 100644
index 0000000000..a49fd22527
--- /dev/null
+++ b/widgets/misc/e-web-view.c
@@ -0,0 +1,1110 @@
+/*
+ * e-web-view.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-web-view.h"
+
+#include <config.h>
+#include <string.h>
+#include <glib/gi18n-lib.h>
+
+#include <camel/camel-internet-address.h>
+#include <camel/camel-url.h>
+
+#include "e-util/e-util.h"
+#include "e-util/e-plugin-ui.h"
+
+#define E_WEB_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_WEB_VIEW, EWebViewPrivate))
+
+typedef struct _EWebViewRequest EWebViewRequest;
+
+struct _EWebViewPrivate {
+ GList *requests;
+ GtkUIManager *ui_manager;
+ gchar *selected_uri;
+};
+
+struct _EWebViewRequest {
+ GFile *file;
+ EWebView *web_view;
+ GCancellable *cancellable;
+ GInputStream *input_stream;
+ GtkHTMLStream *output_stream;
+ gchar buffer[4096];
+};
+
+enum {
+ PROP_0,
+ PROP_ANIMATE,
+ PROP_CARET_MODE,
+ PROP_SELECTED_URI
+};
+
+enum {
+ POPUP_EVENT,
+ STATUS_MESSAGE,
+ STOP_LOADING,
+ UPDATE_ACTIONS,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static const gchar *ui =
+"<ui>"
+" <popup name='context'>"
+" <placeholder name='custom-actions-1'>"
+" <menuitem action='http-open'/>"
+" <menuitem action='send-message'/>"
+" </placeholder>"
+" <placeholder name='custom-actions-2'>"
+" <menuitem action='uri-copy'/>"
+" <menuitem action='mailto-copy'/>"
+" </placeholder>"
+" <placeholder name='custom-actions-3'/>"
+" </popup>"
+"</ui>";
+
+static EWebViewRequest *
+web_view_request_new (EWebView *web_view,
+ const gchar *uri,
+ GtkHTMLStream *stream)
+{
+ EWebViewRequest *request;
+ GList *list;
+
+ request = g_slice_new (EWebViewRequest);
+
+ /* Try to detect file paths posing as URIs. */
+ if (*uri == '/')
+ request->file = g_file_new_for_path (uri);
+ else
+ request->file = g_file_new_for_uri (uri);
+
+ request->web_view = g_object_ref (web_view);
+ request->cancellable = g_cancellable_new ();
+ request->input_stream = NULL;
+ request->output_stream = stream;
+
+ list = request->web_view->priv->requests;
+ list = g_list_prepend (list, request);
+ request->web_view->priv->requests = list;
+
+ return request;
+}
+
+static void
+web_view_request_free (EWebViewRequest *request)
+{
+ GList *list;
+
+ list = request->web_view->priv->requests;
+ list = g_list_remove (list, request);
+ request->web_view->priv->requests = list;
+
+ g_object_unref (request->file);
+ g_object_unref (request->web_view);
+ g_object_unref (request->cancellable);
+
+ if (request->input_stream != NULL)
+ g_object_unref (request->input_stream);
+
+ g_slice_free (EWebViewRequest, request);
+}
+
+static void
+web_view_request_cancel (EWebViewRequest *request)
+{
+ g_cancellable_cancel (request->cancellable);
+}
+
+static gboolean
+web_view_request_check_for_error (EWebViewRequest *request,
+ GError *error)
+{
+ GtkHTML *html;
+ GtkHTMLStream *stream;
+
+ if (error == NULL)
+ return FALSE;
+
+ /* XXX Should we log errors that are not cancellations? */
+
+ html = GTK_HTML (request->web_view);
+ stream = request->output_stream;
+
+ gtk_html_end (html, stream, GTK_HTML_STREAM_ERROR);
+ web_view_request_free (request);
+ g_error_free (error);
+
+ return TRUE;
+}
+
+static void
+web_view_request_stream_read_cb (GInputStream *input_stream,
+ GAsyncResult *result,
+ EWebViewRequest *request)
+{
+ GtkHTML *html;
+ gssize bytes_read;
+ GError *error = NULL;
+
+ html = GTK_HTML (request->web_view);
+ bytes_read = g_input_stream_read_finish (input_stream, result, &error);
+
+ if (web_view_request_check_for_error (request, error))
+ return;
+
+ if (bytes_read == 0) {
+ gtk_html_end (
+ GTK_HTML (request->web_view),
+ request->output_stream, GTK_HTML_STREAM_OK);
+ web_view_request_free (request);
+ return;
+ }
+
+ gtk_html_write (
+ GTK_HTML (request->web_view),
+ request->output_stream, request->buffer, bytes_read);
+
+ g_input_stream_read_async (
+ request->input_stream, request->buffer,
+ sizeof (request->buffer), G_PRIORITY_DEFAULT,
+ request->cancellable, (GAsyncReadyCallback)
+ web_view_request_stream_read_cb, request);
+}
+
+static void
+web_view_request_read_cb (GFile *file,
+ GAsyncResult *result,
+ EWebViewRequest *request)
+{
+ GFileInputStream *input_stream;
+ GError *error = NULL;
+
+ /* Input stream might be NULL, so don't use cast macro. */
+ input_stream = g_file_read_finish (file, result, &error);
+ request->input_stream = (GInputStream *) input_stream;
+
+ if (web_view_request_check_for_error (request, error))
+ return;
+
+ g_input_stream_read_async (
+ request->input_stream, request->buffer,
+ sizeof (request->buffer), G_PRIORITY_DEFAULT,
+ request->cancellable, (GAsyncReadyCallback)
+ web_view_request_stream_read_cb, request);
+}
+
+static void
+action_http_open_cb (GtkAction *action,
+ EWebView *web_view)
+{
+ const gchar *uri;
+ gpointer parent;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ uri = e_web_view_get_selected_uri (web_view);
+ g_return_if_fail (uri != NULL);
+
+ e_show_uri (parent, uri);
+}
+
+static void
+action_mailto_copy_cb (GtkAction *action,
+ EWebView *web_view)
+{
+ CamelURL *curl;
+ CamelInternetAddress *inet_addr;
+ GtkClipboard *clipboard;
+ const gchar *uri;
+ gchar *text;
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ uri = e_web_view_get_selected_uri (web_view);
+ g_return_if_fail (uri != NULL);
+
+ /* This should work because we checked it in update_actions(). */
+ curl = camel_url_new (uri, NULL);
+ g_return_if_fail (curl != NULL);
+
+ inet_addr = camel_internet_address_new ();
+ camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
+ text = camel_address_encode (CAMEL_ADDRESS (inet_addr));
+ if (text == NULL || *text == '\0')
+ text = g_strdup (uri + strlen ("mailto:"));
+
+ camel_object_unref (inet_addr);
+ camel_url_free (curl);
+
+ gtk_clipboard_set_text (clipboard, text, -1);
+ gtk_clipboard_store (clipboard);
+
+ g_free (text);
+}
+
+static void
+action_send_message_cb (GtkAction *action,
+ EWebView *web_view)
+{
+ const gchar *uri;
+ gpointer parent;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ uri = e_web_view_get_selected_uri (web_view);
+ g_return_if_fail (uri != NULL);
+
+ e_show_uri (parent, uri);
+}
+
+static void
+action_uri_copy_cb (GtkAction *action,
+ EWebView *web_view)
+{
+ GtkClipboard *clipboard;
+ const gchar *uri;
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ uri = e_web_view_get_selected_uri (web_view);
+ g_return_if_fail (uri != NULL);
+
+ gtk_clipboard_set_text (clipboard, uri, -1);
+ gtk_clipboard_store (clipboard);
+}
+
+static GtkActionEntry uri_entries[] = {
+
+ { "uri-copy",
+ GTK_STOCK_COPY,
+ N_("_Copy Link Location"),
+ NULL,
+ N_("Copy the link to the clipboard"),
+ G_CALLBACK (action_uri_copy_cb) }
+};
+
+static GtkActionEntry http_entries[] = {
+
+ { "http-open",
+ "emblem-web",
+ N_("_Open Link in Browser"),
+ NULL,
+ N_("Open the link in a web browser"),
+ G_CALLBACK (action_http_open_cb) }
+};
+
+static GtkActionEntry mailto_entries[] = {
+
+ { "mailto-copy",
+ GTK_STOCK_COPY,
+ N_("_Copy Email Address"),
+ NULL,
+ N_("Copy the email address to the clipboard"),
+ G_CALLBACK (action_mailto_copy_cb) },
+
+ { "send-message",
+ "mail-message-new",
+ N_("_Send New Message To..."),
+ NULL,
+ N_("Send a mail message to this address"),
+ G_CALLBACK (action_send_message_cb) }
+};
+
+static gboolean
+web_view_button_press_event_cb (EWebView *web_view,
+ GdkEventButton *event,
+ GtkHTML *frame)
+{
+ gboolean event_handled = FALSE;
+ gchar *uri;
+
+ if (event != NULL && event->button != 3)
+ return FALSE;
+
+ uri = e_web_view_extract_uri (web_view, event, frame);
+
+ if (uri == NULL || g_str_has_prefix (uri, "##")) {
+ g_free (uri);
+ return FALSE;
+ }
+
+ g_signal_emit (
+ web_view, signals[POPUP_EVENT], 0,
+ event, uri, &event_handled);
+
+ g_free (uri);
+
+ return event_handled;
+}
+
+static void
+web_view_menu_item_select_cb (EWebView *web_view,
+ GtkWidget *widget)
+{
+ GtkAction *action;
+ const gchar *tooltip;
+
+ action = gtk_widget_get_action (widget);
+ tooltip = gtk_action_get_tooltip (action);
+
+ if (tooltip == NULL)
+ return;
+
+ e_web_view_status_message (web_view, tooltip);
+}
+
+static void
+web_view_menu_item_deselect_cb (EWebView *web_view)
+{
+ e_web_view_status_message (web_view, NULL);
+}
+
+static void
+web_view_connect_proxy_cb (EWebView *web_view,
+ GtkAction *action,
+ GtkWidget *proxy)
+{
+ if (!GTK_IS_MENU_ITEM (proxy))
+ return;
+
+ g_signal_connect_swapped (
+ proxy, "select",
+ G_CALLBACK (web_view_menu_item_select_cb), web_view);
+
+ g_signal_connect_swapped (
+ proxy, "deselect",
+ G_CALLBACK (web_view_menu_item_deselect_cb), web_view);
+}
+
+static void
+web_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ANIMATE:
+ e_web_view_set_animate (
+ E_WEB_VIEW (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_CARET_MODE:
+ e_web_view_set_caret_mode (
+ E_WEB_VIEW (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SELECTED_URI:
+ e_web_view_set_selected_uri (
+ E_WEB_VIEW (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+web_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ANIMATE:
+ g_value_set_boolean (
+ value, e_web_view_get_animate (
+ E_WEB_VIEW (object)));
+ return;
+
+ case PROP_CARET_MODE:
+ g_value_set_boolean (
+ value, e_web_view_get_caret_mode (
+ E_WEB_VIEW (object)));
+ return;
+
+ case PROP_SELECTED_URI:
+ g_value_set_string (
+ value, e_web_view_get_selected_uri (
+ E_WEB_VIEW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+web_view_dispose (GObject *object)
+{
+ EWebViewPrivate *priv;
+
+ priv = E_WEB_VIEW_GET_PRIVATE (object);
+
+ if (priv->ui_manager != NULL) {
+ g_object_unref (priv->ui_manager);
+ priv->ui_manager = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+web_view_finalize (GObject *object)
+{
+ EWebViewPrivate *priv;
+
+ priv = E_WEB_VIEW_GET_PRIVATE (object);
+
+ /* All URI requests should be complete or cancelled by now. */
+ if (priv->requests != NULL)
+ g_warning ("Finalizing EWebView with active URI requests");
+
+ g_free (priv->selected_uri);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gboolean
+web_view_button_press_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GtkWidgetClass *widget_class;
+ EWebView *web_view;
+
+ web_view = E_WEB_VIEW (widget);
+
+ if (web_view_button_press_event_cb (web_view, event, NULL))
+ return TRUE;
+
+ /* Chain up to parent's button_press_event() method. */
+ widget_class = GTK_WIDGET_CLASS (parent_class);
+ return widget_class->button_press_event (widget, event);
+}
+
+static gboolean
+web_view_scroll_event (GtkWidget *widget,
+ GdkEventScroll *event)
+{
+ if (event->state & GDK_CONTROL_MASK) {
+ switch (event->direction) {
+ case GDK_SCROLL_UP:
+ gtk_html_zoom_in (GTK_HTML (widget));
+ return TRUE;
+ case GDK_SCROLL_DOWN:
+ gtk_html_zoom_out (GTK_HTML (widget));
+ return TRUE;
+ default:
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+web_view_url_requested (GtkHTML *html,
+ const gchar *uri,
+ GtkHTMLStream *stream)
+{
+ EWebViewRequest *request;
+
+ request = web_view_request_new (E_WEB_VIEW (html), uri, stream);
+
+ g_file_read_async (
+ request->file, G_PRIORITY_DEFAULT,
+ request->cancellable, (GAsyncReadyCallback)
+ web_view_request_read_cb, request);
+}
+
+static void
+web_view_link_clicked (GtkHTML *html,
+ const gchar *uri)
+{
+ gpointer parent;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (html));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ e_show_uri (parent, uri);
+}
+
+static void
+web_view_on_url (GtkHTML *html,
+ const gchar *uri)
+{
+ EWebView *web_view;
+ CamelInternetAddress *address;
+ CamelURL *curl;
+ const gchar *format = NULL;
+ gchar *message = NULL;
+ gchar *who;
+
+ web_view = E_WEB_VIEW (html);
+
+ if (uri == NULL || *uri == '\0')
+ goto exit;
+
+ if (g_str_has_prefix (uri, "mailto:"))
+ format = _("Click to mail %s");
+ else if (g_str_has_prefix (uri, "callto:"))
+ format = _("Click to call %s");
+ else if (g_str_has_prefix (uri, "h323:"))
+ format = _("Click to call %s");
+ else if (g_str_has_prefix (uri, "sip:"))
+ format = _("Click to call %s");
+ else if (g_str_has_prefix (uri, "##"))
+ message = g_strdup (_("Click to hide/unhide addresses"));
+ else
+ message = g_strdup_printf (_("Click to open %s"), uri);
+
+ if (format == NULL)
+ goto exit;
+
+ /* XXX Use something other than Camel here. Surely
+ * there's other APIs around that can do this. */
+ curl = camel_url_new (uri, NULL);
+ address = camel_internet_address_new ();
+ camel_address_decode (CAMEL_ADDRESS (address), curl->path);
+ who = camel_address_format (CAMEL_ADDRESS (address));
+ camel_object_unref (address);
+ camel_url_free (curl);
+
+ if (who == NULL)
+ who = g_strdup (strchr (uri, ':') + 1);
+
+ message = g_strdup_printf (format, who);
+
+ g_free (who);
+
+exit:
+ e_web_view_status_message (web_view, message);
+
+ g_free (message);
+}
+
+static void
+web_view_iframe_created (GtkHTML *html,
+ GtkHTML *iframe)
+{
+ g_signal_connect_swapped (
+ iframe, "button-press-event",
+ G_CALLBACK (web_view_button_press_event_cb), html);
+}
+
+static gchar *
+web_view_extract_uri (EWebView *web_view,
+ GdkEventButton *event,
+ GtkHTML *html)
+{
+ gchar *uri;
+
+ if (event != NULL)
+ uri = gtk_html_get_url_at (html, event->x, event->y);
+ else
+ uri = gtk_html_get_cursor_url (html);
+
+ return uri;
+}
+
+static gboolean
+web_view_popup_event (EWebView *web_view,
+ GdkEventButton *event,
+ const gchar *uri)
+{
+ e_web_view_set_selected_uri (web_view, uri);
+ e_web_view_show_popup_menu (web_view, event, NULL, NULL);
+
+ return TRUE;
+}
+
+static void
+web_view_stop_loading (EWebView *web_view)
+{
+ g_list_foreach (
+ web_view->priv->requests, (GFunc)
+ web_view_request_cancel, NULL);
+
+ gtk_html_stop (GTK_HTML (web_view));
+}
+
+static void
+web_view_update_actions (EWebView *web_view)
+{
+ CamelURL *curl;
+ GtkActionGroup *action_group;
+ gboolean scheme_is_http;
+ gboolean scheme_is_mailto;
+ gboolean uri_is_valid;
+ gboolean visible;
+ const gchar *uri;
+
+ uri = e_web_view_get_selected_uri (web_view);
+ g_return_if_fail (uri != NULL);
+
+ /* Parse the URI early so we know if the actions will work. */
+ curl = camel_url_new (uri, NULL);
+ uri_is_valid = (curl != NULL);
+ camel_url_free (curl);
+
+ scheme_is_http =
+ (g_ascii_strncasecmp (uri, "http:", 5) == 0) ||
+ (g_ascii_strncasecmp (uri, "https:", 6) == 0);
+
+ scheme_is_mailto =
+ (g_ascii_strncasecmp (uri, "mailto:", 7) == 0);
+
+ /* Allow copying the URI even if it's malformed. */
+ visible = !scheme_is_mailto;
+ action_group = e_web_view_get_action_group (web_view, "uri");
+ gtk_action_group_set_visible (action_group, visible);
+
+ visible = uri_is_valid && scheme_is_http;
+ action_group = e_web_view_get_action_group (web_view, "http");
+ gtk_action_group_set_visible (action_group, visible);
+
+ visible = uri_is_valid && scheme_is_mailto;
+ action_group = e_web_view_get_action_group (web_view, "mailto");
+ gtk_action_group_set_visible (action_group, visible);
+}
+
+static void
+web_view_class_init (EWebViewClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkHTMLClass *html_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EWebViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = web_view_set_property;
+ object_class->get_property = web_view_get_property;
+ object_class->dispose = web_view_dispose;
+ object_class->finalize = web_view_finalize;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->button_press_event = web_view_button_press_event;
+ widget_class->scroll_event = web_view_scroll_event;
+
+ html_class = GTK_HTML_CLASS (class);
+ html_class->url_requested = web_view_url_requested;
+ html_class->link_clicked = web_view_link_clicked;
+ html_class->on_url = web_view_on_url;
+ html_class->iframe_created = web_view_iframe_created;
+
+ class->extract_uri = web_view_extract_uri;
+ class->popup_event = web_view_popup_event;
+ class->stop_loading = web_view_stop_loading;
+ class->update_actions = web_view_update_actions;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ANIMATE,
+ g_param_spec_boolean (
+ "animate",
+ "Animate Images",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CARET_MODE,
+ g_param_spec_boolean (
+ "caret-mode",
+ "Caret Mode",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTED_URI,
+ g_param_spec_string (
+ "selected-uri",
+ "Selected URI",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ signals[POPUP_EVENT] = g_signal_new (
+ "popup-event",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EWebViewClass, popup_event),
+ g_signal_accumulator_true_handled, NULL,
+ e_marshal_BOOLEAN__BOXED_STRING,
+ G_TYPE_BOOLEAN, 2,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
+ G_TYPE_STRING);
+
+ signals[STATUS_MESSAGE] = g_signal_new (
+ "status-message",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EWebViewClass, status_message),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[STOP_LOADING] = g_signal_new (
+ "stop-loading",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EWebViewClass, stop_loading),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[UPDATE_ACTIONS] = g_signal_new (
+ "update-actions",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EWebViewClass, update_actions),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+web_view_init (EWebView *web_view)
+{
+ GtkUIManager *ui_manager;
+ GtkActionGroup *action_group;
+ const gchar *domain = GETTEXT_PACKAGE;
+ const gchar *id;
+ GError *error = NULL;
+
+ web_view->priv = E_WEB_VIEW_GET_PRIVATE (web_view);
+
+ ui_manager = gtk_ui_manager_new ();
+ web_view->priv->ui_manager = ui_manager;
+
+ g_signal_connect_swapped (
+ ui_manager, "connect-proxy",
+ G_CALLBACK (web_view_connect_proxy_cb), web_view);
+
+ action_group = gtk_action_group_new ("uri");
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+ g_object_unref (action_group);
+
+ gtk_action_group_add_actions (
+ action_group, uri_entries,
+ G_N_ELEMENTS (uri_entries), web_view);
+
+ action_group = gtk_action_group_new ("http");
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+ g_object_unref (action_group);
+
+ gtk_action_group_add_actions (
+ action_group, http_entries,
+ G_N_ELEMENTS (http_entries), web_view);
+
+ action_group = gtk_action_group_new ("mailto");
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+ g_object_unref (action_group);
+
+ gtk_action_group_add_actions (
+ action_group, mailto_entries,
+ G_N_ELEMENTS (mailto_entries), web_view);
+
+ /* Because we are loading from a hard-coded string, there is
+ * no chance of I/O errors. Failure here implies a malformed
+ * UI definition. Full stop. */
+ gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
+ if (error != NULL)
+ g_error ("%s", error->message);
+
+ id = "org.gnome.evolution.webview";
+ e_plugin_ui_register_manager (ui_manager, id, web_view);
+ e_plugin_ui_enable_manager (ui_manager, id);
+}
+
+GType
+e_web_view_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EWebViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) web_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EWebView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) web_view_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_HTML, "EWebView", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_web_view_new (void)
+{
+ return g_object_new (E_TYPE_WEB_VIEW, NULL);
+}
+
+void
+e_web_view_clear (EWebView *web_view)
+{
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ gtk_html_load_empty (GTK_HTML (web_view));
+}
+
+void
+e_web_view_load_string (EWebView *web_view,
+ const gchar *string)
+{
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ if (string != NULL && *string != '\0')
+ gtk_html_load_from_string (GTK_HTML (web_view), string, -1);
+ else
+ e_web_view_clear (web_view);
+}
+
+gboolean
+e_web_view_get_animate (EWebView *web_view)
+{
+ /* XXX This is just here to maintain symmetry
+ * with e_web_view_set_animate(). */
+
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE);
+
+ return gtk_html_get_animate (GTK_HTML (web_view));
+}
+
+void
+e_web_view_set_animate (EWebView *web_view,
+ gboolean animate)
+{
+ /* XXX GtkHTML does not utilize GObject properties as well
+ * as it could. This just wraps gtk_html_set_animate()
+ * so we can get a "notify::animate" signal. */
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ gtk_html_set_animate (GTK_HTML (web_view), animate);
+
+ g_object_notify (G_OBJECT (web_view), "animate");
+}
+
+gboolean
+e_web_view_get_caret_mode (EWebView *web_view)
+{
+ /* XXX This is just here to maintain symmetry
+ * with e_web_view_set_caret_mode(). */
+
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE);
+
+ return gtk_html_get_caret_mode (GTK_HTML (web_view));
+}
+
+void
+e_web_view_set_caret_mode (EWebView *web_view,
+ gboolean caret_mode)
+{
+ /* XXX GtkHTML does not utilize GObject properties as well
+ * as it could. This just wraps gtk_html_set_caret_mode()
+ * so we can get a "notify::caret-mode" signal. */
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ gtk_html_set_caret_mode (GTK_HTML (web_view), caret_mode);
+
+ g_object_notify (G_OBJECT (web_view), "caret-mode");
+}
+
+const gchar *
+e_web_view_get_selected_uri (EWebView *web_view)
+{
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+
+ return web_view->priv->selected_uri;
+}
+
+void
+e_web_view_set_selected_uri (EWebView *web_view,
+ const gchar *selected_uri)
+{
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ g_free (web_view->priv->selected_uri);
+ web_view->priv->selected_uri = g_strdup (selected_uri);
+
+ g_object_notify (G_OBJECT (web_view), "selected-uri");
+}
+
+GtkAction *
+e_web_view_get_action (EWebView *web_view,
+ const gchar *action_name)
+{
+ GtkUIManager *ui_manager;
+
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+ g_return_val_if_fail (action_name != NULL, NULL);
+
+ ui_manager = e_web_view_get_ui_manager (web_view);
+
+ return e_lookup_action (ui_manager, action_name);
+}
+
+GtkActionGroup *
+e_web_view_get_action_group (EWebView *web_view,
+ const gchar *group_name)
+{
+ GtkUIManager *ui_manager;
+
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+
+ ui_manager = e_web_view_get_ui_manager (web_view);
+
+ return e_lookup_action_group (ui_manager, group_name);
+}
+
+gchar *
+e_web_view_extract_uri (EWebView *web_view,
+ GdkEventButton *event,
+ GtkHTML *frame)
+{
+ EWebViewClass *class;
+
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+
+ if (frame == NULL)
+ frame = GTK_HTML (web_view);
+
+ class = E_WEB_VIEW_GET_CLASS (web_view);
+ g_return_val_if_fail (class->extract_uri != NULL, NULL);
+
+ return class->extract_uri (web_view, event, frame);
+}
+
+gboolean
+e_web_view_scroll_forward (EWebView *web_view)
+{
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE);
+
+ return gtk_html_command (GTK_HTML (web_view), "scroll-forward");
+}
+
+gboolean
+e_web_view_scroll_backward (EWebView *web_view)
+{
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE);
+
+ return gtk_html_command (GTK_HTML (web_view), "scroll-backward");
+}
+
+GtkUIManager *
+e_web_view_get_ui_manager (EWebView *web_view)
+{
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+
+ return web_view->priv->ui_manager;
+}
+
+GtkWidget *
+e_web_view_get_popup_menu (EWebView *web_view)
+{
+ GtkUIManager *ui_manager;
+ GtkWidget *menu;
+
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+
+ ui_manager = e_web_view_get_ui_manager (web_view);
+ menu = gtk_ui_manager_get_widget (ui_manager, "/context");
+ g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
+
+ return menu;
+}
+
+void
+e_web_view_show_popup_menu (EWebView *web_view,
+ GdkEventButton *event,
+ GtkMenuPositionFunc func,
+ gpointer user_data)
+{
+ GtkWidget *menu;
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ e_web_view_update_actions (web_view);
+
+ menu = e_web_view_get_popup_menu (web_view);
+
+ if (event != NULL)
+ gtk_menu_popup (
+ GTK_MENU (menu), NULL, NULL, func,
+ user_data, event->button, event->time);
+ else
+ gtk_menu_popup (
+ GTK_MENU (menu), NULL, NULL, func,
+ user_data, 0, gtk_get_current_event_time ());
+}
+
+void
+e_web_view_status_message (EWebView *web_view,
+ const gchar *status_message)
+{
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ g_signal_emit (web_view, signals[STATUS_MESSAGE], 0, status_message);
+}
+
+void
+e_web_view_stop_loading (EWebView *web_view)
+{
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ g_signal_emit (web_view, signals[STOP_LOADING], 0);
+}
+
+void
+e_web_view_update_actions (EWebView *web_view)
+{
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ g_signal_emit (web_view, signals[UPDATE_ACTIONS], 0);
+}
diff --git a/widgets/misc/e-web-view.h b/widgets/misc/e-web-view.h
new file mode 100644
index 0000000000..3bce2b4887
--- /dev/null
+++ b/widgets/misc/e-web-view.h
@@ -0,0 +1,119 @@
+/*
+ * e-web-view.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)
+ *
+ */
+
+/* This is intended to serve as a common base class for all HTML viewing
+ * needs in Evolution. Currently based on GtkHTML, the idea is to wrap
+ * the GtkHTML API enough that we no longer have to make direct calls to
+ * it. This should help smooth the transition to WebKit/GTK+.
+ *
+ * This class handles basic tasks like mouse hovers over links, clicked
+ * links, and servicing URI requests asynchronously via GIO. */
+
+#ifndef E_WEB_VIEW_H
+#define E_WEB_VIEW_H
+
+#include <gtkhtml/gtkhtml.h>
+
+/* Standard GObject macros */
+#define E_TYPE_WEB_VIEW \
+ (e_web_view_get_type ())
+#define E_WEB_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_WEB_VIEW, EWebView))
+#define E_WEB_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_WEB_VIEW, EWebViewClass))
+#define E_IS_WEB_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_WEB_VIEW))
+#define E_IS_WEB_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_WEB_VIEW))
+#define E_WEB_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_WEB_VIEW, EWebViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EWebView EWebView;
+typedef struct _EWebViewClass EWebViewClass;
+typedef struct _EWebViewPrivate EWebViewPrivate;
+
+struct _EWebView {
+ GtkHTML parent;
+ EWebViewPrivate *priv;
+};
+
+struct _EWebViewClass {
+ GtkHTMLClass parent_class;
+
+ /* Methods */
+ gchar * (*extract_uri) (EWebView *web_view,
+ GdkEventButton *event,
+ GtkHTML *frame);
+
+ /* Signals */
+ gboolean (*popup_event) (EWebView *web_view,
+ GdkEventButton *event,
+ const gchar *uri);
+ void (*status_message) (EWebView *web_view,
+ const gchar *status_message);
+ void (*stop_loading) (EWebView *web_view);
+ void (*update_actions) (EWebView *web_view);
+};
+
+GType e_web_view_get_type (void);
+GtkWidget * e_web_view_new (void);
+void e_web_view_clear (EWebView *web_view);
+void e_web_view_load_string (EWebView *web_view,
+ const gchar *string);
+gboolean e_web_view_get_animate (EWebView *web_view);
+void e_web_view_set_animate (EWebView *web_view,
+ gboolean animate);
+gboolean e_web_view_get_caret_mode (EWebView *web_view);
+void e_web_view_set_caret_mode (EWebView *web_view,
+ gboolean caret_mode);
+const gchar * e_web_view_get_selected_uri (EWebView *web_view);
+void e_web_view_set_selected_uri (EWebView *web_view,
+ const gchar *selected_uri);
+GtkAction * e_web_view_get_action (EWebView *web_view,
+ const gchar *action_name);
+GtkActionGroup *e_web_view_get_action_group (EWebView *web_view,
+ const gchar *group_name);
+gchar * e_web_view_extract_uri (EWebView *web_view,
+ GdkEventButton *event,
+ GtkHTML *frame);
+gboolean e_web_view_scroll_forward (EWebView *web_view);
+gboolean e_web_view_scroll_backward (EWebView *web_view);
+GtkUIManager * e_web_view_get_ui_manager (EWebView *web_view);
+GtkWidget * e_web_view_get_popup_menu (EWebView *web_view);
+void e_web_view_show_popup_menu (EWebView *web_view,
+ GdkEventButton *event,
+ GtkMenuPositionFunc func,
+ gpointer user_data);
+void e_web_view_status_message (EWebView *web_view,
+ const gchar *status_message);
+void e_web_view_stop_loading (EWebView *web_view);
+void e_web_view_update_actions (EWebView *web_view);
+
+G_END_DECLS
+
+#endif /* E_WEB_VIEW_H */