// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
/* exported init buildPrefsWidget */
const { Gio, GObject, Gtk } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
const N_ = e => e;
const SETTINGS_KEY = 'application-list';
const Columns = {
APPINFO: 0,
DISPLAY_NAME: 1,
ICON: 2
};
const Widget = GObject.registerClass({
GTypeName: 'WindowGrouperPrefsWidget',
}, class Widget extends Gtk.Grid {
_init(params) {
super._init(params);
this.set_orientation(Gtk.Orientation.VERTICAL);
this._settings = ExtensionUtils.getSettings();
this._settings.connect('changed', this._refresh.bind(this));
this._changedPermitted = false;
this._store = new Gtk.ListStore();
this._store.set_column_types([Gio.AppInfo, GObject.TYPE_STRING, Gio.Icon]);
let scrolled = new Gtk.ScrolledWindow({ shadow_type: Gtk.ShadowType.IN });
scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
this.add(scrolled);
this._treeView = new Gtk.TreeView({
model: this._store,
headers_visible: false,
hexpand: true,
vexpand: true
});
this._treeView.get_selection().set_mode(Gtk.SelectionMode.SINGLE);
let appColumn = new Gtk.TreeViewColumn({
sort_column_id: Columns.DISPLAY_NAME,
spacing: 12
});
let iconRenderer = new Gtk.CellRendererPixbuf({
stock_size: Gtk.IconSize.DIALOG,
xpad: 12,
ypad: 12
});
appColumn.pack_start(iconRenderer, false);
appColumn.add_attribute(iconRenderer, 'gicon', Columns.ICON);
let nameRenderer = new Gtk.CellRendererText();
appColumn.pack_start(nameRenderer, true);
appColumn.add_attribute(nameRenderer, 'text', Columns.DISPLAY_NAME);
this._treeView.append_column(appColumn);
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);
this.add(toolbar);
let newButton = new Gtk.ToolButton({
icon_name: 'list-add-symbolic'
});
newButton.connect('clicked', this._createNew.bind(this));
toolbar.add(newButton);
let delButton = new Gtk.ToolButton({
icon_name: 'list-remove-symbolic'
});
delButton.connect('clicked', this._deleteSelected.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._changedPermitted = true;
this._refresh();
}
_createNew() {
let dialog = new Gtk.AppChooserDialog({
heading: _('Select an application for which grouping should apply'),
transient_for: this.get_toplevel(),
modal: true
});
dialog.get_widget().show_all = true;
dialog.connect('response', (dialog, id) => {
if (id != Gtk.ResponseType.OK) {
dialog.destroy();
return;
}
let appInfo = dialog.get_app_info();
if (!appInfo) {
dialog.destroy();
return;
}
this._changedPermitted = false;
this._appendItem(appInfo.get_id());
this._changedPermitted = true;
let iter = this._store.append();
this._store.set(iter,
[Columns.APPINFO, Columns.ICON, Columns.DISPLAY_NAME],
[appInfo, appInfo.get_icon(), appInfo.get_display_name()]);
dialog.destroy();
});
dialog.show_all();
}
_deleteSelected() {
let [any, model_, iter] = this._treeView.get_selection().get_selected();
if (any) {
let appInfo = this._store.get_value(iter, Columns.APPINFO);
this._changedPermitted = false;
this._removeItem(appInfo.get_id());
this._changedPermitted = true;
this._store.remove(iter);
}
}
_refresh() {
if (!this._changedPermitted)
// Ignore this notification, model is being modified outside
return;
this._store.clear();
let currentItems = this._settings.get_strv(SETTINGS_KEY);
let validItems = [];
for (let i = 0; i < currentItems.length; i++) {
let id = currentItems[i];
let appInfo = Gio.DesktopAppInfo.new(id);
if (!appInfo)
continue;
validItems.push(currentItems[i]);
let iter = this._store.append();
this._store.set(iter,
[Columns.APPINFO, Columns.ICON, Columns.DISPLAY_NAME],
[appInfo, appInfo.get_icon(), appInfo.get_display_name()]);
}
if (validItems.length != currentItems.length) // some items were filtered out
this._settings.set_strv(SETTINGS_KEY, validItems);
}
_appendItem(id) {
let currentItems = this._settings.get_strv(SETTINGS_KEY);
currentItems.push(id);
this._settings.set_strv(SETTINGS_KEY, currentItems);
}
_removeItem(id) {
let currentItems = this._settings.get_strv(SETTINGS_KEY);
let index = currentItems.indexOf(id);
if (index < 0)
return;
currentItems.splice(index, 1);
this._settings.set_strv(SETTINGS_KEY, currentItems);
}
});
function init() {
ExtensionUtils.initTranslations();
}
function buildPrefsWidget() {
let widget = new Widget({ margin: 12 });
widget.show_all();
return widget;
}