[gnome-shell-extensions] workspace-indicator: add preferences dialog



commit 0bb2184efb08732599e523c79570653bb6532c67
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Wed Feb 22 01:15:53 2012 +0100

    workspace-indicator: add preferences dialog
    
    Add a simple pref dialog to configure workspace name, similar to
    the one available for GNOME 2.

 extensions/workspace-indicator/Makefile.am  |    2 +
 extensions/workspace-indicator/extension.js |   14 ++
 extensions/workspace-indicator/prefs.js     |  217 +++++++++++++++++++++++++++
 3 files changed, 233 insertions(+), 0 deletions(-)
---
diff --git a/extensions/workspace-indicator/Makefile.am b/extensions/workspace-indicator/Makefile.am
index 47210de..6620116 100644
--- a/extensions/workspace-indicator/Makefile.am
+++ b/extensions/workspace-indicator/Makefile.am
@@ -1,3 +1,5 @@
 EXTENSION_ID = workspace-indicator
 
+EXTRA_MODULES = prefs.js
+
 include ../../extension.mk
diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js
index e9acbd3..644af8c 100644
--- a/extensions/workspace-indicator/extension.js
+++ b/extensions/workspace-indicator/extension.js
@@ -1,3 +1,6 @@
+// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
+
+const Gio = imports.gi.Gio;
 const Meta = imports.gi.Meta;
 const Clutter = imports.gi.Clutter;
 const St = imports.gi.St;
@@ -16,6 +19,9 @@ const ExtensionUtils = imports.misc.extensionUtils;
 const Me = ExtensionUtils.getCurrentExtension();
 const Convenience = Me.imports.convenience;
 
