From f69c461955e4a2b408995297627ef704fa3d5267 Mon Sep 17 00:00:00 2001 From: Michael James Gratton Date: Wed, 4 Jan 2017 03:32:50 +1100 Subject: [PATCH] Re-enable spell checking in composer. * src/client/application/geary-config.vala (Configuration): Remove spell-check setting, we can just get it from the list of visible languages instead. Update the schema. * src/client/components/client-web-view.vala (WebView::init_web_context): Pass in a config object, use that to init WebKit's spell checking on the WebContext now that is a global configuration, update it when the config changes, update call sites. * src/client/composer/composer-widget.vala (ComposerWidget): Remove WK1-syle spell checking settings prefs. * src/client/composer/spell-check-popover.vala (SpellCheckPopover): Pass a config object in so we don't have to use the global app singleton instance. * src/client/dialogs/preferences-dialog.vala (PreferencesDialog): Modernise by converting into a widget template. * test/client/components/client-web-view-test-case.vala (TestCase): Construct a config object as a fixture, use it to init the WebContext and make it avalaible to subclasses & update subclasses. * ui/preferences-dialog.ui: Moved from preferences.dialog, remove spell check preference. --- desktop/org.gnome.Geary.gschema.xml | 6 -- src/client/application/geary-application.vala | 2 +- src/client/application/geary-config.vala | 5 -- src/client/application/geary-controller.vala | 1 + src/client/components/client-web-view.vala | 14 +++- src/client/composer/composer-widget.vala | 23 ++---- src/client/composer/spell-check-popover.vala | 31 ++++---- src/client/dialogs/preferences-dialog.vala | 70 ++++++++++++------- .../components/client-web-view-test-case.vala | 10 ++- .../composer/composer-web-view-test.vala | 3 +- test/js/composer-page-state-test.vala | 3 +- ui/CMakeLists.txt | 2 +- ...references.glade => preferences-dialog.ui} | 66 ++++------------- 13 files changed, 106 insertions(+), 130 deletions(-) rename ui/{preferences.glade => preferences-dialog.ui} (80%) diff --git a/desktop/org.gnome.Geary.gschema.xml b/desktop/org.gnome.Geary.gschema.xml index 4a70038e..4bcd5d89 100644 --- a/desktop/org.gnome.Geary.gschema.xml +++ b/desktop/org.gnome.Geary.gschema.xml @@ -62,12 +62,6 @@ True if we should display a short preview of each message. - - true - enable inline spell checking - True to spell check while typing. - - [] Languages that shall be used in the spell checker diff --git a/src/client/application/geary-application.vala b/src/client/application/geary-application.vala index 89ea07c1..ebba8a5e 100644 --- a/src/client/application/geary-application.vala +++ b/src/client/application/geary-application.vala @@ -470,7 +470,7 @@ public class GearyApplication : Gtk.Application { } private void on_activate_preferences() { - PreferencesDialog dialog = new PreferencesDialog(get_active_window()); + PreferencesDialog dialog = new PreferencesDialog(get_active_window(), this); dialog.run(); } diff --git a/src/client/application/geary-config.vala b/src/client/application/geary-config.vala index 8df13d85..060d3ef4 100644 --- a/src/client/application/geary-config.vala +++ b/src/client/application/geary-config.vala @@ -19,7 +19,6 @@ public class Configuration { public const string MESSAGES_PANE_POSITION_KEY = "messages-pane-position"; public const string AUTOSELECT_KEY = "autoselect"; public const string DISPLAY_PREVIEW_KEY = "display-preview"; - public const string SPELL_CHECK_KEY = "spell-check"; public const string PLAY_SOUNDS_KEY = "play-sounds"; public const string SHOW_NOTIFICATIONS_KEY = "show-notifications"; public const string STARTUP_NOTIFICATIONS_KEY = "startup-notifications"; @@ -104,10 +103,6 @@ public class Configuration { public bool display_preview { get { return settings.get_boolean(DISPLAY_PREVIEW_KEY); } } - - public bool spell_check { - get { return settings.get_boolean(SPELL_CHECK_KEY); } - } public string[] spell_check_languages { owned get { diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala index be666a31..e2feefe7 100644 --- a/src/client/application/geary-controller.vala +++ b/src/client/application/geary-controller.vala @@ -190,6 +190,7 @@ public class GearyController : Geary.BaseObject { // Initialise WebKit and WebViews ClientWebView.init_web_context( + this.application.config, this.application.get_web_extensions_dir(), Args.log_debug ); diff --git a/src/client/components/client-web-view.vala b/src/client/components/client-web-view.vala index 546ebea9..52a4f531 100644 --- a/src/client/components/client-web-view.vala +++ b/src/client/components/client-web-view.vala @@ -39,7 +39,8 @@ public class ClientWebView : WebKit.WebView { /** * Initialises WebKit.WebContext for use by the client. */ - public static void init_web_context(File web_extension_dir, + public static void init_web_context(Configuration config, + File web_extension_dir, bool enable_logging) { WebKit.WebContext context = WebKit.WebContext.get_default(); context.set_process_model(WebKit.ProcessModel.SHARED_SECONDARY_PROCESS); @@ -64,6 +65,11 @@ public class ClientWebView : WebKit.WebView { new Variant.boolean(enable_logging) ); }); + + update_spellcheck(context, config); + config.settings.changed[Configuration.SPELL_CHECK_LANGUAGES].connect(() => { + update_spellcheck(context, config); + }); } /** @@ -123,6 +129,12 @@ public class ClientWebView : WebKit.WebView { ); } + private static inline void update_spellcheck(WebKit.WebContext context, + Configuration config) { + context.set_spell_checking_enabled(config.spell_check_languages.length > 0); + context.set_spell_checking_languages(config.spell_check_languages); + } + private static inline uint to_wk2_font_size(Pango.FontDescription font) { Gdk.Screen? screen = Gdk.Screen.get_default(); double dpi = screen != null ? screen.get_resolution() : 96.0; diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala index 61ed8cb9..b5fc3a16 100644 --- a/src/client/composer/composer-widget.vala +++ b/src/client/composer/composer-widget.vala @@ -467,16 +467,6 @@ public class ComposerWidget : Gtk.EventBox { this.editor.load_html(this.body_html, this.signature_html, this.top_posting); - GearyApplication.instance.config.settings.changed[Configuration.SPELL_CHECK_KEY].connect( - on_spell_check_changed); - - // WebKit.Settings s = this.editor.settings; - // s.enable_spell_checking = GearyApplication.instance.config.spell_check; - // s.spell_checking_languages = string.joinv( - // ",", GearyApplication.instance.config.spell_check_languages - // ); - // this.editor.settings = s; - this.editor_scrolled.add(editor); // Place the message area before the compose toolbar in the focus chain, so that @@ -792,7 +782,6 @@ public class ComposerWidget : Gtk.EventBox { // This is safe to call even when this connection hasn't been made. realize.disconnect(on_load_finished_and_realized); - on_spell_check_changed(); update_actions(); this.actions.change_action_state(ACTION_SHOW_EXTENDED, false); @@ -1833,11 +1822,6 @@ public class ComposerWidget : Gtk.EventBox { update_message_overlay_label_style(); } - private void on_spell_check_changed() { - //this.editor.settings.enable_spell_checking = GearyApplication.instance.config.spell_check; - //get_action(ACTION_SELECT_DICTIONARY).set_enabled(this.editor.settings.enable_spell_checking); - } - // This overrides the keypress handling for the *widget*; the WebView editor's keypress overrides // are handled by on_editor_key_press public override bool key_press_event(Gdk.EventKey event) { @@ -1910,10 +1894,11 @@ public class ComposerWidget : Gtk.EventBox { private void on_select_dictionary(SimpleAction action, Variant? param) { if (this.spell_check_popover == null) { - this.spell_check_popover = new SpellCheckPopover(select_dictionary_button); + this.spell_check_popover = new SpellCheckPopover( + this.select_dictionary_button, this.config + ); this.spell_check_popover.selection_changed.connect((active_langs) => { - //this.editor.settings.spell_checking_languages = string.joinv(",", active_langs); - GearyApplication.instance.config.spell_check_languages = active_langs; + this.config.spell_check_languages = active_langs; }); } this.spell_check_popover.toggle(); diff --git a/src/client/composer/spell-check-popover.vala b/src/client/composer/spell-check-popover.vala index 0ff12872..c16b8968 100644 --- a/src/client/composer/spell-check-popover.vala +++ b/src/client/composer/spell-check-popover.vala @@ -21,6 +21,7 @@ public class SpellCheckPopover { private Gtk.SearchEntry search_box; private Gtk.ScrolledWindow view; private Gtk.Box content; + private Configuration config; private enum SpellCheckStatus { INACTIVE, @@ -50,9 +51,12 @@ public class SpellCheckPopover { private Gtk.Image active_image; private Gtk.Button remove_button; private SpellCheckStatus lang_active = SpellCheckStatus.INACTIVE; + private Configuration config; - public SpellCheckLangRow (string lang_code) { + public SpellCheckLangRow (string lang_code, Configuration config) { this.lang_code = lang_code; + this.config = config; + Gtk.Box box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 6); lang_name = International.language_name_from_locale(lang_code); @@ -78,12 +82,12 @@ public class SpellCheckPopover { remove_button.clicked.connect(on_remove_clicked); is_lang_visible = false; - foreach (string visible_lang in GearyApplication.instance.config.spell_check_visible_languages) { + foreach (string visible_lang in this.config.spell_check_visible_languages) { if (visible_lang == lang_code) is_lang_visible = true; } - foreach (string active_lang in GearyApplication.instance.config.spell_check_languages) { + foreach (string active_lang in this.config.spell_check_languages) { if (active_lang == lang_code) lang_active = SpellCheckStatus.ACTIVE; } @@ -125,17 +129,17 @@ public class SpellCheckPopover { set_lang_active(SpellCheckStatus.INACTIVE); if (is_lang_visible) { - string[] visible_langs = GearyApplication.instance.config.spell_check_visible_languages; + string[] visible_langs = this.config.spell_check_visible_languages; visible_langs += lang_code; - GearyApplication.instance.config.spell_check_visible_languages = visible_langs; + this.config.spell_check_visible_languages = visible_langs; } else { string[] visible_langs = {}; - foreach (string lang in GearyApplication.instance.config.spell_check_visible_languages) { + foreach (string lang in this.config.spell_check_visible_languages) { if (lang != lang_code) visible_langs += lang; } - GearyApplication.instance.config.spell_check_visible_languages = visible_langs; + this.config.spell_check_visible_languages = visible_langs; } visibility_changed(); @@ -154,9 +158,9 @@ public class SpellCheckPopover { case SpellCheckStatus.ACTIVE: // If the lang is not visible make it visible now if (!is_lang_visible) { - string[] visible_langs = GearyApplication.instance.config.spell_check_visible_languages; + string[] visible_langs = this.config.spell_check_visible_languages; visible_langs += lang_code; - GearyApplication.instance.config.spell_check_visible_languages = visible_langs; + this.config.spell_check_visible_languages = visible_langs; is_lang_visible = true; } break; @@ -189,9 +193,10 @@ public class SpellCheckPopover { } } - public SpellCheckPopover(Gtk.Widget button) { - popover = new Gtk.Popover(button); - selected_rows = new GLib.GenericSet(GLib.str_hash, GLib.str_equal); + public SpellCheckPopover(Gtk.Widget button, Configuration config) { + this.popover = new Gtk.Popover(button); + this.config = config; + this.selected_rows = new GLib.GenericSet(GLib.str_hash, GLib.str_equal); setup_popover(); } @@ -219,7 +224,7 @@ public class SpellCheckPopover { langs_list = new Gtk.ListBox(); langs_list.set_selection_mode(Gtk.SelectionMode.NONE); foreach (string lang in languages) { - SpellCheckLangRow row = new SpellCheckLangRow(lang); + SpellCheckLangRow row = new SpellCheckLangRow(lang, this.config); langs_list.add(row); if (row.is_lang_active()) diff --git a/src/client/dialogs/preferences-dialog.vala b/src/client/dialogs/preferences-dialog.vala index 90286b29..1af91a09 100644 --- a/src/client/dialogs/preferences-dialog.vala +++ b/src/client/dialogs/preferences-dialog.vala @@ -4,34 +4,52 @@ * (version 2.1 or later). See the COPYING file in this distribution. */ -public class PreferencesDialog : Object { - private Gtk.Dialog dialog; - - public PreferencesDialog(Gtk.Window parent) { - Gtk.Builder builder = GearyApplication.instance.create_builder("preferences.glade"); - - // Get all of the dialog elements. - dialog = builder.get_object("dialog") as Gtk.Dialog; - dialog.set_transient_for(parent); - dialog.set_modal(true); - - Configuration config = GearyApplication.instance.config; - config.bind(Configuration.AUTOSELECT_KEY, builder.get_object("autoselect"), "active"); - config.bind(Configuration.DISPLAY_PREVIEW_KEY, builder.get_object("display_preview"), "active"); - config.bind(Configuration.FOLDER_LIST_PANE_HORIZONTAL_KEY, - builder.get_object("three_pane_view"), "active"); - config.bind(Configuration.SPELL_CHECK_KEY, builder.get_object("spell_check"), "active"); - config.bind(Configuration.PLAY_SOUNDS_KEY, builder.get_object("play_sounds"), "active"); - config.bind(Configuration.SHOW_NOTIFICATIONS_KEY, builder.get_object("show_notifications"), "active"); - config.bind(Configuration.STARTUP_NOTIFICATIONS_KEY, builder.get_object("startup_notifications"), "active"); +[GtkTemplate (ui = "/org/gnome/Geary/preferences-dialog.ui")] +public class PreferencesDialog : Gtk.Dialog { + + [GtkChild] + private Gtk.CheckButton autoselect; + + [GtkChild] + private Gtk.CheckButton display_preview; + + [GtkChild] + private Gtk.CheckButton three_pane_view; + + [GtkChild] + private Gtk.CheckButton play_sounds; + + [GtkChild] + private Gtk.CheckButton show_notifications; + + [GtkChild] + private Gtk.CheckButton startup_notifications; + + [GtkChild] + private Gtk.HeaderBar header; + + private GearyApplication app; + + public PreferencesDialog(Gtk.Window parent, GearyApplication app) { + set_transient_for(parent); + set_titlebar(this.header); + this.app = app; + + Configuration config = app.config; + config.bind(Configuration.AUTOSELECT_KEY, autoselect, "active"); + config.bind(Configuration.DISPLAY_PREVIEW_KEY, display_preview, "active"); + config.bind(Configuration.FOLDER_LIST_PANE_HORIZONTAL_KEY, three_pane_view, "active"); + config.bind(Configuration.PLAY_SOUNDS_KEY, play_sounds, "active"); + config.bind(Configuration.SHOW_NOTIFICATIONS_KEY, show_notifications, "active"); + config.bind(Configuration.STARTUP_NOTIFICATIONS_KEY, startup_notifications, "active"); } - - public void run() { + + public new void run() { // Sync startup notification option with file state - GearyApplication.instance.controller.autostart_manager.sync_with_config(); - dialog.show_all(); - dialog.run(); - dialog.destroy(); + this.app.controller.autostart_manager.sync_with_config(); + + base.run(); + destroy(); } } diff --git a/test/client/components/client-web-view-test-case.vala b/test/client/components/client-web-view-test-case.vala index 636a6ada..ddbe9a8d 100644 --- a/test/client/components/client-web-view-test-case.vala +++ b/test/client/components/client-web-view-test-case.vala @@ -10,14 +10,20 @@ extern const string _BUILD_ROOT_DIR; public abstract class ClientWebViewTestCase : Gee.TestCase { - protected V test_view = null; + protected V? test_view = null; + protected Configuration? config = null; public ClientWebViewTestCase(string name) { base(name); } public override void set_up() { - ClientWebView.init_web_context(File.new_for_path(_BUILD_ROOT_DIR).get_child("src"), true); + this.config = new Configuration(GearyApplication.APP_ID); + ClientWebView.init_web_context( + this.config, + File.new_for_path(_BUILD_ROOT_DIR).get_child("src"), + true + ); try { ClientWebView.load_scripts(); } catch (Error err) { diff --git a/test/client/composer/composer-web-view-test.vala b/test/client/composer/composer-web-view-test.vala index 034488b6..3af1e303 100644 --- a/test/client/composer/composer-web-view-test.vala +++ b/test/client/composer/composer-web-view-test.vala @@ -152,8 +152,7 @@ long, long, long, long, long, long, long, long, long, long, } catch (Error err) { assert_not_reached(); } - Configuration config = new Configuration(GearyApplication.APP_ID); - return new ComposerWebView(config); + return new ComposerWebView(this.config); } protected override void load_body_fixture(string? html = null) { diff --git a/test/js/composer-page-state-test.vala b/test/js/composer-page-state-test.vala index e23325b6..a4d580d8 100644 --- a/test/js/composer-page-state-test.vala +++ b/test/js/composer-page-state-test.vala @@ -152,8 +152,7 @@ class ComposerPageStateTest : ClientWebViewTestCase { } catch (Error err) { assert_not_reached(); } - Configuration config = new Configuration(GearyApplication.APP_ID); - return new ComposerWebView(config); + return new ComposerWebView(this.config); } protected override void load_body_fixture(string? html = null) { diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index 14b9d9de..c95061e9 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -29,7 +29,7 @@ set(RESOURCE_LIST STRIPBLANKS "main-toolbar.ui" STRIPBLANKS "main-window.ui" STRIPBLANKS "password-dialog.glade" - STRIPBLANKS "preferences.glade" + STRIPBLANKS "preferences-dialog.ui" STRIPBLANKS "remove_confirm.glade" STRIPBLANKS "toolbar_empty_menu.ui" STRIPBLANKS "toolbar_mark_menu.ui" diff --git a/ui/preferences.glade b/ui/preferences-dialog.ui similarity index 80% rename from ui/preferences.glade rename to ui/preferences-dialog.ui index caf4e53a..4488e396 100644 --- a/ui/preferences.glade +++ b/ui/preferences-dialog.ui @@ -1,18 +1,19 @@ + - +