[geary] Allow HTML signatures
- From: Robert Schroll <rschroll src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary] Allow HTML signatures
- Date: Thu, 29 Jan 2015 22:27:55 +0000 (UTC)
commit c87bbea3ab06121f5fbb23658cb2320efd55aad8
Author: Robert Schroll <rschroll gmail com>
Date: Mon Dec 1 20:14:21 2014 -0500
Allow HTML signatures
We search for HTML-like tags in signatures, and don't do much as much
escaping if we find one. For .signature files detected to be HTML, we
insert them without any change. User-entered signatures get their
whitespace protected, even when HTML is detected. The existing code for
preserving whitespace doesn't work when there's already HTML code in the
text (it converts "<a b>" to "<a b>"), so instead we preserve the
whitespace with CSS.
A preview of the signature is added to the the UI. There's a TextView
and a WebView in a Stack, and we swap between them with a StackSwitcher.
Some of the packing details are changed so that these views are the
thing that expands when the dialog size changes.
https://bugzilla.gnome.org/show_bug.cgi?id=738895
.../accounts/account-dialog-add-edit-pane.vala | 2 +-
src/client/accounts/add-edit-page.vala | 42 ++++++++++++++++----
src/client/composer/composer-widget.vala | 10 ++--
src/engine/util/util-html.vala | 15 +++++++
ui/login.glade | 24 +++++-------
5 files changed, 65 insertions(+), 28 deletions(-)
---
diff --git a/src/client/accounts/account-dialog-add-edit-pane.vala
b/src/client/accounts/account-dialog-add-edit-pane.vala
index 80ad80e..4a90f45 100644
--- a/src/client/accounts/account-dialog-add-edit-pane.vala
+++ b/src/client/accounts/account-dialog-add-edit-pane.vala
@@ -38,7 +38,7 @@ public class AccountDialogAddEditPane : AccountDialogPane {
add_edit_page.size_changed.connect(() => { size_changed(); } );
pack_start(add_edit_page);
- pack_start(button_box);
+ pack_start(button_box, false, false);
// Default mode is Welcome.
set_mode(AddEditPage.PageMode.WELCOME);
diff --git a/src/client/accounts/add-edit-page.vala b/src/client/accounts/add-edit-page.vala
index 567b529..a78d5df 100644
--- a/src/client/accounts/add-edit-page.vala
+++ b/src/client/accounts/add-edit-page.vala
@@ -173,7 +173,9 @@ public class AddEditPage : Gtk.Box {
// Signature
private Gtk.Box composer_container;
private Gtk.CheckButton check_use_email_signature;
+ private Gtk.Stack signature_stack;
private Gtk.TextView textview_email_signature;
+ private StylishWebView preview_webview;
private Gtk.Alignment other_info;
@@ -257,7 +259,32 @@ public class AddEditPage : Gtk.Box {
// composer options
composer_container = (Gtk.Box) builder.get_object("composer container");
check_use_email_signature = (Gtk.CheckButton) builder.get_object("check: use_email_signature");
- textview_email_signature = (Gtk.TextView) builder.get_object("textview: email_signature");
+
+ Gtk.ScrolledWindow edit_window = new Gtk.ScrolledWindow(null, null);
+ edit_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
+ edit_window.set_shadow_type(Gtk.ShadowType.IN);
+ textview_email_signature = new Gtk.TextView();
+ edit_window.add(textview_email_signature);
+
+ Gtk.ScrolledWindow preview_window = new Gtk.ScrolledWindow(null, null);
+ preview_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
+ preview_window.set_shadow_type(Gtk.ShadowType.IN);
+ preview_webview = new StylishWebView();
+ preview_window.add(preview_webview);
+
+ signature_stack = new Gtk.Stack();
+ signature_stack.add_titled(edit_window, "edit_window", _("Edit"));
+ signature_stack.child_set_property(edit_window, "icon-name", "text-editor-symbolic");
+ signature_stack.add_titled(preview_window, "preview_window", _("Preview"));
+ signature_stack.child_set_property(preview_window, "icon-name", "text-x-generic-symbolic");
+ Gtk.StackSwitcher switcher = new Gtk.StackSwitcher();
+ switcher.set_stack(signature_stack);
+
+ Gtk.Box signature_box = (Gtk.Box) builder.get_object("signature box");
+ signature_box.set_spacing(4);
+ signature_box.pack_start(signature_stack);
+ switcher.valign = Gtk.Align.START;
+ signature_box.pack_start(switcher, false, false);
// IMAP info widgets.
entry_imap_host = (Gtk.Entry) builder.get_object("entry: imap host");
@@ -316,7 +343,8 @@ public class AddEditPage : Gtk.Box {
entry_nickname.insert_text.connect(on_nickname_insert_text);
- check_use_email_signature.toggled.connect(() => on_use_signature_changed());
+ check_use_email_signature.bind_property("active", signature_box, "sensitive");
+ signature_stack.notify["visible-child-name"].connect(on_signature_stack_changed);
// Reset the "first update" flag when the window is mapped.
map.connect(() => { first_ui_update = true; });
@@ -394,6 +422,7 @@ public class AddEditPage : Gtk.Box {
combo_smtp_encryption.active = Encryption.NONE;
use_email_signature = initial_use_email_signature;
email_signature = initial_email_signature;
+ signature_stack.set_visible_child_name("edit_window");
// Set defaults for IMAP info
imap_host = initial_default_imap_host ?? "";
@@ -550,12 +579,9 @@ public class AddEditPage : Gtk.Box {
}
}
- private void on_use_signature_changed() {
- if(check_use_email_signature.active == true) {
- textview_email_signature.sensitive = true;
- } else {
- textview_email_signature.sensitive = false;
- }
+ private void on_signature_stack_changed() {
+ if (signature_stack.visible_child_name == "preview_window")
+ preview_webview.load_html_string(Geary.HTML.smart_escape(email_signature, true), "");
}
private uint16 get_default_smtp_port() {
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index 09a48cf..78a6a3d 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -993,6 +993,7 @@ public class ComposerWidget : Gtk.EventBox {
set_cursor();
return;
}
+ signature = Geary.HTML.smart_escape(signature, false);
} catch (Error error) {
debug("Error reading signature file %s: %s", signature_file.get_path(), error.message);
set_cursor();
@@ -1004,16 +1005,15 @@ public class ComposerWidget : Gtk.EventBox {
set_cursor();
return;
}
+ signature = Geary.HTML.smart_escape(signature, true);
}
- signature = Geary.HTML.escape_markup(signature);
-
if (body_html == null)
- body_html = CURSOR + Geary.HTML.preserve_whitespace("\n\n" + signature);
+ body_html = CURSOR + "<br /><br />" + signature;
else if (top_posting)
- body_html = CURSOR + Geary.HTML.preserve_whitespace("\n\n" + signature) + body_html;
+ body_html = CURSOR + "<br /><br />" + signature + body_html;
else
- body_html = body_html + CURSOR + Geary.HTML.preserve_whitespace("\n\n" + signature);
+ body_html = body_html + CURSOR + "<br /><br />" + signature;
}
private void set_cursor() {
diff --git a/src/engine/util/util-html.vala b/src/engine/util/util-html.vala
index ce34ec5..561c9d9 100644
--- a/src/engine/util/util-html.vala
+++ b/src/engine/util/util-html.vala
@@ -88,6 +88,21 @@ public string preserve_whitespace(string? text) {
return output;
}
+public string smart_escape(string? text, bool preserve_whitespace_in_html) {
+ if (text == null)
+ return text;
+
+ string res = text;
+ if (!Regex.match_simple("<([A-Z]*)[^>]*>.*</(\\1)>|<[^>]*/>", res,
+ RegexCompileFlags.CASELESS)) {
+ res = escape_markup(res);
+ preserve_whitespace_in_html = true;
+ }
+ if (preserve_whitespace_in_html)
+ res = @"<div style='white-space: pre;'>$res</div>";
+ return res;
+}
+
// Removes any text between < and >. Additionally, if input terminates in the middle of a tag,
// the tag will be removed.
// If the HTML is invalid, the original string will be returned.
diff --git a/ui/login.glade b/ui/login.glade
index 390e789..1e85ad0 100644
--- a/ui/login.glade
+++ b/ui/login.glade
@@ -7,7 +7,6 @@
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
- <object class="GtkTextBuffer" id="buffer: email_signature"/>
<object class="GtkBox" id="container">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -960,7 +959,7 @@
</child>
<child>
<object class="GtkCheckButton" id="check: use_email_signature">
- <property name="label" translatable="yes">Si_gn emails:</property>
+ <property name="label" translatable="yes">Si_gn emails (HTML allowed):</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@@ -976,23 +975,20 @@
</packing>
</child>
<child>
- <object class="GtkScrolledWindow" id="scrolledwindow2">
+ <object class="GtkBox" id="signature box">
<property name="visible">True</property>
- <property name="can_focus">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">False</property>
<property name="margin_left">12</property>
- <property name="shadow_type">in</property>
<child>
- <object class="GtkTextView" id="textview: email_signature">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="wrap_mode">word</property>
- <property name="buffer">buffer: email_signature</property>
- </object>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
</child>
</object>
<packing>
- <property name="expand">False</property>
+ <property name="expand">True</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
@@ -1002,7 +998,7 @@
</child>
</object>
<packing>
- <property name="expand">False</property>
+ <property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]