ViewSelector: remove the places & devices search provider

Remove the PlacesManager, its search provider and all associated code.
Places search is now provided by nautilus using the external search
provider API.

https://bugzilla.gnome.org/show_bug.cgi?id=683506
This commit is contained in:
Giovanni Campagna 2012-09-06 17:22:11 +02:00
parent b203a95a78
commit f39098a4f2
6 changed files with 0 additions and 784 deletions

View File

@ -69,7 +69,6 @@ nobase_dist_js_DATA = \
ui/overview.js \ ui/overview.js \
ui/panel.js \ ui/panel.js \
ui/panelMenu.js \ ui/panelMenu.js \
ui/placeDisplay.js \
ui/pointerWatcher.js \ ui/pointerWatcher.js \
ui/popupMenu.js \ ui/popupMenu.js \
ui/remoteSearch.js \ ui/remoteSearch.js \

View File

@ -20,7 +20,6 @@ const Keyboard = imports.ui.keyboard;
const MessageTray = imports.ui.messageTray; const MessageTray = imports.ui.messageTray;
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 Layout = imports.ui.layout; const Layout = imports.ui.layout;
const LookingGlass = imports.ui.lookingGlass; const LookingGlass = imports.ui.lookingGlass;

View File

@ -1,412 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Shell = imports.gi.Shell;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const St = imports.gi.St;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
const Params = imports.misc.params;
const Search = imports.ui.search;
const Util = imports.misc.util;
/**
* 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
* @iconFactory: A JavaScript callback which will create an icon texture given a size parameter
* @launch: A JavaScript callback to launch the entry
*/
const PlaceInfo = new Lang.Class({
Name: 'PlaceInfo',
_init: function(id, name, iconFactory, launch) {
this.id = id;
this.name = name;
this._lowerName = name.toLowerCase();
this.iconFactory = iconFactory;
this.launch = launch;
},
matchTerms: function(terms) {
let mtype = Search.MatchType.NONE;
for (let i = 0; i < terms.length; i++) {
let term = terms[i];
let idx = this._lowerName.indexOf(term);
if (idx == 0) {
mtype = Search.MatchType.PREFIX;
} else if (idx > 0) {
if (mtype == Search.MatchType.NONE)
mtype = Search.MatchType.SUBSTRING;
} else {
return Search.MatchType.NONE;
}
}
return mtype;
},
isRemovable: function() {
return false;
}
});
// Helper function to translate launch parameters into a GAppLaunchContext
function _makeLaunchContext(params)
{
params = Params.parse(params, { workspace: -1,
timestamp: 0 });
let launchContext = global.create_app_launch_context();
if (params.workspace != -1)
launchContext.set_desktop(params.workspace);
if (params.timestamp != 0)
launchContext.set_timestamp(params.timestamp);
return launchContext;
}
const PlaceDeviceInfo = new Lang.Class({
Name: 'PlaceDeviceInfo',
Extends: PlaceInfo,
_init: function(mount) {
this._mount = mount;
this.name = mount.get_name();
this._lowerName = this.name.toLowerCase();
this.id = 'mount:' + mount.get_root().get_uri();
},
iconFactory: function(size) {
let icon = this._mount.get_icon();
return St.TextureCache.get_default().load_gicon(null, icon, size);
},
launch: function(params) {
Gio.app_info_launch_default_for_uri(this._mount.get_root().get_uri(),
_makeLaunchContext(params));
},
isRemovable: function() {
return this._mount.can_unmount();
},
remove: function() {
if (!this.isRemovable())
return;
if (this._mount.can_eject())
this._mount.eject(0, null, Lang.bind(this, this._removeFinish));
else
this._mount.unmount(0, null, Lang.bind(this, this._removeFinish));
},
_removeFinish: function(o, res, data) {
try {
if (this._mount.can_eject())
this._mount.eject_finish(res);
else
this._mount.unmount_finish(res);
} catch (e) {
let message = _("Failed to unmount '%s'").format(o.get_name());
Main.overview.setMessage(message,
Lang.bind(this, this.remove),
_("Retry"));
}
}
});
const PlacesManager = new Lang.Class({
Name: 'PlacesManager',
_init: function() {
this._defaultPlaces = [];
this._mounts = [];
this._bookmarks = [];
let homeFile = Gio.file_new_for_path (GLib.get_home_dir());
let homeUri = homeFile.get_uri();
let homeLabel = Shell.util_get_label_for_uri (homeUri);
let homeIcon = Shell.util_get_icon_for_uri (homeUri);
this._home = new PlaceInfo('special:home', homeLabel,
function(size) {
return St.TextureCache.get_default().load_gicon(null, homeIcon, size);
},
function(params) {
Gio.app_info_launch_default_for_uri(homeUri, _makeLaunchContext(params));
});
let desktopPath = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP);
let desktopFile = Gio.file_new_for_path (desktopPath);
let desktopUri = desktopFile.get_uri();
let desktopLabel = Shell.util_get_label_for_uri (desktopUri);
let desktopIcon = Shell.util_get_icon_for_uri (desktopUri);
this._desktopMenu = new PlaceInfo('special:desktop', desktopLabel,
function(size) {
return St.TextureCache.get_default().load_gicon(null, desktopIcon, size);
},
function(params) {
Gio.app_info_launch_default_for_uri(desktopUri, _makeLaunchContext(params));
});
this._defaultPlaces.push(this._home);
this._defaultPlaces.push(this._desktopMenu);
/*
* Show devices, code more or less ported from nautilus-places-sidebar.c
*/
this._volumeMonitor = Gio.VolumeMonitor.get();
this._volumeMonitor.connect('volume-added', Lang.bind(this, this._updateDevices));
this._volumeMonitor.connect('volume-removed',Lang.bind(this, this._updateDevices));
this._volumeMonitor.connect('volume-changed', Lang.bind(this, this._updateDevices));
this._volumeMonitor.connect('mount-added', Lang.bind(this, this._updateDevices));
this._volumeMonitor.connect('mount-removed', Lang.bind(this, this._updateDevices));
this._volumeMonitor.connect('mount-changed', Lang.bind(this, this._updateDevices));
this._volumeMonitor.connect('drive-connected', Lang.bind(this, this._updateDevices));
this._volumeMonitor.connect('drive-disconnected', Lang.bind(this, this._updateDevices));
this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices));
this._updateDevices();
this._bookmarksPath = GLib.build_filenamev([GLib.get_user_config_dir(), 'gtk-3.0', 'bookmarks']);
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
this._monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
this._bookmarkTimeoutId = 0;
this._monitor.connect('changed', Lang.bind(this, function () {
if (this._bookmarkTimeoutId > 0)
return;
/* Defensive event compression */
this._bookmarkTimeoutId = Mainloop.timeout_add(100, Lang.bind(this, function () {
this._bookmarkTimeoutId = 0;
this._reloadBookmarks();
return false;
}));
}));
this._reloadBookmarks();
},
_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() {
this._bookmarks = [];
if (!GLib.file_test(this._bookmarksPath, GLib.FileTest.EXISTS))
return;
let bookmarksContent = Shell.get_file_contents_utf8_sync(this._bookmarksPath);
let bookmarks = bookmarksContent.split('\n');
let bookmarksToLabel = {};
let bookmarksOrder = [];
for (let i = 0; i < bookmarks.length; i++) {
let bookmarkLine = bookmarks[i];
let components = bookmarkLine.split(' ');
let bookmark = components[0];
if (bookmark in bookmarksToLabel)
continue;
let label = null;
if (components.length > 1)
label = components.slice(1).join(' ');
bookmarksToLabel[bookmark] = label;
bookmarksOrder.push(bookmark);
}
for (let i = 0; i < bookmarksOrder.length; i++) {
let bookmark = bookmarksOrder[i];
let label = bookmarksToLabel[bookmark];
let file = Gio.file_new_for_uri(bookmark);
if (!file.query_exists(null))
continue;
if (label == null)
label = Shell.util_get_label_for_uri(bookmark);
if (label == null)
continue;
let icon = Shell.util_get_icon_for_uri(bookmark);
let item = new PlaceInfo('bookmark:' + bookmark, label,
function(size) {
return St.TextureCache.get_default().load_gicon(null, icon, size);
},
function(params) {
Gio.app_info_launch_default_for_uri(bookmark, _makeLaunchContext(params));
});
this._bookmarks.push(item);
}
/* See comment in _updateDevices for explanation why there are two signals. */
this.emit('bookmarks-updated');
this.emit('places-updated');
},
_addMount: function(mount) {
let devItem = new PlaceDeviceInfo(mount);
this._mounts.push(devItem);
},
getAllPlaces: function () {
return this.getDefaultPlaces().concat(this.getBookmarks(), this.getMounts());
},
getDefaultPlaces: function () {
return this._defaultPlaces;
},
getBookmarks: function () {
return this._bookmarks;
},
getMounts: function () {
return this._mounts;
},
_lookupIndexById: function(sourceArray, id) {
for (let i = 0; i < sourceArray.length; i++) {
let place = sourceArray[i];
if (place.id == id)
return i;
}
return -1;
},
lookupPlaceById: function(id) {
let colonIdx = id.indexOf(':');
let type = id.substring(0, colonIdx);
let sourceArray = null;
if (type == 'special')
sourceArray = this._defaultPlaces;
else if (type == 'mount')
sourceArray = this._mounts;
else if (type == 'bookmark')
sourceArray = this._bookmarks;
return sourceArray[this._lookupIndexById(sourceArray, id)];
},
_removeById: function(sourceArray, id) {
sourceArray.splice(this._lookupIndexById(sourceArray, id), 1);
}
});
Signals.addSignalMethods(PlacesManager.prototype);
const PlaceSearchProvider = new Lang.Class({
Name: 'PlaceSearchProvider',
Extends: Search.SearchProvider,
_init: function() {
this.parent(_("PLACES & DEVICES"));
this.placesManager = new PlacesManager();
},
getResultMetas: function(resultIds, callback) {
let metas = [];
for (let i = 0; i < resultIds.length; i++) {
let placeInfo = this.placesManager.lookupPlaceById(resultIds[i]);
if (!placeInfo)
metas.push(null);
else
metas.push({ 'id': resultIds[i],
'name': placeInfo.name,
'createIcon': function(size) {
return placeInfo.iconFactory(size);
}
});
}
callback(metas);
},
activateResult: function(id, params) {
let placeInfo = this.placesManager.lookupPlaceById(id);
placeInfo.launch(params);
},
_compareResultMeta: function (idA, idB) {
let infoA = this.placesManager.lookupPlaceById(idA);
let infoB = this.placesManager.lookupPlaceById(idB);
return infoA.name.localeCompare(infoB.name);
},
_searchPlaces: function(places, terms) {
let prefixResults = [];
let substringResults = [];
terms = terms.map(String.toLowerCase);
for (let i = 0; i < places.length; i++) {
let place = places[i];
let mtype = place.matchTerms(terms);
if (mtype == Search.MatchType.PREFIX)
prefixResults.push(place.id);
else if (mtype == Search.MatchType.SUBSTRING)
substringResults.push(place.id);
}
prefixResults.sort(Lang.bind(this, this._compareResultMeta));
substringResults.sort(Lang.bind(this, this._compareResultMeta));
this.searchSystem.pushResults(this, prefixResults.concat(substringResults));
},
getInitialResultSet: function(terms) {
let places = this.placesManager.getAllPlaces();
this._searchPlaces(places, terms);
},
getSubsearchResultSet: function(previousResults, terms) {
let places = previousResults.map(Lang.bind(this, function(id) {
return this.placesManager.lookupPlaceById(id);
}));
this._searchPlaces(places, terms);
}
});

