91c9982d7f
This code has been commented out since it was added, presumably due to difficulty in avoiding a cycle of reloading rows on settings changes and writing settings on row changes. Considering that the setting changing while the preference dialog is up is extremely unlikely, don't bother with making it work and just remove the dead code. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
211 lines
6.2 KiB
JavaScript
211 lines
6.2 KiB
JavaScript
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
|
|
/* exported init buildPrefsWidget */
|
|
|
|
const { Gio, GObject, Gtk } = imports.gi;
|
|
|
|
const Gettext = imports.gettext.domain('gnome-shell-extensions');
|
|
const _ = Gettext.gettext;
|
|
const N_ = e => e;
|
|
|
|
const ExtensionUtils = imports.misc.extensionUtils;
|
|
|
|
const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences';
|
|
const WORKSPACE_KEY = 'workspace-names';
|
|
|
|
const WorkspaceNameModel = GObject.registerClass(
|
|
class WorkspaceNameModel extends Gtk.ListStore {
|
|
_init(params) {
|
|
super._init(params);
|
|
this.set_column_types([GObject.TYPE_STRING]);
|
|
|
|
this.Columns = {
|
|
LABEL: 0,
|
|
};
|
|
|
|
this._settings = new Gio.Settings({ schema_id: WORKSPACE_SCHEMA });
|
|
this._reloadFromSettings();
|
|
|
|
// overriding class closure doesn't work, because GtkTreeModel
|
|
// plays tricks with marshallers and class closures
|
|
this.connect('row-changed', this._onRowChanged.bind(this));
|
|
this.connect('row-inserted', this._onRowInserted.bind(this));
|
|
this.connect('row-deleted', this._onRowDeleted.bind(this));
|
|
}
|
|
|
|
_reloadFromSettings() {
|
|
if (this._preventChanges)
|
|
return;
|
|
this._preventChanges = true;
|
|
|
|
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]]);
|
|
}
|
|
|
|
this._preventChanges = false;
|
|
}
|
|
|
|
_onRowChanged(self, path, iter) {
|
|
if (this._preventChanges)
|
|
return;
|
|
this._preventChanges = true;
|
|
|
|
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(self, path, iter) {
|
|
if (this._preventChanges)
|
|
return;
|
|
this._preventChanges = true;
|
|
|
|
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(self, path) {
|
|
if (this._preventChanges)
|
|
return;
|
|
this._preventChanges = true;
|
|
|
|
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 = GObject.registerClass(
|
|
class WorkspaceSettingsWidget extends Gtk.Grid {
|
|
_init(params) {
|
|
super._init(params);
|
|
this.margin = 12;
|
|
this.orientation = Gtk.Orientation.VERTICAL;
|
|
|
|
this.add(new Gtk.Label({
|
|
label: '<b>%s</b>'.format(_('Workspace Names')),
|
|
use_markup: true,
|
|
margin_bottom: 6,
|
|
hexpand: true,
|
|
halign: Gtk.Align.START
|
|
}));
|
|
|
|
let scrolled = new Gtk.ScrolledWindow({ shadow_type: Gtk.ShadowType.IN });
|
|
scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
|
this.add(scrolled);
|
|
|
|
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', this._cellEdited.bind(this));
|
|
column.pack_start(renderer, true);
|
|
column.add_attribute(renderer, 'text', this._store.Columns.LABEL);
|
|
this._treeView.append_column(column);
|
|
|
|
scrolled.add(this._treeView);
|
|
|
|
let toolbar = new Gtk.Toolbar({ icon_size: Gtk.IconSize.SMALL_TOOLBAR });
|
|
toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR);
|
|
|
|
let newButton = new Gtk.ToolButton({ icon_name: 'list-add-symbolic' });
|
|
newButton.connect('clicked', this._newClicked.bind(this));
|
|
toolbar.add(newButton);
|
|
|
|
let delButton = new Gtk.ToolButton({ icon_name: 'list-remove-symbolic' });
|
|
delButton.connect('clicked', this._delClicked.bind(this));
|
|
toolbar.add(delButton);
|
|
|
|
let selection = this._treeView.get_selection();
|
|
selection.connect('changed', () => {
|
|
delButton.sensitive = selection.count_selected_rows() > 0;
|
|
});
|
|
delButton.sensitive = selection.count_selected_rows() > 0;
|
|
|
|
this.add(toolbar);
|
|
}
|
|
|
|
_cellEdited(renderer, path, newText) {
|
|
let [ok, iter] = this._store.get_iter_from_string(path);
|
|
|
|
if (ok)
|
|
this._store.set(iter, [this._store.Columns.LABEL], [newText]);
|
|
}
|
|
|
|
_newClicked() {
|
|
let iter = this._store.append();
|
|
let index = this._store.get_path(iter).get_indices()[0];
|
|
|
|
let label = _('Workspace %d').format(index + 1);
|
|
this._store.set(iter, [this._store.Columns.LABEL], [label]);
|
|
}
|
|
|
|
_delClicked() {
|
|
let [any, model_, iter] = this._treeView.get_selection().get_selected();
|
|
|
|
if (any)
|
|
this._store.remove(iter);
|
|
}
|
|
});
|
|
|
|
function init() {
|
|
ExtensionUtils.initTranslations();
|
|
}
|
|
|
|
function buildPrefsWidget() {
|
|
let widget = new WorkspaceSettingsWidget();
|
|
widget.show_all();
|
|
|
|
return widget;
|
|
}
|