Make places results available in search

Places is one of the dash sections and it should be included in search results.

Factor out the code for getting and updating the information about places from
Places to PlacesManager.

Introduce PlaceInfo class that contains information about the place and can be
used by classes that display it in different ways. Rename classes so that their
names are consistent with corresponding classes in appDisplay.js and
docDisplay.js

https://bugzilla.gnome.org/show_bug.cgi?id=599125
This commit is contained in:
JP St. Pierre 2009-10-31 22:25:28 -04:00 committed by Marina Zhurakhinskaya
parent 5ee72d807d
commit 585bfe5b5a
4 changed files with 412 additions and 174 deletions

View File

@ -19,7 +19,7 @@ dist_jsui_DATA = \
main.js \ main.js \
overview.js \ overview.js \
panel.js \ panel.js \
places.js \ placeDisplay.js \
runDialog.js \ runDialog.js \
shellDBus.js \ shellDBus.js \
sidebar.js \ sidebar.js \

View File

@ -14,7 +14,7 @@ const _ = Gettext.gettext;
const AppDisplay = imports.ui.appDisplay; const AppDisplay = imports.ui.appDisplay;
const DocDisplay = imports.ui.docDisplay; const DocDisplay = imports.ui.docDisplay;
const Places = imports.ui.places; const PlaceDisplay = imports.ui.placeDisplay;
const GenericDisplay = imports.ui.genericDisplay; const GenericDisplay = imports.ui.genericDisplay;
const Button = imports.ui.button; const Button = imports.ui.button;
const Main = imports.ui.main; const Main = imports.ui.main;
@ -60,6 +60,7 @@ PANE_BACKGROUND_COLOR.from_pixel(0x000000f4);
const APPS = "apps"; const APPS = "apps";
const PREFS = "prefs"; const PREFS = "prefs";
const DOCS = "docs"; const DOCS = "docs";
const PLACES = "places";
/* /*
* Returns the index in an array of a given length that is obtained * Returns the index in an array of a given length that is obtained
@ -81,7 +82,8 @@ function _createDisplay(displayType) {
return new AppDisplay.AppDisplay(true); return new AppDisplay.AppDisplay(true);
else if (displayType == DOCS) else if (displayType == DOCS)
return new DocDisplay.DocDisplay(); return new DocDisplay.DocDisplay();
else if (displayType == PLACES)
return new PlaceDisplay.PlaceDisplay();
return null; return null;
} }
@ -729,7 +731,7 @@ Dash.prototype = {
/* Translators: This is in the sense of locations for documents, /* Translators: This is in the sense of locations for documents,
network locations, etc. */ network locations, etc. */
this._placesSection = new Section(_("PLACES"), true); this._placesSection = new Section(_("PLACES"), true);
let placesDisplay = new Places.Places(); let placesDisplay = new PlaceDisplay.DashPlaceDisplay();
this._placesSection.content.append(placesDisplay.actor, Big.BoxPackFlags.EXPAND); this._placesSection.content.append(placesDisplay.actor, Big.BoxPackFlags.EXPAND);
this.sectionArea.append(this._placesSection.actor, Big.BoxPackFlags.NONE); this.sectionArea.append(this._placesSection.actor, Big.BoxPackFlags.NONE);
@ -783,6 +785,11 @@ Dash.prototype = {
title: _("RECENT DOCUMENTS"), title: _("RECENT DOCUMENTS"),
header: null, header: null,
resultArea: null resultArea: null
},
{ type: PLACES,
title: _("PLACES"),
header: null,
resultArea: null
} }
]; ];

View File

@ -16,6 +16,7 @@ const Chrome = imports.ui.chrome;
const Environment = imports.ui.environment; const Environment = imports.ui.environment;
const Overview = imports.ui.overview; const Overview = imports.ui.overview;
const Panel = imports.ui.panel; const Panel = imports.ui.panel;
const PlaceDisplay = imports.ui.placeDisplay;
const RunDialog = imports.ui.runDialog; const RunDialog = imports.ui.runDialog;
const LookingGlass = imports.ui.lookingGlass; const LookingGlass = imports.ui.lookingGlass;
const ShellDBus = imports.ui.shellDBus; const ShellDBus = imports.ui.shellDBus;
@ -28,6 +29,7 @@ DEFAULT_BACKGROUND_COLOR.from_pixel(0x2266bbff);
let chrome = null; let chrome = null;
let panel = null; let panel = null;
let sidebar = null; let sidebar = null;
let placesManager = null;
let overview = null; let overview = null;
let runDialog = null; let runDialog = null;
let lookingGlass = null; let lookingGlass = null;
@ -96,6 +98,7 @@ function start() {
getRunDialog().open(); getRunDialog().open();
}); });
placesManager = new PlaceDisplay.PlacesManager();
overview = new Overview.Overview(); overview = new Overview.Overview();
chrome = new Chrome.Chrome(); chrome = new Chrome.Chrome();
panel = new Panel.Panel(); panel = new Panel.Panel();

