[gnome-characters/bilelmoussaoui/gtk4: 3/7] characters view: load latin scripts correctly




commit efc164528ac6a2c13a7c2edf52819752c537f99b
Author: Bilal Elmoussaoui <bil elmoussaoui gmail com>
Date:   Wed Nov 24 14:59:33 2021 +0100

    characters view: load latin scripts correctly

 src/charactersView.js | 164 ++++++++++++++++++++++++++++++++++++++++----------
 src/sidebar.js        | 124 +-------------------------------------
 src/sidebarRow.js     |   2 +-
 src/window.js         |  16 ++---
 4 files changed, 144 insertions(+), 162 deletions(-)
---
diff --git a/src/charactersView.js b/src/charactersView.js
index 6700f41..9943730 100644
--- a/src/charactersView.js
+++ b/src/charactersView.js
@@ -17,7 +17,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
-const { Gc, Gdk, GLib, Gio, GObject, Gtk, Pango, Graphene } = imports.gi;
+const { Gc, Gdk, Gio, GnomeDesktop, GObject, Gtk, Pango, Graphene } = imports.gi;
 
 const Util = imports.util;
 
@@ -181,6 +181,12 @@ var CharactersView = GObject.registerClass({
         'vadjustment': GObject.ParamSpec.override('vadjustment', Gtk.Scrollable),
         'hscroll-policy': GObject.ParamSpec.override('hscroll-policy', Gtk.Scrollable),
         'hadjustment': GObject.ParamSpec.override('hadjustment', Gtk.Scrollable),
+        'loading': GObject.ParamSpec.boolean(
+            'loading',
+            'Loading', 'Whether the category is still loading',
+            GObject.ParamFlags.READWRITE,
+            false,
+        ),
     },
     Implements: [Gtk.Scrollable],
 }, class CharactersView extends Gtk.Widget {
@@ -191,18 +197,18 @@ var CharactersView = GObject.registerClass({
             overflow: Gtk.Overflow.HIDDEN,
         });
 
+        this._scripts = [];
+        this._scriptsLoaded = false;
+
         let context = this.get_pango_context();
         this._fontDescription = context.get_font_description();
         this._fontDescription.set_size(CELL_SIZE * Pango.SCALE);
 
-
         this._selectedCharacter = null;
         this._characters = [];
-        this._spinnerTimeoutId = 0;
         this._searchContext = null;
         this._cancellable = new Gio.Cancellable();
         this._cancellable.connect(() => {
-            this._stopSpinner();
             this._searchContext = null;
             this._characters = [];
         });
@@ -391,28 +397,8 @@ var CharactersView = GObject.registerClass({
         this.queue_draw();
     }
 
-    _startSpinner() {
-        this._stopSpinner();
-        this._spinnerTimeoutId =
-            GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, () => {
-                // this._loading_spinner.start();
-                // this.visible_child_name = 'loading';
-            });
-    }
-
-    _stopSpinner() {
-        if (this._spinnerTimeoutId > 0) {
-            GLib.source_remove(this._spinnerTimeoutId);
-            this._spinnerTimeoutId = 0;
-            // this._loading_spinner.stop();
-        }
-    }
-
     _finishSearch(result) {
-        this._stopSpinner();
-
         let characters = Util.searchResultToArray(result);
-
         this.setCharacters(characters);
     }
 
@@ -438,9 +424,7 @@ var CharactersView = GObject.registerClass({
     }
 
     _searchWithContext(context, count) {
-        this._startSpinner();
         context.search(count, this._cancellable, (ctx, res) => {
-            this._stopSpinner();
             try {
                 let result = ctx.search_finish(res);
                 this._addSearchResult(result);
@@ -452,10 +436,12 @@ var CharactersView = GObject.registerClass({
 
     searchByCategory(category) {
         this._characters = [];
-        /* if ('scripts' in category) {
-            this.searchByScripts(category.scripts);
+        if (category === Gc.Category.LETTER_LATIN) {
+            if (!this._scriptsLoaded)
+                this.populateScripts();
+            this._searchByScripts();
             return;
-        }*/
+        }
 
         let criteria = Gc.SearchCriteria.new_category(category);
         this._searchContext = new Gc.SearchContext({ criteria });
@@ -472,8 +458,8 @@ var CharactersView = GObject.registerClass({
         return this._characters.length;
     }
 
-    searchByScripts(scripts) {
-        var criteria = Gc.SearchCriteria.new_scripts(scripts);
+    _searchByScripts() {
+        var criteria = Gc.SearchCriteria.new_scripts(this.scripts);
         this._searchContext = new Gc.SearchContext({ criteria });
         this._searchWithContext(this._searchContext, this.initialSearchCount);
     }
@@ -482,4 +468,120 @@ var CharactersView = GObject.registerClass({
         this._cancellable.cancel();
         this._cancellable.reset();
     }
+
+    // / Specific to GC_CATEGORY_LETTER_LATIN
+    get scripts() {
+        return this._scripts;
+    }
+
+    // / Populate the "scripts" based on the current locale
+    // / and the input-sources settings.
+    populateScripts() {
+        this.loading = true;
+        let settings =
+            Util.getSettings('org.gnome.desktop.input-sources',
+                '/org/gnome/desktop/input-sources/');
+        if (settings) {
+            let sources = settings.get_value('sources').deep_unpack();
+            let hasIBus = sources.some((current, _index, _array) => {
+                return current[0] === 'ibus';
+            });
+            if (hasIBus)
+                this._ensureIBusLanguageList(sources);
+            else
+                this._finishBuildScriptList(sources);
+        }
+    }
+
+    _ensureIBusLanguageList(sources) {
+        if (this._ibusLanguageList !== null)
+            return;
+
+        this._ibusLanguageList = {};
+
+        // Don't assume IBus is always available.
+        let ibus;
+        try {
+            ibus = imports.gi.IBus;
+        } catch (e) {
+            this._finishBuildScriptList(sources);
+            return;
+        }
+
+        ibus.init();
+        let bus = new ibus.Bus();
+        if (bus.is_connected()) {
+            bus.list_engines_async(-1, null, (sources_, bus_, res) => {
+                this._finishListEngines(sources_, bus_, res);
+            });
+        } else {
+            this._finishBuildScriptList(sources);
+        }
+    }
+
+    _finishListEngines(sources, bus, res) {
+        try {
+            let engines = bus.list_engines_async_finish(res);
+            if (engines) {
+                for (let j in engines) {
+                    let engine = engines[j];
+                    let language = engine.get_language();
+                    if (language !== null)
+                        this._ibusLanguageList[engine.get_name()] = language;
+                }
+            }
+        } catch (e) {
+            log(`Failed to list engines: ${e.message}`);
+        }
+        this._finishBuildScriptList(sources);
+    }
+
+    _finishBuildScriptList(sources) {
+        let xkbInfo = new GnomeDesktop.XkbInfo();
+        let languages = [];
+        for (let i in sources) {
+            let [type, id] = sources[i];
+            switch (type) {
+            case 'xkb':
+                // FIXME: Remove this check once gnome-desktop gets the
+                // support for that.
+                if (xkbInfo.get_languages_for_layout) {
+                    languages = languages.concat(
+                        xkbInfo.get_languages_for_layout(id));
+                }
+                break;
+            case 'ibus':
+                if (id in this._ibusLanguageList)
+                    languages.push(this._ibusLanguageList[id]);
+                break;
+            }
+        }
+
+        // Add current locale language to languages.
+        languages.push(Gc.get_current_language());
+
+        let allScripts = [];
+        for (let i in languages) {
+            let language = GnomeDesktop.normalize_locale(languages[i]);
+            if (language === null)
+                continue;
+            let scripts = Gc.get_scripts_for_language(languages[i]);
+            for (let j in scripts) {
+                let script = scripts[j];
+                // Exclude Latin and Han, since Latin is always added
+                // at the top and Han contains too many characters.
+                if (['Latin', 'Han'].indexOf(script) >= 0)
+                    continue;
+                if (allScripts.indexOf(script) >= 0)
+                    continue;
+                allScripts.push(script);
+            }
+        }
+
+        allScripts.unshift('Latin');
+
+        this._scripts = allScripts;
+        this._scriptsLoaded = true;
+        this.loading = false;
+    }
 });
diff --git a/src/sidebar.js b/src/sidebar.js
index 48c613c..5ed9c91 100644
--- a/src/sidebar.js
+++ b/src/sidebar.js
@@ -18,9 +18,8 @@
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 
-const { Adw, Gc, GObject, GnomeDesktop } = imports.gi;
+const { Adw, GObject } = imports.gi;
 const { SidebarRow } = imports.sidebarRow;
-const Util = imports.util;
 
 var Sidebar = GObject.registerClass({
     Template: 'resource:///org/gnome/Characters/sidebar.ui',
@@ -94,125 +93,4 @@ var Sidebar = GObject.registerClass({
     get list() {
         return this._list;
     }
-
-    _finishListEngines(sources, bus, res) {
-        try {
-            let engines = bus.list_engines_async_finish(res);
-            if (engines) {
-                for (let j in engines) {
-                    let engine = engines[j];
-                    let language = engine.get_language();
-                    if (language !== null)
-                        this._ibusLanguageList[engine.get_name()] = language;
-                }
-            }
-        } catch (e) {
-            log(`Failed to list engines: ${e.message}`);
-        }
-        this._finishBuildScriptList(sources);
-    }
-
-    _ensureIBusLanguageList(sources) {
-        if (this._ibusLanguageList !== null)
-            return;
-
-        this._ibusLanguageList = {};
-
-        // Don't assume IBus is always available.
-        let ibus;
-        try {
-            ibus = imports.gi.IBus;
-        } catch (e) {
-            this._finishBuildScriptList(sources);
-            return;
-        }
-
-        ibus.init();
-        let bus = new ibus.Bus();
-        if (bus.is_connected()) {
-            bus.list_engines_async(-1, null, (sources_, bus_, res) => {
-                this._finishListEngines(sources_, bus_, res);
-            });
-        } else {
-            this._finishBuildScriptList(sources);
-        }
-    }
-
-    _finishBuildScriptList(sources) {
-        let xkbInfo = new GnomeDesktop.XkbInfo();
-        let languages = [];
-        for (let i in sources) {
-            let [type, id] = sources[i];
-            switch (type) {
-            case 'xkb':
-                // FIXME: Remove this check once gnome-desktop gets the
-                // support for that.
-                if (xkbInfo.get_languages_for_layout) {
-                    languages = languages.concat(
-                        xkbInfo.get_languages_for_layout(id));
-                }
-                break;
-            case 'ibus':
-                if (id in this._ibusLanguageList)
-                    languages.push(this._ibusLanguageList[id]);
-                break;
-            }
-        }
-
-        // Add current locale language to languages.
-        languages.push(Gc.get_current_language());
-
-        let allScripts = [];
-        for (let i in languages) {
-            let language = GnomeDesktop.normalize_locale(languages[i]);
-            if (language === null)
-                continue;
-            let scripts = Gc.get_scripts_for_language(languages[i]);
-            for (let j in scripts) {
-                let script = scripts[j];
-                // Exclude Latin and Han, since Latin is always added
-                // at the top and Han contains too many characters.
-                if (['Latin', 'Han'].indexOf(script) >= 0)
-                    continue;
-                if (allScripts.indexOf(script) >= 0)
-                    continue;
-                allScripts.push(script);
-            }
-        }
-
-        allScripts.unshift('Latin');
-        let category = this.getCategory('letters');
-        category.scripts = allScripts;
-    }
-
-    populateCategoryList() {
-        // Populate the "scripts" element of the "Letter" category
-        // object, based on the current locale and the input-sources
-        // settings.
-        //
-        // This works asynchronously, in the following call flow:
-        //
-        // _buildScriptList()
-        //    if an IBus input-source is configured:
-        //       _ensureIBusLanguageList()
-        //          ibus_bus_list_engines_async()
-        //             _finishListEngines()
-        //                _finishBuildScriptList()
-        //    else:
-        //       _finishBuildScriptList()
-        //
-        let settings =
-            Util.getSettings('org.gnome.desktop.input-sources',
-                '/org/gnome/desktop/input-sources/');
-        if (settings) {
-            let sources = settings.get_value('sources').deep_unpack();
-            let hasIBus = sources.some((current, _index, _array) => {
-                return current[0] === 'ibus';
-            });
-            if (hasIBus)
-                this._ensureIBusLanguageList(sources);
-            else
-                this._finishBuildScriptList(sources);
-        }
-    }
 });
diff --git a/src/sidebarRow.js b/src/sidebarRow.js
index 7caac9c..e7d3c6a 100644
--- a/src/sidebarRow.js
+++ b/src/sidebarRow.js
@@ -46,6 +46,7 @@ var SidebarRow = GObject.registerClass({
         super._init({
             accessible_role: Gtk.AccessibleRole.ROW,
         });
+        this._scripts = [];
 
         let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL });
 
@@ -65,7 +66,6 @@ var SidebarRow = GObject.registerClass({
         this.connect('notify::title', row => {
             row.tooltip_text = _('%s Sidebar Row').format(row.title);
         });
-
         hbox.append(label);
 
         this.set_child(hbox);
diff --git a/src/window.js b/src/window.js
index d2eb11f..7417af6 100644
--- a/src/window.js
+++ b/src/window.js
@@ -98,13 +98,6 @@ var MainWindow = GObject.registerClass({
                 parameterType: new GLib.VariantType('b'),
                 state: new GLib.Variant('b', false) },
             { name: 'find', activate: this._find },
-            { name: 'category',
-                activate: this._category,
-                parameterType: new GLib.VariantType('s'),
-                state: new GLib.Variant('s', 'emoji-smileys') },
-            { name: 'character',
-                activate: this._character,
-                parameterType: new GLib.VariantType('s') },
             {
                 name: 'show-primary-menu',
                 activate: this._togglePrimaryMenu,
@@ -127,6 +120,14 @@ var MainWindow = GObject.registerClass({
             this._leaflet.navigate(Adw.NavigationDirection.BACK);
         });
 
+        this._charactersView.connect('notify::loading', view => {
+            if (view.loading) {
+                this._mainStack.visible_child_name = 'loading';
+            } else {
+                this._mainStack.visible_child_name = 'character-list';
+                this._mainStack.queue_draw();
+            }
+        });
         // Due to limitations of gobject-introspection wrt GdkEvent
         // and GdkEventKey, this needs to be a signal handler
         // TODO: use EventControllerKey
@@ -264,6 +265,7 @@ var MainWindow = GObject.registerClass({
             }
         } else {
             this._charactersView.searchByCategory(pageRow.category);
+
             this._mainStack.visible_child_name = 'character-list';
             // this._charactersView.model = pageRow.model;
         }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]