[evolution/webkit-composer: 19/231] Make bold, italic, underline and strike-through buttons work
- From: Tomas Popela <tpopela src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/webkit-composer: 19/231] Make bold, italic, underline and strike-through buttons work
- Date: Fri, 13 Sep 2013 14:07:36 +0000 (UTC)
commit b10a42a47cdc9ad957d07d13e329261fc96857e7
Author: Dan Vrátil <dvratil redhat com>
Date: Wed Aug 1 11:49:36 2012 +0200
Make bold, italic, underline and strike-through buttons work
This is done by binding their 'activate' property with
EEditorSelection's properties for each style, so that
when selection changes, the buttons are notified about
style property change and their activate state is toggled
if neccessary.
This does not fully work for Monospaced button, as removing
of the formatting must be implemented manually.
e-util/e-editor-actions.c | 118 +++++++++---------------------------------
e-util/e-editor-private.h | 3 +-
e-util/e-editor-selection.c | 117 ++++++++++++++++++++++++++++++++++++-------
e-util/e-editor-selection.h | 6 ++
e-util/e-editor-widget.c | 15 +++++-
e-util/e-editor.c | 1 +
6 files changed, 147 insertions(+), 113 deletions(-)
---
diff --git a/e-util/e-editor-actions.c b/e-util/e-editor-actions.c
index d030028..5af4a4c 100644
--- a/e-util/e-editor-actions.c
+++ b/e-util/e-editor-actions.c
@@ -110,18 +110,6 @@ insert_text_file_ready_cb (GFile *file,
* Action Callbacks
*****************************************************************************/
-static void
-action_bold_cb (GtkToggleAction *action,
- EEditor *editor)
-{
- EEditorSelection *selection;
-
- selection = e_editor_widget_get_selection (
- e_editor_get_editor_widget (editor));
- e_editor_selection_set_bold (
- selection, gtk_toggle_action_get_active (action));
-}
-
static WebKitDOMNode *
find_parent_element_by_type (WebKitDOMNode *node, GType type)
{
@@ -785,18 +773,6 @@ action_insert_text_file_cb (GtkAction *action,
}
static void
-action_italic_cb (GtkToggleAction *action,
- EEditor *editor)
-{
- EEditorSelection *selection;
-
- selection = e_editor_widget_get_selection (
- e_editor_get_editor_widget (editor));
- e_editor_selection_set_italic (
- selection, gtk_toggle_action_get_active (action));
-}
-
-static void
action_justify_cb (GtkRadioAction *action,
GtkRadioAction *current,
EEditor *editor)
@@ -984,32 +960,6 @@ action_mode_cb (GtkRadioAction *action,
}
static void
-action_monospaced_cb (GtkToggleAction *action,
- EEditor *editor)
-{
- /* FIXME WEBKIT */
- /*
- GtkHTML *html;
- GtkHTMLFontStyle and_mask;
- GtkHTMLFontStyle or_mask;
-
- if (editor->priv->ignore_style_change)
- return;
-
- if (gtk_toggle_action_get_active (action)) {
- and_mask = GTK_HTML_FONT_STYLE_MAX;
- or_mask = GTK_HTML_FONT_STYLE_FIXED;
- } else {
- and_mask = ~GTK_HTML_FONT_STYLE_FIXED;
- or_mask = 0;
- }
-
- html = gtkhtml_editor_get_html (editor);
- gtk_html_set_font_style (html, and_mask, or_mask);
- */
-}
-
-static void
action_paste_cb (GtkAction *action,
EEditor *editor)
{
@@ -1093,10 +1043,6 @@ action_style_cb (GtkRadioAction *action,
{
EEditorSelection *selection;
- /* FIXME WEBKIT What's this good for? */
- if (editor->priv->ignore_style_change)
- return;
-
selection = e_editor_widget_get_selection (
e_editor_get_editor_widget (editor));
e_editor_selection_set_block_format (
@@ -1162,9 +1108,6 @@ action_size_cb (GtkRadioAction *action,
{
EEditorSelection *selection;
- if (editor->priv->ignore_style_change)
- return;
-
selection = e_editor_widget_get_selection (
e_editor_get_editor_widget (editor));
e_editor_selection_set_font_size (
@@ -1181,21 +1124,6 @@ action_spell_check_cb (GtkAction *action,
}
static void
-action_strikethrough_cb (GtkToggleAction *action,
- EEditor *editor)
-{
- EEditorSelection *selection;
-
- if (editor->priv->ignore_style_change)
- return;
-
- selection = e_editor_widget_get_selection (
- e_editor_get_editor_widget (editor));
- e_editor_selection_set_italic (
- selection, gtk_toggle_action_get_active (action));
-}
-
-static void
action_test_url_cb (GtkAction *action,
EEditor *editor)
{
@@ -1216,21 +1144,6 @@ action_test_url_cb (GtkAction *action,
}
static void
-action_underline_cb (GtkToggleAction *action,
- EEditor *editor)
-{
- EEditorSelection *selection;
-
- if (editor->priv->ignore_style_change)
- return;
-
- selection = e_editor_widget_get_selection (
- e_editor_get_editor_widget (editor));
- e_editor_selection_set_underline (
- selection, gtk_toggle_action_get_active (action));
-}
-
-static void
action_undo_cb (GtkAction *action,
EEditor *editor)
{
@@ -1686,7 +1599,7 @@ static GtkToggleActionEntry html_toggle_entries[] = {
N_("_Bold"),
"<Control>b",
N_("Bold"),
- G_CALLBACK (action_bold_cb),
+ NULL,
FALSE },
{ "italic",
@@ -1694,7 +1607,7 @@ static GtkToggleActionEntry html_toggle_entries[] = {
N_("_Italic"),
"<Control>i",
N_("Italic"),
- G_CALLBACK (action_italic_cb),
+ NULL,
FALSE },
{ "monospaced",
@@ -1702,7 +1615,7 @@ static GtkToggleActionEntry html_toggle_entries[] = {
N_("_Plain Text"),
"<Control>t",
N_("Plain Text"),
- G_CALLBACK (action_monospaced_cb),
+ NULL,
FALSE },
{ "strikethrough",
@@ -1710,7 +1623,7 @@ static GtkToggleActionEntry html_toggle_entries[] = {
N_("_Strikethrough"),
NULL,
N_("Strikethrough"),
- G_CALLBACK (action_strikethrough_cb),
+ NULL,
FALSE },
{ "underline",
@@ -1718,7 +1631,7 @@ static GtkToggleActionEntry html_toggle_entries[] = {
N_("_Underline"),
"<Control>u",
N_("Underline"),
- G_CALLBACK (action_underline_cb),
+ NULL,
FALSE }
};
@@ -2286,4 +2199,25 @@ editor_actions_init (EEditor *editor)
ACTION (PASTE), "sensitive",
G_BINDING_SYNC_CREATE);
+ g_object_bind_property (
+ editor->priv->selection, "bold",
+ ACTION (BOLD), "active",
+ G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
+ g_object_bind_property (
+ editor->priv->selection, "italic",
+ ACTION (ITALIC), "active",
+ G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
+ g_object_bind_property (
+ editor->priv->selection, "monospaced",
+ ACTION (MONOSPACED), "active",
+ G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
+ g_object_bind_property (
+ editor->priv->selection, "strike-through",
+ ACTION (STRIKETHROUGH), "active",
+ G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
+ g_object_bind_property (
+ editor->priv->selection, "underline",
+ ACTION (UNDERLINE), "active",
+ G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
+
}
diff --git a/e-util/e-editor-private.h b/e-util/e-editor-private.h
index cdb2379..c736add 100644
--- a/e-util/e-editor-private.h
+++ b/e-util/e-editor-private.h
@@ -64,8 +64,7 @@ struct _EEditorPrivate {
GtkWidget *scrolled_window;
EEditorWidget *editor_widget;
-
- guint ignore_style_change : 1;
+ EEditorSelection *selection;
gchar *filename;
};
diff --git a/e-util/e-editor-selection.c b/e-util/e-editor-selection.c
index 579dc3f..0fdd4d3 100644
--- a/e-util/e-editor-selection.c
+++ b/e-util/e-editor-selection.c
@@ -58,6 +58,7 @@ enum {
PROP_FONT_COLOR,
PROP_BLOCK_FORMAT,
PROP_ITALIC,
+ PROP_MONOSPACED,
PROP_STRIKE_THROUGH,
PROP_SUBSCRIPT,
PROP_SUPERSCRIPT,
@@ -82,31 +83,47 @@ editor_selection_get_current_range (EEditorSelection *selection)
}
static gboolean
-get_has_style_property (EEditorSelection *selection,
- const gchar *style,
- const gchar *value)
+get_has_style (EEditorSelection *selection,
+ const gchar *style_tag)
{
WebKitDOMNode *node;
WebKitDOMElement *element;
WebKitDOMRange *range;
- WebKitDOMCSSStyleDeclaration *css;
- gchar *style_value;
gboolean result;
+ gint tag_len;
+
range = editor_selection_get_current_range (selection);
- node = webkit_dom_range_get_common_ancestor_container (range, NULL);
+ if (!range) {
+ return FALSE;
+ }
+
+ node = webkit_dom_range_get_start_container (range, NULL);
if (!WEBKIT_DOM_IS_ELEMENT (node)) {
element = webkit_dom_node_get_parent_element (node);
} else {
element = WEBKIT_DOM_ELEMENT (node);
}
- css = webkit_dom_element_get_style (element);
- style_value = webkit_dom_css_style_declaration_get_property_value (
- css, style);
+ tag_len = strlen (style_tag);
+ result = FALSE;
+ while (!result && element) {
+ gchar *element_tag;
+
+ element_tag = webkit_dom_element_get_tag_name (element);
+
+ result = ((tag_len == strlen (element_tag)) &&
+ (g_ascii_strncasecmp (element_tag, style_tag, tag_len) == 0));
- result = (g_ascii_strncasecmp (style_value, value, strlen (value)) == 0);
- g_free (style_value);
+ g_free (element_tag);
+
+ if (result) {
+ break;
+ }
+
+ element = webkit_dom_node_get_parent_element (
+ WEBKIT_DOM_NODE (element));
+ }
return result;
}
@@ -122,6 +139,7 @@ webview_selection_changed (WebKitWebView *webview,
g_object_notify (G_OBJECT (selection), "font-color");
g_object_notify (G_OBJECT (selection), "block-format");
g_object_notify (G_OBJECT (selection), "italic");
+ g_object_notify (G_OBJECT (selection), "monospaced");
g_object_notify (G_OBJECT (selection), "strike-through");
g_object_notify (G_OBJECT (selection), "subscript");
g_object_notify (G_OBJECT (selection), "superscript");
@@ -134,8 +152,9 @@ editor_selection_set_webview (EEditorSelection *selection,
WebKitWebView *webview)
{
selection->priv->webview = g_object_ref (webview);
- g_signal_connect (webview, "selection-changed",
- G_CALLBACK (webview_selection_changed), selection);
+ g_signal_connect (
+ webview, "selection-changed",
+ G_CALLBACK (webview_selection_changed), selection);
}
@@ -184,6 +203,11 @@ e_editor_selection_get_property (GObject *object,
e_editor_selection_get_italic (selection));
return;
+ case PROP_MONOSPACED:
+ g_value_set_boolean (value,
+ e_editor_selection_get_monospaced (selection));
+ return;
+
case PROP_STRIKE_THROUGH:
g_value_set_boolean (value,
e_editor_selection_get_strike_through (selection));
@@ -257,6 +281,11 @@ e_editor_selection_set_property (GObject *object,
selection, g_value_get_boolean (value));
return;
+ case PROP_MONOSPACED:
+ e_editor_selection_set_monospaced (
+ selection, g_value_get_boolean (value));
+ return;
+
case PROP_STRIKE_THROUGH:
e_editor_selection_set_strike_through (
selection, g_value_get_boolean (value));
@@ -390,6 +419,16 @@ e_editor_selection_class_init (EEditorSelectionClass *klass)
g_object_class_install_property (
object_class,
+ PROP_MONOSPACED,
+ g_param_spec_boolean (
+ "monospaced",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
PROP_STRIKE_THROUGH,
g_param_spec_boolean (
"strike-through",
@@ -635,8 +674,7 @@ e_editor_selection_get_bold (EEditorSelection *selection)
{
g_return_val_if_fail (E_IS_EDITOR_SELECTION (selection), FALSE);
- return (get_has_style_property (selection, "fontWeight", "bold") ||
- get_has_style_property (selection, "fontWeight", "700"));
+ return get_has_style (selection, "b");
}
void
@@ -772,7 +810,7 @@ e_editor_selection_get_italic (EEditorSelection *selection)
{
g_return_val_if_fail (E_IS_EDITOR_SELECTION (selection), FALSE);
- return get_has_style_property (selection, "fontStyle", "italic");
+ return get_has_style (selection, "i");
}
void
@@ -795,11 +833,54 @@ e_editor_selection_set_italic (EEditorSelection *selection,
}
gboolean
+e_editor_selection_get_monospaced (EEditorSelection *selection)
+{
+ g_return_val_if_fail (E_IS_EDITOR_SELECTION (selection), FALSE);
+
+ return get_has_style (selection, "tt");
+}
+
+void
+e_editor_selection_set_monospaced (EEditorSelection *selection,
+ gboolean monospaced)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMRange *range;
+
+ g_return_if_fail (E_IS_EDITOR_SELECTION (selection));
+
+ if ((e_editor_selection_get_monospaced (selection) ? TRUE : FALSE)
+ == (monospaced ? TRUE : FALSE)) {
+ return;
+ }
+
+ document = webkit_web_view_get_dom_document (selection->priv->webview);
+
+ range = editor_selection_get_current_range (selection);
+ if (!range) {
+ return;
+ }
+
+ if (monospaced) {
+ WebKitDOMElement *tt;
+
+ tt = webkit_dom_document_create_element (document, "TT", NULL);
+ webkit_dom_range_surround_contents (
+ range, WEBKIT_DOM_NODE (tt), NULL);
+
+ } else {
+ /* FIXME WEBKIT: this does not work yet :)
+ }
+
+ g_object_notify (G_OBJECT (selection), "monospaced");
+}
+
+gboolean
e_editor_selection_get_strike_through (EEditorSelection *selection)
{
g_return_val_if_fail (E_IS_EDITOR_SELECTION (selection), FALSE);
- return get_has_style_property (selection, "textDecoration", "overline");
+ return get_has_style (selection, "strike");
}
void
@@ -920,7 +1001,7 @@ e_editor_selection_get_underline (EEditorSelection *selection)
{
g_return_val_if_fail (E_IS_EDITOR_SELECTION (selection), FALSE);
- return get_has_style_property (selection, "textDecoration", "underline");
+ return get_has_style (selection, "u");
}
void
diff --git a/e-util/e-editor-selection.h b/e-util/e-editor-selection.h
index 176436e..8c6dccc 100644
--- a/e-util/e-editor-selection.h
+++ b/e-util/e-editor-selection.h
@@ -138,6 +138,12 @@ void e_editor_selection_set_italic (EEditorSelection *selection,
gboolean italic);
gboolean e_editor_selection_get_italic (EEditorSelection *selection);
+void e_editor_selection_set_monospaced
+ (EEditorSelection *selection,
+ gboolean monospaced);
+gboolean e_editor_selection_get_monospaced
+ (EEditorSelection *selection);
+
void e_editor_selection_set_strike_through
(EEditorSelection *selection,
gboolean strike_through);
diff --git a/e-util/e-editor-widget.c b/e-util/e-editor-widget.c
index a3b886a..9341c54 100644
--- a/e-util/e-editor-widget.c
+++ b/e-util/e-editor-widget.c
@@ -36,6 +36,8 @@ struct _EEditorWidgetPrivate {
gint can_redo : 1;
gint can_undo : 1;
+ EEditorSelection *selection;
+
EEditorWidgetMode mode;
/* FIXME WEBKIT Is this in widget's competence? */
@@ -237,6 +239,12 @@ e_editor_widget_set_property (GObject *object,
static void
e_editor_widget_finalize (GObject *object)
{
+ EEditorWidgetPrivate *priv = E_EDITOR_WIDGET (object)->priv;
+
+ g_clear_object (&priv->selection);
+
+ /* Chain up to parent's implementation */
+ G_OBJECT_CLASS (e_editor_widget_parent_class)->finalize (object);
}
static void
@@ -399,6 +407,9 @@ e_editor_widget_init (EEditorWidget *editor)
G_CALLBACK (editor_widget_user_changed_contents_cb), NULL);
g_signal_connect (editor, "selection-changed",
G_CALLBACK (editor_widget_selection_changed_cb), NULL);
+
+ editor->priv->selection = e_editor_selection_new (
+ WEBKIT_WEB_VIEW (editor));
}
EEditorWidget *
@@ -410,7 +421,9 @@ e_editor_widget_new (void)
EEditorSelection *
e_editor_widget_get_selection (EEditorWidget *widget)
{
- return e_editor_selection_new (WEBKIT_WEB_VIEW (widget));
+ g_return_val_if_fail (E_IS_EDITOR_WIDGET (widget), NULL);
+
+ return widget->priv->selection;
}
gboolean
diff --git a/e-util/e-editor.c b/e-util/e-editor.c
index 61bfdd9..c558e52 100644
--- a/e-util/e-editor.c
+++ b/e-util/e-editor.c
@@ -361,6 +361,7 @@ e_editor_init (EEditor *editor)
priv->spell_check_actions = gtk_action_group_new ("spell-check");
priv->suggestion_actions = gtk_action_group_new ("suggestion");
priv->editor_widget = e_editor_widget_new ();
+ priv->selection = e_editor_widget_get_selection (priv->editor_widget);
filename = editor_find_ui_file ("e-editor-manager.ui");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]