+const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences';
+const WORKSPACE_KEY = 'workspace-names';
+
 const WorkspaceIndicator = new Lang.Class({
     Name: 'WorkspaceIndicator.WorkspaceIndicator',
     Extends: PanelMenu.Button,
@@ -43,12 +49,20 @@ const WorkspaceIndicator = new Lang.Class({
 	//styling
 	this.menu.actor.add_style_class_name('workspace-indicator-shorter');
 	this.statusLabel.add_style_class_name('panel-workspace-indicator');
+
+        this._settings = new Gio.Settings({ schema: WORKSPACE_SCHEMA });
+        this._settingsChangedId = this._settings.connect('changed::' + WORKSPACE_KEY, Lang.bind(this, this._createWorkspacesSection));
     },
 
     destroy: function() {
 	for (let i = 0; i < this._screenSignals.length; i++)
 	    global.screen.disconnect(this._screenSignals[i]);
 
+        if (this._settingsChangedId) {
+            this._settings.disconnect(this._settingsChangedId);
+            this._settingsChangedId = 0;
+        }
+
 	this.parent();
     },
 
diff --git a/extensions/workspace-indicator/prefs.js b/extensions/workspace-indicator/prefs.js
new file mode 100644
index 0000000..40a32ac
--- /dev/null
+++ b/extensions/workspace-indicator/prefs.js
@@ -0,0 +1,217 @@
+// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
+
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
+const Gtk = imports.gi.Gtk;
+const Lang = imports.lang;
+
+const Gettext = imports.gettext.domain('gnome-shell-extensions');
+const _ = Gettext.gettext;
+const N_ = function(e) { return e };
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Me = ExtensionUtils.getCurrentExtension();
+const Convenience = Me.imports.convenience;
+
+const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences';
+const WORKSPACE_KEY = 'workspace-names';
+
+const WorkspaceNameModel = new GObject.Class({
+    Name: 'WorkspaceIndicator.WorkspaceNameModel',
+    GTypeName: 'WorkspaceNameModel',
+    Extends: Gtk.ListStore,
+
+    Columns: {
+        LABEL: 0,
+    },
+
+    _init: function(params) {
+        this.parent(params);
+        this.set_column_types([GObject.TYPE_STRING]);
+
+        this._settings = new Gio.Settings({ schema: WORKSPACE_SCHEMA });
+        //this._settings.connect('changed::workspace-names', Lang.bind(this, this._reloadFromSettings));
+
+        this._reloadFromSettings();
+
+        // overriding class closure doesn't work, because GtkTreeModel
+        // plays tricks with marshallers and class closures
+        this.connect('row-changed', Lang.bind(this, this._onRowChanged));
+        this.connect('row-inserted', Lang.bind(this, this._onRowInserted));
+        this.connect('row-deleted', Lang.bind(this, this._onRowDeleted));
+    },
+
+    _reloadFromSettings: function() {
+        if (this._preventChanges)
+            return;
+        this._preventChanges = true;
+
+        print('reloading from settings');
+
+        let newNames = this._settings.get_strv(WORKSPACE_KEY);
+
+        let i = 0;
+        let [ok, iter] = this.get_iter_first();
+        while (ok && i < newNames.length) {
+            this.set(iter, [this.Columns.LABEL], [newNames[i]]);
+
+            ok = this.iter_next(iter);
+            i++;
+        }
+
+        while (ok)
+            ok = this.remove(iter);
+
+        for ( ; i < newNames.length; i++) {
+            iter = this.append();
+            this.set(iter, [this.Columns.LABEL], [newNames[i]]);
+        }
+
+        printerr('three');
+
+        this._preventChanges = false;
+    },
+
+    _onRowChanged: function(self, path, iter) {
+        if (this._preventChanges)
+            return;
+        this._preventChanges = true;
+
+        print('on_row_changed: ' + path.to_string());
+
+        let index = path.get_indices()[0];
+        let names = this._settings.get_strv(WORKSPACE_KEY);
+
+        if (index >= names.length) {
+            // fill with blanks
+            for (let i = names.length; i <= index; i++)
+                names[i] = '';
+        }
+
+        names[index] = this.get_value(iter, this.Columns.LABEL);
+
+        this._settings.set_strv(WORKSPACE_KEY, names);
+
+        this._preventChanges = false;
+    },
+
+    _onRowInserted: function(self, path, iter) {
+        if (this._preventChanges)
+            return;
+        this._preventChanges = true;
+
+        print('on_row_inserted: ' + path.to_string());
+
+        let index = path.get_indices()[0];
+        let names = this._settings.get_strv(WORKSPACE_KEY);
+        let label = this.get_value(iter, this.Columns.LABEL) || '';
+        names.splice(index, 0, label);
+
+        this._settings.set_strv(WORKSPACE_KEY, names);
+
+        this._preventChanges = false;
+    },
+
+    _onRowDeleted: function(self, path) {
+        if (this._preventChanges)
+            return;
+        this._preventChanges = true;
+
+        print('on_row_deleted: ' + path.to_string());
+
+        let index = path.get_indices()[0];
+        let names = this._settings.get_strv(WORKSPACE_KEY);
+
+        if (index >= names.length)
+            return;
+
+        names.splice(index, 1);
+
+        // compact the array
+        for (let i = names.length -1; i >= 0 && !names[i]; i++)
+            names.pop();
+
+        this._settings.set_strv(WORKSPACE_KEY, names);
+
+        this._preventChanges = false;
+    },
+});
+
+const WorkspaceSettingsWidget = new GObject.Class({
+    Name: 'WorkspaceIndicator.WorkspaceSettingsWidget',
+    GTypeName: 'WorkspaceSettingsWidget',
+    Extends: Gtk.Grid,
+
+    _init: function(params) {
+        this.parent(params);
+        this.margin = 10;
+        this.orientation = Gtk.Orientation.VERTICAL;
+
+        this.add(new Gtk.Label({ label: _("Workspace names:"),
+                                 margin_bottom: 5 }));
+
+        this._store = new WorkspaceNameModel();
+        this._treeView = new Gtk.TreeView({ model: this._store,
+                                            headers_visible: false,
+                                            reorderable: true,
+                                            hexpand: true,
+                                            vexpand: true
+                                          });
+
+        let column = new Gtk.TreeViewColumn({ title: _("Name") });
+        let renderer = new Gtk.CellRendererText({ editable: true });
+        renderer.connect('edited', Lang.bind(this, this._cellEdited));
+        column.pack_start(renderer, true);
+        column.add_attribute(renderer, 'text', this._store.Columns.LABEL);
+        this._treeView.append_column(column);
+
+        this.add(this._treeView);
+
+        let toolbar = new Gtk.Toolbar();
+        toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR);
+
+        let newButton = new Gtk.ToolButton({ stock_id: Gtk.STOCK_NEW });
+        newButton.connect('clicked', Lang.bind(this, this._newClicked));
+        toolbar.add(newButton);
+
+        let delButton = new Gtk.ToolButton({ stock_id: Gtk.STOCK_DELETE });
+        delButton.connect('clicked', Lang.bind(this, this._delClicked));
+        toolbar.add(delButton);
+
+        this.add(toolbar);
+    },
+
+    _cellEdited: function(renderer, path, new_text) {
+        let [ok, iter] = this._store.get_iter_from_string(path);
+
+        if (ok)
+            this._store.set(iter, [this._store.Columns.LABEL], [new_text]);
+    },
+
+    _newClicked: function() {
+        let iter = this._store.append();
+        let index = this._store.get_path(iter).get_indices()[0];
+
+        let label = _("Workspace %d").format(index);
+        this._store.set(iter, [this._store.Columns.LABEL], [label]);
+    },
+
+    _delClicked: function() {
+        let [any, model, iter] = this._treeView.get_selection().get_selected();
+
+        if (any)
+            this._store.remove(iter);
+    }
+});
+
+function init() {
+    Convenience.initTranslations();
+}
+
+function buildPrefsWidget() {
+    let widget = new WorkspaceSettingsWidget();
+    widget.show_all();
+
+    return widget;
+}



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