[evolution/webkit-composer: 9/147] Implement EEditorWidget



commit 5f099b5e53aa39e8464ae2c8ef408aa24bdb1b97
Author: Dan VrÃtil <dvratil redhat com>
Date:   Thu Jul 26 21:14:44 2012 +0200

    Implement EEditorWidget
    
    EEditorWidget is a subclass of WebKitWebView and provides a low-level
    API to control behavior, formatting and content of the editor.

 e-util/e-editor-widget.c |  331 +++++++++++++++++++++++++++++++++++++++++-----
 e-util/e-editor-widget.h |   58 +++++++--
 2 files changed, 346 insertions(+), 43 deletions(-)
---
diff --git a/e-util/e-editor-widget.c b/e-util/e-editor-widget.c
index 1a52824..1c9add6 100644
--- a/e-util/e-editor-widget.c
+++ b/e-util/e-editor-widget.c
@@ -22,8 +22,17 @@
 
 #include "e-editor-widget.h"
 
+#include <glib/gi18n-lib.h>
+
 struct _EEditorWidgetPrivate {
-	gint dummy;
+	gint changed		: 1;
+	gint html_mode		: 1;
+	gint inline_spelling	: 1;
+	gint magic_links	: 1;
+	gint magic_smileys	: 1;
+
+	/* FIXME WEBKIT Is this in widget's competence? */
+	GList *spelling_langs;
 };
 
 G_DEFINE_TYPE (
@@ -32,6 +41,16 @@ G_DEFINE_TYPE (
 	WEBKIT_TYPE_WEB_VIEW
 );
 
+enum {
+	PROP_0,
+	PROP_CHANGED,
+	PROP_HTML_MODE,
+	PROP_INLINE_SPELLING,
+	PROP_MAGIC_LINKS,
+	PROP_MAGIC_SMILEYS,
+	PROP_SPELL_LANGUAGES
+};
+
 
 static void
 e_editor_widget_get_property (GObject *object,
@@ -39,6 +58,37 @@ e_editor_widget_get_property (GObject *object,
 			      GValue *value,
 			      GParamSpec *pspec)
 {
+	switch (property_id) {
+
+		case PROP_HTML_MODE:
+			g_value_set_boolean (
+				value, e_editor_widget_get_html_mode (
+				E_EDITOR_WIDGET (object)));
+			return;
+
+		case PROP_INLINE_SPELLING:
+			g_value_set_boolean (
+				value, e_editor_widget_get_inline_spelling (
+				E_EDITOR_WIDGET (object)));
+			return;
+
+		case PROP_MAGIC_LINKS:
+			g_value_set_boolean (
+				value, e_editor_widget_get_magic_links (
+				E_EDITOR_WIDGET (object)));
+			return;
+
+		case PROP_MAGIC_SMILEYS:
+			g_value_set_boolean (
+				value, e_editor_widget_get_magic_smileys (
+				E_EDITOR_WIDGET (object)));
+			return;
+		case PROP_CHANGED:
+			g_value_set_boolean (
+				value, e_editor_widget_get_changed (
+				E_EDITOR_WIDGET (object)));
+			return;
+	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 }
@@ -49,6 +99,37 @@ e_editor_widget_set_property (GObject *object,
 			      const GValue *value,
 			      GParamSpec *pspec)
 {
+	switch (property_id) {
+
+		case PROP_HTML_MODE:
+			e_editor_widget_set_html_mode (
+				E_EDITOR_WIDGET (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_INLINE_SPELLING:
+			e_editor_widget_set_inline_spelling (
+				E_EDITOR_WIDGET (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_MAGIC_LINKS:
+			e_editor_widget_set_magic_links (
+				E_EDITOR_WIDGET (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_MAGIC_SMILEYS:
+			e_editor_widget_set_magic_smileys (
+				E_EDITOR_WIDGET (object),
+				g_value_get_boolean (value));
+			return;
+		case PROP_CHANGED:
+			e_editor_widget_set_changed (
+				E_EDITOR_WIDGET (object),
+				g_value_get_boolean (value));
+			return;
+	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 }
@@ -56,7 +137,6 @@ e_editor_widget_set_property (GObject *object,
 static void
 e_editor_widget_finalize (GObject *object)
 {
-	EEditorWidget *editor = E_EDITOR_WIDGET (object);
 }
 
 static void
@@ -64,19 +144,80 @@ e_editor_widget_class_init (EEditorWidgetClass *klass)
 {
 	GObjectClass *object_class;
 
+	g_type_class_add_private (klass, sizeof (EEditorWidgetPrivate));
+
 	object_class = G_OBJECT_CLASS (klass);
 	object_class->get_property = e_editor_widget_get_property;
 	object_class->set_property = e_editor_widget_set_property;
 	object_class->finalize = e_editor_widget_finalize;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_HTML_MODE,
+		g_param_spec_boolean (
+			"html-mode",
+			"HTML Mode",
+			"Edit HTML or plain text",
+			TRUE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_INLINE_SPELLING,
+		g_param_spec_boolean (
+			"inline-spelling",
+			"Inline Spelling",
+			"Check your spelling as you type",
+			TRUE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_MAGIC_LINKS,
+		g_param_spec_boolean (
+			"magic-links",
+			"Magic Links",
+			"Make URIs clickable as you type",
+			TRUE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_MAGIC_SMILEYS,
+		g_param_spec_boolean (
+			"magic-smileys",
+			"Magic Smileys",
+			"Convert emoticons to images as you type",
+			TRUE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_CHANGED,
+		g_param_spec_boolean (
+			"changed",
+			_("Changed property"),
+			_("Whether editor changed"),
+			FALSE,
+			G_PARAM_READWRITE));
 }
 
 static void
 e_editor_widget_init (EEditorWidget *editor)
 {
 	WebKitWebSettings *settings;
+	WebKitDOMDocument *document;
 	GSettings *g_settings;
 	gboolean enable_spellchecking;
 
+	editor->priv = G_TYPE_INSTANCE_GET_PRIVATE (
+		editor, E_TYPE_EDITOR_WIDGET, EEditorWidgetPrivate);
+
+	webkit_web_view_set_editable (WEBKIT_WEB_VIEW (editor), TRUE);
 	settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (editor));
 
 	g_settings = g_settings_new ("org.gnome.evolution.mail");
@@ -95,14 +236,18 @@ e_editor_widget_init (EEditorWidget *editor)
 	g_object_unref(g_settings);
 
 	webkit_web_view_set_settings (WEBKIT_WEB_VIEW (editor), settings);
+
+	/* Don't use CSS when possible to preserve compatibility with older
+	 * versions of Evolution or other MUAs */
+	document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (editor));
+	webkit_dom_document_exec_command (
+		document, "styleWithCSS", FALSE, "false");
 }
 
 EEditorWidget *
 e_editor_widget_new (void)
 {
-	return g_object_new (
-			E_TYPE_EDITOR_WIDGET,
-			"editable", TRUE, NULL);
+	return g_object_new (E_TYPE_EDITOR_WIDGET, NULL);
 }
 
 EEditorSelection *
@@ -111,51 +256,173 @@ e_editor_widget_get_selection (EEditorWidget *widget)
 	return e_editor_selection_new (WEBKIT_WEB_VIEW (widget));
 }
 
+gboolean
+e_editor_widget_get_changed (EEditorWidget *widget)
+{
+	g_return_val_if_fail (E_IS_EDITOR_WIDGET (widget), FALSE);
+
+	return widget->priv->changed;
+}
+
 void
-e_editor_widget_insert_html (EEditorWidget *widget,
-			     const gchar *html)
+e_editor_widget_set_changed (EEditorWidget *widget,
+			     gboolean changed)
 {
-	WebKitDOMDocument *document;
+	g_return_if_fail (E_IS_EDITOR_WIDGET (widget));
+
+	if ((widget->priv->changed ? TRUE : FALSE) == (changed ? TRUE : FALSE))
+		return;
+
+	widget->priv->changed = changed;
+
+	g_object_notify (G_OBJECT (widget), "changed");
+}
+
+gboolean
+e_editor_widget_get_html_mode (EEditorWidget *widget)
+{
+	g_return_val_if_fail (E_IS_EDITOR_WIDGET (widget), FALSE);
+
+	return widget->priv->html_mode;
+}
 
+void
+e_editor_widget_set_html_mode (EEditorWidget *widget,
+			       gboolean html_mode)
+{
 	g_return_if_fail (E_IS_EDITOR_WIDGET (widget));
-	g_return_if_fail (html != NULL);
 
-	document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (widget));
-	webkit_dom_document_exec_command (
-			document, "insertHTML", FALSE, html);
+	if ((widget->priv->html_mode ? TRUE : FALSE) == (html_mode ? TRUE : FALSE))
+		return;
+
+	widget->priv->html_mode = html_mode;
+
+	g_object_notify (G_OBJECT (widget), "html-mode");
+}
+
+gboolean
+e_editor_widget_get_inline_spelling (EEditorWidget *widget)
+{
+	g_return_val_if_fail (E_IS_EDITOR_WIDGET (widget), FALSE);
+
+	return widget->priv->inline_spelling;
 }
 
 void
-e_editor_widget_insert_text (EEditorWidget *widget,
-			     const gchar *text)
+e_editor_widget_set_inline_spelling (EEditorWidget *widget,
+				     gboolean inline_spelling)
 {
-	WebKitDOMDocument *document;
-	WebKitDOMDOMWindow *window;
-	WebKitDOMDOMSelection *selection;
-	WebKitDOMRange *range;
-	WebKitDOMElement *element;
+	g_return_if_fail (E_IS_EDITOR_WIDGET (widget));
+
+	if ((widget->priv->inline_spelling ? TRUE : FALSE) == (inline_spelling ? TRUE : FALSE))
+		return;
+
+	widget->priv->inline_spelling = inline_spelling;
+
+	g_object_notify (G_OBJECT (widget), "inline-spelling");
+}
+
+gboolean
+e_editor_widget_get_magic_links (EEditorWidget *widget)
+{
+	g_return_val_if_fail (E_IS_EDITOR_WIDGET (widget), FALSE);
+
+	return widget->priv->magic_links;
+}
 
+void
+e_editor_widget_set_magic_links (EEditorWidget *widget,
+				 gboolean magic_links)
+{
 	g_return_if_fail (E_IS_EDITOR_WIDGET (widget));
-	g_return_if_fail (text != NULL);
 
-	document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (widget));
-	window = webkit_dom_document_get_default_view (document);
-	selection = webkit_dom_dom_window_get_selection (window);
+	if ((widget->priv->magic_links ? TRUE : FALSE) == (magic_links ? TRUE : FALSE))
+		return;
+
+	widget->priv->magic_links = magic_links;
+
+	g_object_notify (G_OBJECT (widget), "magic-links");
+}
+
+gboolean
+e_editor_widget_get_magic_smileys (EEditorWidget *widget)
+{
+	g_return_val_if_fail (E_IS_EDITOR_WIDGET (widget), FALSE);
 
-	if (webkit_dom_dom_selection_get_range_count (selection) < 1) {
+	return widget->priv->magic_smileys;
+}
+
+void
+e_editor_widget_set_magic_smileys (EEditorWidget *widget,
+				   gboolean magic_smileys)
+{
+	g_return_if_fail (E_IS_EDITOR_WIDGET (widget));
+
+	if ((widget->priv->magic_smileys ? TRUE : FALSE) == (magic_smileys ? TRUE : FALSE))
 		return;
+
+	widget->priv->magic_smileys = magic_smileys;
+
+	g_object_notify (G_OBJECT (widget), "magic-smileys");
+}
+
+GList *
+e_editor_widget_get_spell_languages (EEditorWidget *widget)
+{
+	g_return_val_if_fail (E_IS_EDITOR_WIDGET (widget), NULL);
+
+	return g_list_copy (widget->priv->spelling_langs);
+}
+
+void
+e_editor_widget_set_spell_languages (EEditorWidget *widget,
+				     GList *spell_languages)
+{
+	GList *iter;
+
+	g_return_if_fail (E_IS_EDITOR_WIDGET (widget));
+	g_return_if_fail (spell_languages);
+
+	g_list_free_full (widget->priv->spelling_langs, g_free);
+
+	widget->priv->spelling_langs = NULL;
+	for (iter = spell_languages; iter; iter = g_list_next (iter)) {
+		widget->priv->spelling_langs =
+			g_list_append (
+				widget->priv->spelling_langs,
+		  		g_strdup (iter->data));
 	}
 
-	range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+	g_object_notify (G_OBJECT (widget), "spell-languages");
+}
 
-	element = webkit_dom_document_create_element (document, "DIV", NULL);
-	webkit_dom_html_element_set_inner_text (
-		WEBKIT_DOM_HTML_ELEMENT (element), text, NULL);
+gchar *
+e_editor_widget_get_text_html (EEditorWidget *widget)
+{
+	WebKitDOMDocument *document;
+	WebKitDOMElement *element;
+
+	document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (widget));
+	element = webkit_dom_document_get_document_element (document);
+	return webkit_dom_html_element_get_outer_html (
+			WEBKIT_DOM_HTML_ELEMENT (element));
+}
 
-	webkit_dom_range_insert_node (
-		range, webkit_dom_node_get_first_child (
-			WEBKIT_DOM_NODE (element)), NULL);
+gchar *
+e_editor_widget_get_text_plain (EEditorWidget *widget)
+{
+	WebKitDOMDocument *document;
+	WebKitDOMHTMLElement *element;
 
-	g_object_unref (element);
+	document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (widget));
+	element = webkit_dom_document_get_body (document);
+	return webkit_dom_html_element_get_inner_text (element);
+}
+
+void
+e_editor_widget_set_text_html (EEditorWidget *widget,
+			       const gchar *text)
+{
+	webkit_web_view_load_html_string (WEBKIT_WEB_VIEW (widget), text, NULL);
 }
 
diff --git a/e-util/e-editor-widget.h b/e-util/e-editor-widget.h
index 897a068..0ed03c0 100644
--- a/e-util/e-editor-widget.h
+++ b/e-util/e-editor-widget.h
@@ -53,6 +53,13 @@ typedef enum {
 	E_EDITOR_WIDGET_MODE_HTML,
 } EEditorWidgetMode;
 
+typedef enum {
+	E_EDITOR_WIDGET_REPLACE_ANSWER_REPLACE,
+	E_EDITOR_WIDGET_REPLACE_ANSWER_REPLACE_ALL,
+	E_EDITOR_WIDGET_REPLACE_ANSWER_CANCEL,
+	E_EDITOR_WIDGET_REPLACE_ANSWER_NEXT
+} EEditorWidgetReplaceAnswer;
+
 typedef struct _EEditorWidget EEditorWidget;
 typedef struct _EEditorWidgetClass EEditorWidgetClass;
 typedef struct _EEditorWidgetPrivate EEditorWidgetPrivate;
@@ -67,17 +74,46 @@ struct _EEditorWidgetClass {
 	WebKitWebViewClass parent_class;
 };
 
-GType			e_editor_widget_get_type 	(void);
-
-EEditorWidget *		e_editor_widget_new		(void);
-
-EEditorSelection *	e_editor_widget_get_selection	(EEditorWidget *widget);
-
-void			e_editor_widget_insert_html	(EEditorWidget *widget,
-							 const gchar *html);
-
-void			e_editor_widget_insert_text	(EEditorWidget *widget,
-							 const gchar *html);
+GType		e_editor_widget_get_type 	(void);
+
+EEditorWidget *	e_editor_widget_new		(void);
+
+EEditorSelection *
+		e_editor_widget_get_selection	(EEditorWidget *widget);
+
+
+gboolean	e_editor_widget_get_changed	(EEditorWidget *widget);
+void		e_editor_widget_set_changed	(EEditorWidget *widget,
+						 gboolean changed);
+
+gboolean	e_editor_widget_get_html_mode	(EEditorWidget *widget);
+void		e_editor_widget_set_html_mode	(EEditorWidget *widget,
+						 gboolean html_mode);
+
+gboolean	e_editor_widget_get_inline_spelling
+						(EEditorWidget *widget);
+void		e_editor_widget_set_inline_spelling
+						(EEditorWidget *widget,
+						 gboolean inline_spelling);
+gboolean	e_editor_widget_get_magic_links	(EEditorWidget *widget);
+void		e_editor_widget_set_magic_links	(EEditorWidget *widget,
+						 gboolean magic_links);
+gboolean	e_editor_widget_get_magic_smileys
+						(EEditorWidget *widget);
+void		e_editor_widget_set_magic_smileys
+						(EEditorWidget *widget,
+						 gboolean magic_smileys);
+
+GList *		e_editor_widget_get_spell_languages
+						(EEditorWidget *widget);
+void		e_editor_widget_set_spell_languages
+						(EEditorWidget *widget,
+						 GList *spell_languages);
+
+gchar *		e_editor_widget_get_text_html	(EEditorWidget *widget);
+gchar *		e_editor_widget_get_text_plain	(EEditorWidget *widget);
+void		e_editor_widget_set_text_html	(EEditorWidget *widget,
+						 const gchar *text);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]