[evolution/webkit-composer: 17/150] Port HTML/plain text mode toggling
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/webkit-composer: 17/150] Port HTML/plain text mode toggling
- Date: Wed, 6 Feb 2013 00:12:22 +0000 (UTC)
commit 84f9cf6e818a29d4a1954feba0b2876aeb302565
Author: Dan VrÃtil <dvratil redhat com>
Date: Tue Jul 31 15:54:49 2012 +0200
Port HTML/plain text mode toggling
Unlike with GtkHTML, we can't change renderers and make WebKit to
render HTML code as plain text. The only way is to discard any formatting
when toggling from HTML to plain text. This is similar to what KMail does.
e-util/e-editor-actions.c | 143 ++++++++++++++++++++++++++------------------
e-util/e-editor-widget.c | 65 ++++++++++++++-------
e-util/e-editor-widget.h | 7 +-
e-util/test-editor.c | 8 +-
4 files changed, 136 insertions(+), 87 deletions(-)
---
diff --git a/e-util/e-editor-actions.c b/e-util/e-editor-actions.c
index 94e5702..d030028 100644
--- a/e-util/e-editor-actions.c
+++ b/e-util/e-editor-actions.c
@@ -885,80 +885,102 @@ action_language_cb (GtkToggleAction *action,
*/
}
-static void
-action_mode_cb (GtkRadioAction *action,
- GtkRadioAction *current,
- EEditor *editor)
+struct _ModeChanged {
+ GtkRadioAction *action;
+ EEditor *editor;
+};
+
+static gboolean
+mode_changed (struct _ModeChanged *data)
{
- /* FIXME WEBKIT */
- /*
GtkActionGroup *action_group;
- HTMLPainter *new_painter;
- HTMLPainter *old_painter;
- GtkHTML *html;
- EditorMode mode;
- gboolean html_mode;
+ EEditor *editor = data->editor;
+ EEditorWidget *widget;
+ EEditorWidgetMode mode;
+ gboolean is_html;
- html = gtkhtml_editor_get_html (editor);
- mode = gtk_radio_action_get_current_value (current);
- html_mode = (mode == EDITOR_MODE_HTML);
+ widget = e_editor_get_editor_widget (editor);
+ mode = gtk_radio_action_get_current_value (data->action);
+ is_html = (mode == E_EDITOR_WIDGET_MODE_HTML);
+
+ if (mode == e_editor_widget_get_mode (widget)) {
+ goto exit;
+ }
+
+ /* If switching from HTML to plain text */
+ if (!is_html) {
+ GtkWidget *dialog, *parent;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (editor));
+ if (!GTK_IS_WINDOW (parent)) {
+ parent = NULL;
+ }
+
+ dialog = gtk_message_dialog_new (
+ parent ? GTK_WINDOW (parent) : NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK_CANCEL,
+ _("Turning HTML mode off will cause the text "
+ "to loose all formatting. Do you want to continue?"));
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_CANCEL) {
+ gtk_radio_action_set_current_value (
+ data->action, E_EDITOR_WIDGET_MODE_HTML);
+ gtk_widget_destroy (dialog);
+ goto exit;
+ }
+
+ gtk_widget_destroy (dialog);
+ }
action_group = editor->priv->html_actions;
- gtk_action_group_set_sensitive (action_group, html_mode);
+ gtk_action_group_set_sensitive (action_group, is_html);
action_group = editor->priv->html_context_actions;
- gtk_action_group_set_visible (action_group, html_mode);
+ gtk_action_group_set_visible (action_group, is_html);
- gtk_widget_set_sensitive (editor->priv->color_combo_box, html_mode);
+ gtk_widget_set_sensitive (editor->priv->color_combo_box, is_html);
- if (html_mode)
+ if (is_html) {
gtk_widget_show (editor->priv->html_toolbar);
- else
+ } else {
gtk_widget_hide (editor->priv->html_toolbar);
+ }
- // Certain paragraph styles are HTML-only.
- gtk_action_set_sensitive (ACTION (STYLE_H1), html_mode);
- gtk_action_set_sensitive (ACTION (STYLE_H2), html_mode);
- gtk_action_set_sensitive (ACTION (STYLE_H3), html_mode);
- gtk_action_set_sensitive (ACTION (STYLE_H4), html_mode);
- gtk_action_set_sensitive (ACTION (STYLE_H5), html_mode);
- gtk_action_set_sensitive (ACTION (STYLE_H6), html_mode);
- gtk_action_set_sensitive (ACTION (STYLE_ADDRESS), html_mode);
+ /* Certain paragraph styles are HTML-only. */
+ gtk_action_set_sensitive (ACTION (STYLE_H1), is_html);
+ gtk_action_set_sensitive (ACTION (STYLE_H2), is_html);
+ gtk_action_set_sensitive (ACTION (STYLE_H3), is_html);
+ gtk_action_set_sensitive (ACTION (STYLE_H4), is_html);
+ gtk_action_set_sensitive (ACTION (STYLE_H5), is_html);
+ gtk_action_set_sensitive (ACTION (STYLE_H6), is_html);
+ gtk_action_set_sensitive (ACTION (STYLE_ADDRESS), is_html);
- // Swap painters.
+ e_editor_widget_set_mode (
+ e_editor_get_editor_widget (editor), mode);
- if (html_mode) {
- new_painter = editor->priv->html_painter;
- old_painter = editor->priv->plain_painter;
- } else {
- new_painter = editor->priv->plain_painter;
- old_painter = editor->priv->html_painter;
- }
+ exit:
+ g_clear_object (&data->editor);
+ g_clear_object (&data->action);
+ g_free (data);
- // Might be true during initialization.
- if (html->engine->painter == new_painter)
- return;
+ return FALSE;
+}
- html_gdk_painter_unrealize (HTML_GDK_PAINTER (old_painter));
- if (html->engine->window != NULL)
- html_gdk_painter_realize (
- HTML_GDK_PAINTER (new_painter),
- html->engine->window);
-
- html_font_manager_set_default (
- &new_painter->font_manager,
- old_painter->font_manager.variable.face,
- old_painter->font_manager.fixed.face,
- old_painter->font_manager.var_size,
- old_painter->font_manager.var_points,
- old_painter->font_manager.fix_size,
- old_painter->font_manager.fix_points);
-
- html_engine_set_painter (html->engine, new_painter);
- html_engine_schedule_redraw (html->engine);
-
- g_object_notify (G_OBJECT (editor), "html-mode");
- */
+static void
+action_mode_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EEditor *editor)
+{
+ struct _ModeChanged *data;
+
+ data = g_new0 (struct _ModeChanged, 1);
+ data->action = g_object_ref (current);
+ data->editor = g_object_ref (editor);
+
+ /* We can't change group current value from this callback, so
+ * let's do it all from an idle callback */
+ g_idle_add ((GSourceFunc) mode_changed, data);
}
static void
@@ -2130,6 +2152,7 @@ editor_actions_init (EEditor *editor)
manager = e_editor_get_ui_manager (editor);
domain = GETTEXT_PACKAGE;
+ editor_widget = e_editor_get_editor_widget (editor);
/* Core Actions */
action_group = editor->priv->core_actions;
@@ -2154,6 +2177,9 @@ editor_actions_init (EEditor *editor)
G_CALLBACK (action_style_cb), editor);
gtk_ui_manager_insert_action_group (manager, action_group, 0);
+ /* Synchronize wiget mode with the button */
+ e_editor_widget_set_mode (editor_widget, E_EDITOR_WIDGET_MODE_HTML);
+
/* Face Action */
action = e_emoticon_action_new (
"insert-face", _("_Emoticon"),
@@ -2239,7 +2265,6 @@ editor_actions_init (EEditor *editor)
gtk_action_set_sensitive (ACTION (UNINDENT), FALSE);
gtk_action_set_sensitive (ACTION (FIND_AGAIN), FALSE);
- editor_widget = e_editor_get_editor_widget (editor);
g_object_bind_property (
editor_widget, "can-redo",
ACTION (REDO), "sensitive",
diff --git a/e-util/e-editor-widget.c b/e-util/e-editor-widget.c
index 7930595..4951221 100644
--- a/e-util/e-editor-widget.c
+++ b/e-util/e-editor-widget.c
@@ -21,12 +21,12 @@
#endif
#include "e-editor-widget.h"
+#include "e-editor.h"
#include <glib/gi18n-lib.h>
struct _EEditorWidgetPrivate {
gint changed : 1;
- gint html_mode : 1;
gint inline_spelling : 1;
gint magic_links : 1;
gint magic_smileys : 1;
@@ -36,6 +36,8 @@ struct _EEditorWidgetPrivate {
gint can_redo : 1;
gint can_undo : 1;
+ EEditorWidgetMode mode;
+
/* FIXME WEBKIT Is this in widget's competence? */
GList *spelling_langs;
};
@@ -49,7 +51,7 @@ G_DEFINE_TYPE (
enum {
PROP_0,
PROP_CHANGED,
- PROP_HTML_MODE,
+ PROP_MODE,
PROP_INLINE_SPELLING,
PROP_MAGIC_LINKS,
PROP_MAGIC_SMILEYS,
@@ -61,6 +63,22 @@ enum {
PROP_CAN_UNDO
};
+static void
+editor_widget_strip_formatting (EEditorWidget *widget)
+{
+ gchar *plain, *html;
+
+ plain = e_editor_widget_get_text_plain (widget);
+
+ /* Convert \n to <br> */
+ regex = g_regex_new ("\n", 0, 0, NULL);
+ html = g_regex_replace (regex, plain, strlen (plain), 0, "<br>", 0, NULL);
+
+ e_editor_widget_set_text_html (widget, html);
+
+ g_free (plain);
+ g_free (html);
+}
static void
editor_widget_user_changed_contents_cb (EEditorWidget *widget,
@@ -116,9 +134,9 @@ e_editor_widget_get_property (GObject *object,
{
switch (property_id) {
- case PROP_HTML_MODE:
- g_value_set_boolean (
- value, e_editor_widget_get_html_mode (
+ case PROP_MODE:
+ g_value_set_int (
+ value, e_editor_widget_get_mode (
E_EDITOR_WIDGET (object)));
return;
@@ -182,10 +200,10 @@ e_editor_widget_set_property (GObject *object,
{
switch (property_id) {
- case PROP_HTML_MODE:
- e_editor_widget_set_html_mode (
+ case PROP_MODE:
+ e_editor_widget_set_mode (
E_EDITOR_WIDGET (object),
- g_value_get_boolean (value));
+ g_value_get_int (value));
return;
case PROP_INLINE_SPELLING:
@@ -234,12 +252,14 @@ e_editor_widget_class_init (EEditorWidgetClass *klass)
g_object_class_install_property (
object_class,
- PROP_HTML_MODE,
- g_param_spec_boolean (
- "html-mode",
- "HTML Mode",
+ PROP_MODE,
+ g_param_spec_int (
+ "mode",
+ "Mode",
"Edit HTML or plain text",
- TRUE,
+ E_EDITOR_WIDGET_MODE_PLAIN_TEXT,
+ E_EDITOR_WIDGET_MODE_HTML,
+ E_EDITOR_WIDGET_MODE_PLAIN_TEXT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
@@ -414,26 +434,29 @@ e_editor_widget_set_changed (EEditorWidget *widget,
g_object_notify (G_OBJECT (widget), "changed");
}
-gboolean
-e_editor_widget_get_html_mode (EEditorWidget *widget)
+EEditorWidgetMode
+e_editor_widget_get_mode (EEditorWidget *widget)
{
g_return_val_if_fail (E_IS_EDITOR_WIDGET (widget), FALSE);
- return widget->priv->html_mode;
+ return widget->priv->mode;
}
void
-e_editor_widget_set_html_mode (EEditorWidget *widget,
- gboolean html_mode)
+e_editor_widget_set_mode (EEditorWidget *widget,
+ EEditorWidgetMode mode)
{
g_return_if_fail (E_IS_EDITOR_WIDGET (widget));
- if ((widget->priv->html_mode ? TRUE : FALSE) == (html_mode ? TRUE : FALSE))
+ if (widget->priv->mode == mode)
return;
- widget->priv->html_mode = html_mode;
+ widget->priv->mode = mode;
+
+ if (widget->priv->mode == E_EDITOR_WIDGET_MODE_PLAIN_TEXT)
+ editor_widget_strip_formatting (widget);
- g_object_notify (G_OBJECT (widget), "html-mode");
+ g_object_notify (G_OBJECT (widget), "mode");
}
gboolean
diff --git a/e-util/e-editor-widget.h b/e-util/e-editor-widget.h
index 0ed03c0..0affadf 100644
--- a/e-util/e-editor-widget.h
+++ b/e-util/e-editor-widget.h
@@ -86,9 +86,10 @@ 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);
+EEditorWidgetMode
+ e_editor_widget_get_mode (EEditorWidget *widget);
+void e_editor_widget_set_mode (EEditorWidget *widget,
+ EEditorWidgetMode mode);
gboolean e_editor_widget_get_inline_spelling
(EEditorWidget *widget);
diff --git a/e-util/test-editor.c b/e-util/test-editor.c
index 00635a3..8cac737 100644
--- a/e-util/test-editor.c
+++ b/e-util/test-editor.c
@@ -217,8 +217,8 @@ action_save_cb (GtkAction *action,
return;
filename = e_editor_get_filename (editor);
- as_html = e_editor_widget_get_html_mode (
- e_editor_get_editor_widget (editor));
+ as_html = (e_editor_widget_get_mode (
+ e_editor_get_editor_widget (editor)) == E_EDITOR_WIDGET_MODE_HTML);
e_editor_save (editor, filename, as_html, &error);
handle_error (&error);
@@ -236,8 +236,8 @@ action_save_as_cb (GtkAction *action,
return;
filename = e_editor_get_filename (editor);
- as_html = e_editor_widget_get_html_mode (
- e_editor_get_editor_widget (editor));
+ as_html = (e_editor_widget_get_mode (
+ e_editor_get_editor_widget (editor)) == E_EDITOR_WIDGET_MODE_HTML);
e_editor_save (editor, filename, as_html, &error);
handle_error (&error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]