diff --git a/libdino/src/entity/settings.vala b/libdino/src/entity/settings.vala index 2aae6055..97ea5482 100644 --- a/libdino/src/entity/settings.vala +++ b/libdino/src/entity/settings.vala @@ -11,6 +11,7 @@ public class Settings : Object { send_marker_ = col_to_bool_or_default("send_marker", true); notifications_ = col_to_bool_or_default("notifications", true); convert_utf8_smileys_ = col_to_bool_or_default("convert_utf8_smileys", true); + check_spelling = col_to_bool_or_default("check_spelling", true); } private bool col_to_bool_or_default(string key, bool def) { @@ -65,6 +66,18 @@ public class Settings : Object { convert_utf8_smileys_ = value; } } + + private bool check_spelling_; + public bool check_spelling { + get { return check_spelling_; } + set { + db.settings.upsert() + .value(db.settings.key, "check_spelling", true) + .value(db.settings.value, value.to_string()) + .perform(); + check_spelling_ = value; + } + } } } diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala index 652971a0..17499404 100644 --- a/libdino/src/service/database.vala +++ b/libdino/src/service/database.vala @@ -7,7 +7,7 @@ using Dino.Entities; namespace Dino { public class Database : Qlite.Database { - private const int VERSION = 18; + private const int VERSION = 19; public class AccountTable : Table { public Column id = new Column.Integer("id") { primary_key = true, auto_increment = true }; @@ -254,6 +254,19 @@ public class Database : Qlite.Database { } } + public class ConversationSettingsTable : Table { + public Column id = new Column.Integer("id") { primary_key = true, auto_increment = true }; + public Column conversation_id = new Column.Integer("conversation_id") {not_null=true}; + public Column key = new Column.Text("key") { not_null=true }; + public Column value = new Column.Text("value"); + + internal ConversationSettingsTable(Database db) { + base(db, "conversation_settings"); + init({id, conversation_id, key, value}); + index("settings_conversationid_key", { conversation_id, key }, true); + } + } + public AccountTable account { get; private set; } public JidTable jid { get; private set; } public EntityTable entity { get; private set; } @@ -269,6 +282,7 @@ public class Database : Qlite.Database { public RosterTable roster { get; private set; } public MamCatchupTable mam_catchup { get; private set; } public SettingsTable settings { get; private set; } + public ConversationSettingsTable conversation_settings { get; private set; } public Map jid_table_cache = new HashMap(); public Map jid_table_reverse = new HashMap(Jid.hash_func, Jid.equals_func); @@ -291,7 +305,8 @@ public class Database : Qlite.Database { roster = new RosterTable(this); mam_catchup = new MamCatchupTable(this); settings = new SettingsTable(this); - init({ account, jid, entity, content_item, message, message_correction, real_jid, file_transfer, conversation, avatar, entity_identity, entity_feature, roster, mam_catchup, settings }); + conversation_settings = new ConversationSettingsTable(this); + init({ account, jid, entity, content_item, message, message_correction, real_jid, file_transfer, conversation, avatar, entity_identity, entity_feature, roster, mam_catchup, settings, conversation_settings }); try { exec("PRAGMA journal_mode = WAL"); diff --git a/main/data/settings_dialog.ui b/main/data/settings_dialog.ui index c76f347e..d5b7ac92 100644 --- a/main/data/settings_dialog.ui +++ b/main/data/settings_dialog.ui @@ -65,6 +65,18 @@ 1 + + + Check spelling + True + + + 0 + 4 + 1 + 1 + + diff --git a/main/src/ui/chat_input/spell_checker.vala b/main/src/ui/chat_input/spell_checker.vala index a05d9251..8359b1b4 100644 --- a/main/src/ui/chat_input/spell_checker.vala +++ b/main/src/ui/chat_input/spell_checker.vala @@ -9,26 +9,64 @@ namespace Dino.Ui { public class SpellChecker { private Conversation? conversation; - private TextView gspell_view; - private HashMap language_cache = new HashMap(Conversation.hash_func, Conversation.equals_func); + private TextView text_view; + private TextBuffer text_buffer; public SpellChecker(Gtk.TextView text_input) { - this.gspell_view = TextView.get_from_gtk_text_view(text_input); - gspell_view.basic_setup(); + this.text_view = TextView.get_from_gtk_text_view(text_input); + this.text_buffer = TextBuffer.get_from_gtk_text_buffer(text_view.view.buffer); + + text_view.basic_setup(); + text_buffer.spell_checker.notify["language"].connect(lang_changed); + + // Enable/Disable spell checking live + Dino.Application.get_default().settings.notify["check-spelling"].connect((obj, _) => { + if (((Dino.Entities.Settings) obj).check_spelling) { + initialize_for_conversation(this.conversation); + } else { + text_buffer.set_spell_checker(null); + } + }); } public void initialize_for_conversation(Conversation conversation) { - Checker spell_checker = TextBuffer.get_from_gtk_text_buffer(gspell_view.view.buffer).spell_checker; - - if (this.conversation != null) language_cache[this.conversation] = spell_checker.language; - this.conversation = conversation; - if (language_cache.has_key(this.conversation)) { - spell_checker.language = language_cache[conversation]; - } else { - spell_checker.language = null; + if (!Dino.Application.get_default().settings.check_spelling) { + text_buffer.set_spell_checker(null); + return; } + if (text_buffer.spell_checker == null) text_buffer.spell_checker = new Checker(null); + + // Set the conversation language (from cache or db) + text_buffer.spell_checker.notify["language"].disconnect(lang_changed); + + var db = Dino.Application.get_default().db; + Qlite.RowOption row_option = db.conversation_settings.select() + .with(db.conversation_settings.conversation_id, "=", conversation.id) + .with(db.conversation_settings.key, "=", "lang") + .single().row(); + if (row_option.is_present()) { + string lang_code = row_option.inner[db.conversation_settings.value]; + Language? lang = Language.lookup(lang_code); + text_buffer.spell_checker.language = lang; + } else { + text_buffer.spell_checker.language = null; + } + + text_buffer.spell_checker.notify["language"].connect(lang_changed); + } + + private void lang_changed() { + var db = Dino.Application.get_default().db; + + Checker spell_checker = text_buffer.spell_checker; + if (spell_checker.language.get_code() == null) return; + db.conversation_settings.upsert() + .value(db.conversation_settings.conversation_id, conversation.id, true) + .value(db.conversation_settings.key, "lang", true) + .value(db.conversation_settings.value, spell_checker.language.get_code()) + .perform(); } } diff --git a/main/src/ui/settings_dialog.vala b/main/src/ui/settings_dialog.vala index 68c711dc..a24b9c22 100644 --- a/main/src/ui/settings_dialog.vala +++ b/main/src/ui/settings_dialog.vala @@ -9,6 +9,7 @@ class SettingsDialog : Dialog { [GtkChild] private CheckButton marker_checkbutton; [GtkChild] private CheckButton notification_checkbutton; [GtkChild] private CheckButton emoji_checkbutton; + [GtkChild] private CheckButton check_spelling_checkbutton; Dino.Entities.Settings settings = Dino.Application.get_default().settings; @@ -19,11 +20,13 @@ class SettingsDialog : Dialog { marker_checkbutton.active = settings.send_marker; notification_checkbutton.active = settings.notifications; emoji_checkbutton.active = settings.convert_utf8_smileys; + check_spelling_checkbutton.active = settings.check_spelling; typing_checkbutton.toggled.connect(() => { settings.send_typing = typing_checkbutton.active; } ); marker_checkbutton.toggled.connect(() => { settings.send_marker = marker_checkbutton.active; } ); notification_checkbutton.toggled.connect(() => { settings.notifications = notification_checkbutton.active; } ); emoji_checkbutton.toggled.connect(() => { settings.convert_utf8_smileys = emoji_checkbutton.active; }); + check_spelling_checkbutton.toggled.connect(() => { settings.check_spelling = check_spelling_checkbutton.active; }); } }