View File

@ -23,120 +23,93 @@ const PLACES_VSPACING = 8;
const PLACES_ICON_SIZE = 16; const PLACES_ICON_SIZE = 16;
/** /**
* An entry in the places menu. * Represents a place object, which is most normally a bookmark entry,
* a mount/volume, or a special place like the Home Folder, Computer, and Network.
*
* @name: String title * @name: String title
* @iconFactory: A JavaScript callback which will create an icon texture * @iconFactory: A JavaScript callback which will create an icon texture given a size parameter
* @onActivate: A JavaScript callback to launch the entry * @launch: A JavaScript callback to launch the entry
*/ */
function PlaceDisplay(name, iconFactory, onActivate) { function PlaceInfo(name, iconFactory, launch) {
this._init(name, iconFactory, onActivate); this._init(name, iconFactory, launch);
} }
PlaceDisplay.prototype = { PlaceInfo.prototype = {
_init : function(name, iconFactory, onActivate) { _init: function(name, iconFactory, launch) {
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL, this.name = name;
reactive: true, this.iconFactory = iconFactory;
spacing: 4 }); this.launch = launch;
this.actor.connect('button-release-event', Lang.bind(this, function (b, e) { this.id = null;
onActivate(this);
Main.overview.hide();
}));
let text = new Clutter.Text({ font_name: "Sans 14px",
ellipsize: Pango.EllipsizeMode.END,
color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
text: name });
let iconBox = new Big.Box({ y_align: Big.BoxAlignment.CENTER });
this._icon = iconFactory();
iconBox.append(this._icon, Big.BoxPackFlags.NONE);
this.actor.append(iconBox, Big.BoxPackFlags.NONE);
this.actor.append(text, Big.BoxPackFlags.EXPAND);
this._iconFactory = iconFactory;
this._onActivate = onActivate;
this.actor._delegate = this;
let draggable = DND.makeDraggable(this.actor);
},
getDragActorSource: function() {
return this._icon;
},
getDragActor: function(stageX, stageY) {
return this._iconFactory();
},
//// Drag and drop methods ////
shellWorkspaceLaunch : function() {
this._onActivate();
} }
}; }
Signals.addSignalMethods(PlaceDisplay.prototype);
function Places() {
function PlacesManager() {
this._init(); this._init();
} }
Places.prototype = { PlacesManager.prototype = {
_init : function() { _init: function() {
// Places is divided semi-arbitrarily into left and right; a grid would
// look better in that there would be an even number of items left+right,
// but it seems like we want some sort of differentiation between actions
// like "Connect to server..." and regular folders
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
spacing: 4 });
this._leftBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL });
this.actor.append(this._leftBox, Big.BoxPackFlags.EXPAND);
this._rightBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL });
this.actor.append(this._rightBox, Big.BoxPackFlags.EXPAND);
// Subdivide left into actions and devices
this._actionsBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
spacing: PLACES_VSPACING });
this._leftBox.append(this._actionsBox, Big.BoxPackFlags.NONE);
this._devBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
spacing: PLACES_VSPACING,
padding_top: 6 });
this._leftBox.append(this._devBox, Big.BoxPackFlags.NONE);
// Right is bookmarks
this._dirsBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
spacing: PLACES_VSPACING });
this._rightBox.append(this._dirsBox, Big.BoxPackFlags.NONE);
let gconf = Shell.GConf.get_default(); let gconf = Shell.GConf.get_default();
gconf.watch_directory(NAUTILUS_PREFS_DIR); gconf.watch_directory(NAUTILUS_PREFS_DIR);
this._mounts = [];
this._bookmarks = [];
this._isDesktopHome = false;
let homeFile = Gio.file_new_for_path (GLib.get_home_dir()); let homeFile = Gio.file_new_for_path (GLib.get_home_dir());
let homeUri = homeFile.get_uri(); let homeUri = homeFile.get_uri();
let homeLabel = Shell.util_get_label_for_uri (homeUri); let homeLabel = Shell.util_get_label_for_uri (homeUri);
let homeIcon = Shell.util_get_icon_for_uri (homeUri); let homeIcon = Shell.util_get_icon_for_uri (homeUri);
let home = new PlaceDisplay(homeLabel, this._home = new PlaceInfo(homeLabel,
function() { function(size) {
return Shell.TextureCache.get_default().load_gicon(homeIcon, PLACES_ICON_SIZE); return Shell.TextureCache.get_default().load_gicon(homeIcon, size);
}, },
function() { function() {
Gio.app_info_launch_default_for_uri(homeUri, Main.createAppLaunchContext()); Gio.app_info_launch_default_for_uri(homeUri, Main.createAppLaunchContext());
}); });
this._actionsBox.append(home.actor, Big.BoxPackFlags.NONE);
let desktopPath = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP); let desktopPath = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP);
let desktopFile = Gio.file_new_for_path (desktopPath); let desktopFile = Gio.file_new_for_path (desktopPath);
let desktopUri = desktopFile.get_uri(); let desktopUri = desktopFile.get_uri();
let desktopLabel = Shell.util_get_label_for_uri (desktopUri); let desktopLabel = Shell.util_get_label_for_uri (desktopUri);
let desktopIcon = Shell.util_get_icon_for_uri (desktopUri); let desktopIcon = Shell.util_get_icon_for_uri (desktopUri);
this._desktopMenu = new PlaceDisplay(desktopLabel, this._desktopMenu = new PlaceInfo(desktopLabel,
function() { function(size) {
return Shell.TextureCache.get_default().load_gicon(desktopIcon, PLACES_ICON_SIZE); return Shell.TextureCache.get_default().load_gicon(desktopIcon, size);
}, },
function() { function() {
Gio.app_info_launch_default_for_uri(desktopUri, Main.createAppLaunchContext()); Gio.app_info_launch_default_for_uri(desktopUri, Main.createAppLaunchContext());
}); });
this._actionsBox.append(this._desktopMenu.actor, Big.BoxPackFlags.NONE);
this._updateDesktopMenuVisibility(); this._connect = new PlaceInfo(_("Connect to..."),
gconf.connect('changed::' + DESKTOP_IS_HOME_KEY, Lang.bind(this, this._updateDesktopMenuVisibility)); function (size) {
return Shell.TextureCache.get_default().load_icon_name("applications-internet", size);
},
function () {
new Shell.Process({ args: ['nautilus-connect-server'] }).run();
});
let networkApp = null;
try {
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('gnome-network-scheme.desktop');
} catch(e) {
try {
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('network-scheme.desktop');
} catch(e) {
log("Cannot create \"Network\" item, .desktop file not found or corrupt.");
}
}
if (networkApp != null) {
this._network = new PlaceInfo(networkApp.get_name(),
function(size) {
return networkApp.create_icon_texture(size);
},
function () {
networkApp.launch();
});
}
/* /*
* Show devices, code more or less ported from nautilus-places-sidebar.c * Show devices, code more or less ported from nautilus-places-sidebar.c
@ -153,37 +126,6 @@ Places.prototype = {
this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices)); this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices));
this._updateDevices(); this._updateDevices();
let networkApp = null;
try {
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('gnome-network-scheme.desktop');
} catch(e) {
try {
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('network-scheme.desktop');
} catch(e) {
log("Cannot create \"Network\" item, .desktop file not found or corrupt.");
}
}
if (networkApp != null) {
let network = new PlaceDisplay(networkApp.get_name(),
function() {
return networkApp.create_icon_texture(PLACES_ICON_SIZE);
},
function () {
networkApp.launch();
});
this._actionsBox.append(network.actor, Big.BoxPackFlags.NONE);
}
let connect = new PlaceDisplay(_("Connect to..."),
function () {
return Shell.TextureCache.get_default().load_icon_name("applications-internet", PLACES_ICON_SIZE);
},
function () {
new Shell.Process({ args: ['nautilus-connect-server'] }).run();
});
this._actionsBox.append(connect.actor, Big.BoxPackFlags.NONE);
this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), ".gtk-bookmarks"]); this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), ".gtk-bookmarks"]);
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath); this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
let monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null); let monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
@ -200,14 +142,68 @@ Places.prototype = {
})); }));
this._reloadBookmarks(); this._reloadBookmarks();
this._updateDesktopMenuVisibility();
gconf.connect('changed::' + DESKTOP_IS_HOME_KEY, Lang.bind(this, this._updateDesktopMenuVisibility));
},
_updateDevices: function() {
this._mounts = [];
/* first go through all connected drives */
let drives = this._volumeMonitor.get_connected_drives();
for (let i = 0; i < drives.length; i++) {
let volumes = drives[i].get_volumes();
for(let j = 0; j < volumes.length; j++) {
let mount = volumes[j].get_mount();
if(mount != null) {
this._addMount(mount);
}
}
}
/* add all volumes that is not associated with a drive */
let volumes = this._volumeMonitor.get_volumes();
for(let i = 0; i < volumes.length; i++) {
if(volumes[i].get_drive() != null)
continue;
let mount = volumes[i].get_mount();
if(mount != null) {
this._addMount(mount);
}
}
/* add mounts that have no volume (/etc/mtab mounts, ftp, sftp,...) */
let mounts = this._volumeMonitor.get_mounts();
for(let i = 0; i < mounts.length; i++) {
if(mounts[i].is_shadowed())
continue;
if(mounts[i].get_volume())
continue;
this._addMount(mounts[i]);
}
/* We emit two signals, one for a generic 'all places' update
* and the other for one specific to mounts. We do this because
* clients like PlaceDisplay may only care about places in general
* being updated while clients like DashPlaceDisplay care which
* specific type of place got updated.
*/
this.emit('mounts-updated');
this.emit('places-updated');
}, },
_reloadBookmarks: function() { _reloadBookmarks: function() {
this._dirsBox.remove_all(); this._bookmarks = [];
if (!GLib.file_test(this._bookmarksPath, GLib.FileTest.EXISTS)) if (!GLib.file_test(this._bookmarksPath, GLib.FileTest.EXISTS))
return; return;
let [success, bookmarksContent, len] = GLib.file_get_contents(this._bookmarksPath); let [success, bookmarksContent, len] = GLib.file_get_contents(this._bookmarksPath);
@ -243,55 +239,28 @@ Places.prototype = {
continue; continue;
let icon = Shell.util_get_icon_for_uri(bookmark); let icon = Shell.util_get_icon_for_uri(bookmark);
let item = new PlaceDisplay(label, let item = new PlaceInfo(label,
function() { function(size) {
return Shell.TextureCache.get_default().load_gicon(icon, PLACES_ICON_SIZE); return Shell.TextureCache.get_default().load_gicon(icon, size);
}, },
function() { function() {
Gio.app_info_launch_default_for_uri(bookmark, Main.createAppLaunchContext()); Gio.app_info_launch_default_for_uri(bookmark, Main.createAppLaunchContext());
}); });
this._dirsBox.append(item.actor, Big.BoxPackFlags.NONE); this._bookmarks.push(item);
} }
/* See comment in _updateDevices for explanation why there are two signals. */
this.emit('bookmarks-updated');
this.emit('places-updated');
}, },
_updateDevices: function() { _updateDesktopMenuVisibility: function() {
this._devBox.remove_all(); let gconf = Shell.GConf.get_default();
this._isDesktopHome = gconf.get_boolean(DESKTOP_IS_HOME_KEY);
/* first go through all connected drives */ /* See comment in _updateDevices for explanation why there are two signals. */
let drives = this._volumeMonitor.get_connected_drives(); this.emit('defaults-updated');
for (let i = 0; i < drives.length; i++) { this.emit('places-updated');
let volumes = drives[i].get_volumes();
for(let j = 0; j < volumes.length; j++) {
let mount = volumes[j].get_mount();
if(mount != null) {
this._addMount(mount);
}
}
}
/* add all volumes that is not associated with a drive */
let volumes = this._volumeMonitor.get_volumes();
for(let i = 0; i < volumes.length; i++) {
if(volumes[i].get_drive() != null)
continue;
let mount = volumes[i].get_mount();
if(mount != null) {
this._addMount(mount);
}
}
/* add mounts that have no volume (/etc/mtab mounts, ftp, sftp,...) */
let mounts = this._volumeMonitor.get_mounts();
for(let i = 0; i < mounts.length; i++) {
if(mounts[i].is_shadowed())
continue;
if(mounts[i].get_volume())
continue;
this._addMount(mounts[i]);
}
}, },
_addMount: function(mount) { _addMount: function(mount) {
@ -299,23 +268,282 @@ Places.prototype = {
let mountIcon = mount.get_icon(); let mountIcon = mount.get_icon();
let root = mount.get_root(); let root = mount.get_root();
let mountUri = root.get_uri(); let mountUri = root.get_uri();
let devItem = new PlaceDisplay(mountLabel, let devItem = new PlaceInfo(mountLabel,
function() { function(size) {
return Shell.TextureCache.get_default().load_gicon(mountIcon, PLACES_ICON_SIZE); return Shell.TextureCache.get_default().load_gicon(mountIcon, size);
}, },
function() { function() {
Gio.app_info_launch_default_for_uri(mountUri, Main.createAppLaunchContext()); Gio.app_info_launch_default_for_uri(mountUri, Main.createAppLaunchContext());
}); });
this._devBox.append(devItem.actor, Big.BoxPackFlags.NONE); this._mounts.push(devItem);
}, },
_updateDesktopMenuVisibility: function() { getAllPlaces: function () {
let gconf = Shell.GConf.get_default(); return this.getDefaultPlaces().concat(this.getBookmarks(), this.getMounts());
let desktopIsHome = gconf.get_boolean(DESKTOP_IS_HOME_KEY); },
if (desktopIsHome)
this._desktopMenu.actor.hide(); getDefaultPlaces: function () {
else let places = [this._home];
this._desktopMenu.actor.show();
if (this._isDesktopHome)
places.push(this._desktopMenu);
if (this._network)
places.push(this._network);
places.push(this._connect);
return places;
},
getBookmarks: function () {
return this._bookmarks;
},
getMounts: function () {
return this._mounts;
}
};
Signals.addSignalMethods(PlacesManager.prototype);
/**
* An entry in the places menu.
* @info The corresponding PlaceInfo to populate this entry.
*/
function DashPlaceDisplayItem(info) {
this._init(info);
}
DashPlaceDisplayItem.prototype = {
_init: function(info) {
this.name = info.name;
this._info = info;
this._icon = info.iconFactory(PLACES_ICON_SIZE);
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
reactive: true,
spacing: 4 });
this.actor.connect('button-release-event', Lang.bind(this, function (b, e) {
this._info.launch();
Main.overview.hide();
}));
let text = new Clutter.Text({ font_name: 'Sans 14px',
ellipsize: Pango.EllipsizeMode.END,
color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
text: this.name });
let iconBox = new Big.Box({ y_align: Big.BoxAlignment.CENTER });
iconBox.append(this._icon, Big.BoxPackFlags.NONE);
this.actor.append(iconBox, Big.BoxPackFlags.NONE);
this.actor.append(text, Big.BoxPackFlags.EXPAND);
this.actor._delegate = this;
let draggable = DND.makeDraggable(this.actor);
},
getDragActorSource: function() {
return this._icon;
},
getDragActor: function(stageX, stageY) {
return this._info.iconFactory(PLACES_ICON_SIZE);
},
//// Drag and drop methods ////
shellWorkspaceLaunch: function() {
this._info.launch();
}
};
function DashPlaceDisplay() {
this._init();
}
DashPlaceDisplay.prototype = {
_init: function() {
// Places is divided semi-arbitrarily into left and right; a grid would
// look better in that there would be an even number of items left+right,
// but it seems like we want some sort of differentiation between actions
// like "Connect to server..." and regular folders
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
spacing: 4 });
this._leftBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL });
this.actor.append(this._leftBox, Big.BoxPackFlags.EXPAND);
this._rightBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL });
this.actor.append(this._rightBox, Big.BoxPackFlags.EXPAND);
// Subdivide left into actions and devices
this._actionsBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
spacing: PLACES_VSPACING });
this._devBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
spacing: PLACES_VSPACING,
padding_top: 6 });
this._dirsBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
spacing: PLACES_VSPACING });
this._leftBox.append(this._actionsBox, Big.BoxPackFlags.NONE);
this._leftBox.append(this._devBox, Big.BoxPackFlags.NONE);
this._rightBox.append(this._dirsBox, Big.BoxPackFlags.NONE);
Main.placesManager.connect('defaults-updated', Lang.bind(this, this._updateDefaults));
Main.placesManager.connect('bookmarks-updated', Lang.bind(this, this._updateBookmarks));
Main.placesManager.connect('mounts-updated', Lang.bind(this, this._updateMounts));
this._updateDefaults();
this._updateMounts();
this._updateBookmarks();
},
_updateDefaults: function() {
this._actionsBox.get_children().forEach(function (child) {
child.destroy();
});
let places = Main.placesManager.getDefaultPlaces();
for (let i = 0; i < places.length; i++)
this._actionsBox.append(new DashPlaceDisplayItem(places[i]).actor, Big.BoxPackFlags.NONE);
},
_updateMounts: function() {
this._devBox.get_children().forEach(function (child) {
child.destroy();
});
let places = Main.placesManager.getMounts();
for (let i = 0; i < places.length; i++)
this._devBox.append(new DashPlaceDisplayItem(places[i]).actor, Big.BoxPackFlags.NONE);
},
_updateBookmarks: function() {
this._dirsBox.get_children().forEach(function (child) {
child.destroy();
});
let places = Main.placesManager.getBookmarks();
for (let i = 0; i < places.length; i ++)
this._dirsBox.append(new DashPlaceDisplayItem(places[i]).actor, Big.BoxPackFlags.NONE);
}
};
Signals.addSignalMethods(DashPlaceDisplay.prototype);
function PlaceDisplayItem(placeInfo) {
this._init(placeInfo);
}
PlaceDisplayItem.prototype = {
__proto__: GenericDisplay.GenericDisplayItem.prototype,
_init : function(placeInfo) {
GenericDisplay.GenericDisplayItem.prototype._init.call(this);
this._info = placeInfo;
this._setItemInfo(placeInfo.name, '');
},
//// Public method overrides ////
// Opens an application represented by this display item.
launch : function() {
this._info.launch();
},
shellWorkspaceLaunch: function() {
this._info.launch();
},
//// Protected method overrides ////
// Returns an icon for the item.
_createIcon: function() {
return this._info.iconFactory(GenericDisplay.ITEM_DISPLAY_ICON_SIZE);
},
// Returns a preview icon for the item.
_createPreviewIcon: function() {
return this._info.iconFactory(GenericDisplay.PREVIEW_ICON_SIZE);
}
};
function PlaceDisplay() {
this._init();
}
PlaceDisplay.prototype = {
__proto__: GenericDisplay.GenericDisplay.prototype,
_init: function() {
GenericDisplay.GenericDisplay.prototype._init.call(this);
this._stale = true;
Main.placesManager.connect('places-updated', Lang.bind(this, function (e) {
this._stale = true;
}));
},
//// Protected method overrides ////
_refreshCache: function () {
if (!this._stale)
return true;
this._allItems = {};
let array = Main.placesManager.getAllPlaces();
for (let i = 0; i < array.length; i ++) {
// We are using an array id as placeInfo id because placeInfo doesn't have any
// other information piece that can be used as a unique id. There are different
// types of placeInfo, such as devices and directories that would result in differently
// structured ids. Also the home directory can show up in both the default places and in
// bookmarks which means its URI can't be used as a unique id. (This does mean it can
// appear twice in search results, though that doesn't happen at the moment because we
// name it "Home Folder" in default places and it's named with the user's system name
// if it appears as a bookmark.)
let placeInfo = array[i];
placeInfo.id = i;
this._allItems[i] = placeInfo;
}
this._stale = false;
return false;
},
// Sets the list of the displayed items.
_setDefaultList: function() {
this._matchedItems = {};
this._matchedItemKeys = [];
for (id in this._allItems) {
this._matchedItems[id] = 1;
this._matchedItemKeys.push(id);
}
this._matchedItemKeys.sort(Lang.bind(this, this._compareItems));
},
// Checks if the item info can be a match for the search string by checking
// the name of the place. Item info is expected to be PlaceInfo.
// Returns a boolean flag indicating if itemInfo is a match.
_isInfoMatching: function(itemInfo, search) {
if (search == null || search == '')
return true;
let name = itemInfo.name.toLowerCase();
if (name.indexOf(search) >= 0)
return true;
return false;
},
// Compares items associated with the item ids based on the alphabetical order
// of the item names.
// Returns an integer value indicating the result of the comparison.
_compareItems: function(itemIdA, itemIdB) {
let placeA = this._allItems[itemIdA];
let placeB = this._allItems[itemIdB];
return placeA.name.localeCompare(placeB.name);
},
// Creates a PlaceDisplayItem based on itemInfo, which is expected to be a PlaceInfo object.
_createDisplayItem: function(itemInfo) {
return new PlaceDisplayItem(itemInfo);
} }
}; };
Signals.addSignalMethods(Places.prototype);