gnome-shell/js/ui/realms/realmSearchProvider.js

327 lines
9.3 KiB
JavaScript

const { Clutter, GObject, Pango, Shell, St } = imports.gi;
const Search = imports.ui.search;
const Main = imports.ui.main;
const Util = imports.misc.util;
// Based on ProviderInfo in search.js
var RealmProviderInfo = GObject.registerClass(
class RealmProviderInfo extends St.Button {
_init() {
super._init({
style_class: 'search-provider-icon',
reactive: false,
can_focus: false,
accessible_name: "Realms",
track_hover: false,
y_align: Clutter.ActorAlign.START,
});
this._content = new St.BoxLayout({ vertical: false,
style_class: 'list-search-provider-content' });
this.set_child(this._content);
let icon = new St.Icon({ icon_size: this.PROVIDER_ICON_SIZE,
icon_name: 'computer' });
let detailsBox = new St.BoxLayout({ style_class: 'list-search-provider-details',
vertical: true,
x_expand: true });
let nameLabel = new St.Label({
text: "Realms",
x_align: Clutter.ActorAlign.START
});
this._moreLabel = new St.Label({ x_align: Clutter.ActorAlign.START });
detailsBox.add_actor(nameLabel);
detailsBox.add_actor(this._moreLabel);
this._content.add_actor(icon);
this._content.add_actor(detailsBox);
}
get PROVIDER_ICON_SIZE() {
return 48;
}
setMoreCount(count) {
this._moreLabel.text = ngettext("%d more", "%d more", count).format(count);
this._moreLabel.visible = count > 0;
}
});
var MAX_LIST_SEARCH_RESULTS_ROWS = 10;
// Based on ListSearchResult in search.js
var RealmSearchResult = GObject.registerClass(
class ListSearchResult extends Search.SearchResult {
_init(provider, metaInfo, resultsView) {
super._init(provider, metaInfo, resultsView);
this.style_class = 'list-search-result';
let content = new St.BoxLayout({
style_class: 'list-search-result-content',
vertical: false,
x_align: Clutter.ActorAlign.FILL,
x_expand: true,
y_expand: true,
});
this.set_child(content);
this._termsChangedId = 0;
let titleBox = new St.BoxLayout({
style_class: 'list-search-result-title',
y_align: Clutter.ActorAlign.CENTER,
});
content.add_child(titleBox);
// An icon for, or thumbnail of, content
let icon = this.metaInfo['createIcon'](this.ICON_SIZE);
if (icon)
titleBox.add(icon);
let title = new St.Label({
text: this.metaInfo['name'],
y_align: Clutter.ActorAlign.CENTER,
});
titleBox.add_child(title);
this.label_actor = title;
if (this.metaInfo['description']) {
this._descriptionLabel = new St.Label({
style_class: 'list-search-result-description',
x_expand: true,
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER,
});
this._descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
content.add_child(this._descriptionLabel);
this._termsChangedId =
this._resultsView.connect('terms-changed',
this._highlightTerms.bind(this));
this._highlightTerms();
}
let id = this.metaInfo['id'];
if (id != ':new:') {
this.configButton = new St.Button({
style_class: 'button',
track_hover: true,
can_focus: true,
child: new St.Icon({
style_class: 'realm-config-icon',
icon_name: 'emblem-system-symbolic',
icon_size: 24,
}),
});
this.configButton.connect('clicked', () => {
Main.overview.toggle();
Util.spawn(['/usr/libexec/realm-config-ui', id]);
});
content.add_child(this.configButton);
}
this.connect('destroy', this._onDestroy.bind(this));
}
get ICON_SIZE() {
return 24;
}
_highlightTerms() {
let markup = this._resultsView.highlightTerms(this.metaInfo['description'].split('\n')[0]);
this._descriptionLabel.clutter_text.set_markup(markup);
}
_onDestroy() {
if (this._termsChangedId)
this._resultsView.disconnect(this._termsChangedId);
this._termsChangedId = 0;
}
});
// Based on ListSearchResults in search.js
var RealmSearchResults = GObject.registerClass(
class RealmSearchResults extends Search.SearchResultsBase {
_init(provider, resultsView) {
super._init(provider, resultsView);
this._container = new St.BoxLayout({ style_class: 'search-section-content' });
this.providerInfo = new RealmProviderInfo();
this.providerInfo.connect('key-focus-in', this._keyFocusIn.bind(this));
this.providerInfo.connect('clicked', () => {
Main.overview.toggle();
});
this._container.add_child(this.providerInfo);
this._content = new St.BoxLayout({
style_class: 'list-search-results',
vertical: true,
x_expand: true,
});
this._container.add_child(this._content);
this._resultDisplayBin.set_child(this._container);
}
_setMoreCount(count) {
this.providerInfo.setMoreCount(count);
}
_getMaxDisplayedResults() {
return MAX_LIST_SEARCH_RESULTS_ROWS;
}
_clearResultDisplay() {
this._content.remove_all_children();
}
_createResultDisplay(meta) {
return super._createResultDisplay(meta) ||
new RealmSearchResult(this.provider, meta, this._resultsView);
}
_addItem(display) {
this._content.add_actor(display);
}
getFirstResult() {
if (this._content.get_n_children() > 0)
return this._content.get_child_at_index(0);
else
return null;
}
});
var RealmSearchProvider = class RealmSearchProvider {
constructor() {
this._shellRealms = Shell.Realms.get_default();
this.id = 'realms';
this.isRemoteProvider = false;
this.canLaunchSearch = false;
this.display = null;
}
createResultDisplay(resultsView) {
this.display = new RealmSearchResults(this, resultsView);
this.display.connect('notify::focus-child', resultsView._focusChildChanged.bind(resultsView));
this.display.hide();
resultsView._content.add(this.display);
}
createIcon(size, realm) {
if (realm.is_running()) {
return new St.Icon({ icon_name: 'emblem-synchronizing', icon_size: size });
} else {
return new St.Icon({ icon_name: 'exaile', icon_size: size });
}
}
createRealmMeta(realm) {
let id = realm.get_realm_name();
let description = '';
if (realm.is_running()) {
description = `Set realm-${id} as current realm`;
} else {
description = `Start realm-${id}`;
}
return {
id: id,
name: `realm-${id}`,
description: description,
createIcon: size => {
return this.createIcon(size, realm);
},
};
}
createNewRealmMeta() {
return {
id: ':new:',
name: 'New Realm',
description: 'Create a new realm',
createIcon: size => {
return new St.Icon({
icon_name: 'computer',
icon_size: size,
});
}
}
}
getResultMetas (ids, callback) {
let metas = [];
for (let id of ids) {
if (id == ":new:") {
metas.push(this.createNewRealmMeta());
} else {
let realm = this._shellRealms.realm_by_name(id);
if (realm && !realm.is_current()) {
metas.push(this.createRealmMeta(realm));
} else {
log(`No realm found for ${id}`);
}
}
}
callback(metas);
}
activateResult (resultId, _terms) {
if (resultId == ':new:') {
Main.overview.toggle();
Util.spawn(['/usr/libexec/realm-config-ui', '--new']);
return;
}
let realm = this._shellRealms.realm_by_name(resultId);
if (realm) {
realm.set_current();
} else {
log(`No realm found for ${resultId}`);
}
}
filterResults(results, maxNumber) {
return results.slice(0, maxNumber)
}
getInitialResultSet(terms, callback, _cancellable) {
let realms = this._shellRealms.get_all_realms();
let matches = [];
if (terms.length == 1 && "new".startsWith(terms[0])) {
matches.push(":new:");
}
for (let realm of realms) {
if (!realm.is_current()) {
let name = realm.get_realm_name();
if (terms.every(t => name.indexOf(t) != -1)) {
matches.push(name);
}
}
}
callback(matches);
}
getSubsearchResultSet(previousResults, terms, callback, cancellable) {
this.getInitialResultSet(terms, callback, cancellable)
}
}