View File

@ -11,7 +11,6 @@ const St = imports.gi.St;
const AppDisplay = imports.ui.appDisplay; const AppDisplay = imports.ui.appDisplay;
const Main = imports.ui.main; const Main = imports.ui.main;
const PlaceDisplay = imports.ui.placeDisplay;
const RemoteSearch = imports.ui.remoteSearch; const RemoteSearch = imports.ui.remoteSearch;
const Search = imports.ui.search; const Search = imports.ui.search;
const SearchDisplay = imports.ui.searchDisplay; const SearchDisplay = imports.ui.searchDisplay;
@ -98,7 +97,6 @@ const ViewSelector = new Lang.Class({
this.addSearchProvider(new Wanda.WandaSearchProvider()); this.addSearchProvider(new Wanda.WandaSearchProvider());
this.addSearchProvider(new AppDisplay.AppSearchProvider()); this.addSearchProvider(new AppDisplay.AppSearchProvider());
this.addSearchProvider(new AppDisplay.SettingsSearchProvider()); this.addSearchProvider(new AppDisplay.SettingsSearchProvider());
this.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
// Load remote search providers provided by applications // Load remote search providers provided by applications
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider)); RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));

View File

@ -19,371 +19,6 @@
#include <systemd/sd-login.h> #include <systemd/sd-login.h>
#endif #endif
/* Some code in this file adapted under the GPLv2+ from:
*
* GNOME panel utils: gnome-panel/gnome-panel/panel-util.c
* (C) 1997, 1998, 1999, 2000 The Free Software Foundation
* Copyright 2000 Helix Code, Inc.
* Copyright 2000,2001 Eazel, Inc.
* Copyright 2001 George Lebl
* Copyright 2002 Sun Microsystems Inc.
*
* Authors: George Lebl
* Jacob Berkman
* Mark McLoughlin
*/
static GFile *
shell_util_get_gfile_root (GFile *file)
{
GFile *parent;
GFile *parent_old;
/* search for the root on the URI */
parent_old = g_object_ref (file);
parent = g_file_get_parent (file);
while (parent != NULL)
{
g_object_unref (parent_old);
parent_old = parent;
parent = g_file_get_parent (parent);
}
return parent_old;
}
static char *
shell_util_get_file_display_name_if_mount (GFile *file)
{
GFile *compare;
GVolumeMonitor *monitor;
GList *mounts, *l;
char *ret;
ret = NULL;
/* compare with all mounts */
monitor = g_volume_monitor_get ();
mounts = g_volume_monitor_get_mounts (monitor);
for (l = mounts; l != NULL; l = l->next)
{
GMount *mount;
mount = G_MOUNT(l->data);
compare = g_mount_get_root (mount);
if (!ret && g_file_equal (file, compare))
ret = g_mount_get_name (mount);
g_object_unref (mount);
}
g_list_free (mounts);
g_object_unref (monitor);
return ret;
}
static char *
shell_util_get_file_display_for_common_files (GFile *file)
{
GFile *compare;
compare = g_file_new_for_path (g_get_home_dir ());
if (g_file_equal (file, compare))
{
g_object_unref (compare);
/* Translators: this is the same string as the one found in
* nautilus */
return g_strdup (_("Home"));
}
g_object_unref (compare);
compare = g_file_new_for_path ("/");
if (g_file_equal (file, compare))
{
g_object_unref (compare);
/* Translators: this is the same string as the one found in
* nautilus */
return g_strdup (_("File System"));
}
g_object_unref (compare);
return NULL;
}
static char *
shell_util_get_file_description (GFile *file)
{
GFileInfo *info;
char *ret;
ret = NULL;
info = g_file_query_info (file, "standard::description",
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL);
if (info)
{
ret = g_strdup (g_file_info_get_attribute_string(info,
G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION));
g_object_unref (info);
}
return ret;
}
static char *
shell_util_get_file_display_name (GFile *file, gboolean use_fallback)
{
GFileInfo *info;
char *ret;
ret = NULL;
info = g_file_query_info (file, "standard::display-name",
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL);
if (info)
{
ret = g_strdup (g_file_info_get_display_name (info));
g_object_unref (info);
}
if (!ret && use_fallback)
{
/* can happen with URI schemes non supported by gvfs */
char *basename;
basename = g_file_get_basename (file);
ret = g_filename_display_name (basename);
g_free (basename);
}
return ret;
}
static GIcon *
shell_util_get_file_icon_if_mount (GFile *file)
{
GFile *compare;
GVolumeMonitor *monitor;
GList *mounts, *l;
GIcon *ret;
ret = NULL;
/* compare with all mounts */
monitor = g_volume_monitor_get ();
mounts = g_volume_monitor_get_mounts (monitor);
for (l = mounts; l != NULL; l = l->next)
{
GMount *mount;
mount = G_MOUNT (l->data);
compare = g_mount_get_root (mount);
if (!ret && g_file_equal (file, compare))
{
ret = g_mount_get_icon (mount);
}
g_object_unref (mount);
}
g_list_free (mounts);
g_object_unref (monitor);
return ret;
}
static const char *
shell_util_get_icon_for_uri_known_folders (const char *uri)
{
const char *icon;
char *path;
int len;
icon = NULL;
if (!g_str_has_prefix (uri, "file:"))
return NULL;
path = g_filename_from_uri (uri, NULL, NULL);
len = strlen (path);
if (path[len] == '/')
path[len] = '\0';
if (strcmp (path, "/") == 0)
icon = "drive-harddisk";
else if (strcmp (path, g_get_home_dir ()) == 0)
icon = "user-home";
else if (strcmp (path, g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP))
== 0)
icon = "user-desktop";
g_free (path);
return icon;
}
/* This is based on nautilus_compute_title_for_uri() and
* nautilus_file_get_display_name_nocopy() */
char *
shell_util_get_label_for_uri (const char *text_uri)
{
GFile *file;
char *label;
GFile *root;
char *root_display;
/* Here's what we do:
* + x-nautilus-search: URI
* + check if the URI is a mount
* + if file: URI:
* - check for known file: URI
* - check for description of the GFile
* - use display name of the GFile
* + else:
* - check for description of the GFile
* - if the URI is a root: "root displayname"
* - else: "root displayname: displayname"
*/
label = NULL;
//FIXME: see nautilus_query_to_readable_string() to have a nice name
if (g_str_has_prefix (text_uri, "x-nautilus-search:"))
return g_strdup (_("Search"));
file = g_file_new_for_uri (text_uri);
label = shell_util_get_file_display_name_if_mount (file);
if (label)
{
g_object_unref (file);
return label;
}
if (g_str_has_prefix (text_uri, "file:"))
{
label = shell_util_get_file_display_for_common_files (file);
if (!label)
label = shell_util_get_file_description (file);
if (!label)
label = shell_util_get_file_display_name (file, TRUE);
g_object_unref (file);
return label;
}
label = shell_util_get_file_description (file);
if (label)
{
g_object_unref (file);
return label;
}
root = shell_util_get_gfile_root (file);
root_display = shell_util_get_file_description (root);
if (!root_display)
root_display = shell_util_get_file_display_name (root, FALSE);
if (!root_display)
/* can happen with URI schemes non supported by gvfs */
root_display = g_file_get_uri_scheme (root);
if (g_file_equal (file, root))
label = root_display;
else
{
char *displayname;
displayname = shell_util_get_file_display_name (file, TRUE);
/* Translators: the first string is the name of a gvfs
* method, and the second string is a path. For
* example, "Trash: some-directory". It means that the
* directory called "some-directory" is in the trash.
*/
label = g_strdup_printf (_("%1$s: %2$s"),
root_display, displayname);
g_free (root_display);
g_free (displayname);
}
g_object_unref (root);
g_object_unref (file);
return label;
}
/**
* shell_util_get_icon_for_uri:
* @text_uri: A URI
*
* Look up the icon that should be associated with a given URI. Handles
* various special GNOME-internal cases like x-nautilus-search, etc.
*
* Return Value: (transfer full): A new #GIcon
*/
GIcon *
shell_util_get_icon_for_uri (const char *text_uri)
{
const char *name;
GFile *file;
GFileInfo *info;
GIcon *retval;
/* Here's what we do:
* + check for known file: URI
* + x-nautilus-search: URI
* + override burn: URI icon
* + check if the URI is a mount
* + override trash: URI icon for subfolders
* + check for application/x-gnome-saved-search mime type and override
* icon of the GFile
* + use icon of the GFile
*/
/* this only checks file: URI */
name = shell_util_get_icon_for_uri_known_folders (text_uri);
if (name)
return g_themed_icon_new (name);
if (g_str_has_prefix (text_uri, "x-nautilus-search:"))
return g_themed_icon_new ("folder-saved-search");
/* gvfs doesn't give us a nice icon, so overriding */
if (g_str_has_prefix (text_uri, "burn:"))
return g_themed_icon_new ("nautilus-cd-burner");
file = g_file_new_for_uri (text_uri);
retval = shell_util_get_file_icon_if_mount (file);
if (retval)
return retval;
/* gvfs doesn't give us a nice icon for subfolders of the trash, so
* overriding */
if (g_str_has_prefix (text_uri, "trash:"))
{
GFile *root;
root = shell_util_get_gfile_root (file);
g_object_unref (file);
file = root;
}
info = g_file_query_info (file, "standard::icon", G_FILE_QUERY_INFO_NONE,
NULL, NULL);
g_object_unref (file);
if (!info)
return g_themed_icon_new ("gtk-file");
retval = g_file_info_get_icon (info);
if (retval)
g_object_ref (retval);
g_object_unref (info);
if (retval)
return retval;
return g_themed_icon_new ("gtk-file");
}
static void static void
stop_pick (ClutterActor *actor, stop_pick (ClutterActor *actor,
const ClutterColor *color) const ClutterColor *color)

View File

@ -10,9 +10,6 @@
G_BEGIN_DECLS G_BEGIN_DECLS
char *shell_util_get_label_for_uri (const char *text_uri);
GIcon *shell_util_get_icon_for_uri (const char *text_uri);
void shell_util_set_hidden_from_pick (ClutterActor *actor, void shell_util_set_hidden_from_pick (ClutterActor *actor,
gboolean hidden); gboolean hidden);