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



commit 8d8f1471c6335a8632e2e11946f21a403a7e9163
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]