Compare commits

...

8 Commits

Author SHA1 Message Date
Matthias Clasen
5b9a7c8bf1 file chooser: Note when searching remote locations
Inform the user that we won't search recursively when searching
in remote locations.
2015-07-24 16:26:32 -04:00
Matthias Clasen
1c252c2962 Avoid more GFile<>uri roundtrips
Make GtkSearchHit carry a GFile instead of an uri. Most of the
search engines already have the object around, and converting
to an uri and back is unnecessary extra work.
2015-07-24 16:03:56 -04:00
Matthias Clasen
b3ceb19dfe search engine: Don't crawl remote locations
This is slow, and causes too much network I/O.
So skip locations that look like they are remote.
2015-07-24 16:03:35 -04:00
Matthias Clasen
59fc57bdc3 Add a helper function for remote locations
Add a helper function that says whether a location should be
considered remote. To determine this, we look at the filesystem
type reported by gvfs, and say 'remote' for sftp, webdav, ftp,
nfs and cifs.
2015-07-24 16:03:35 -04:00
Matthias Clasen
df9658c0c3 Actually use search results from the model
We didn't connect to the signals, so we never picked up
any search results from the model engine. Good thing, since
it was returning the wrong thing.
2015-07-24 15:44:20 -04:00
Matthias Clasen
360ce4aaa8 Port to GtkSearchHit
GtkSearchEngineModel was still trying to return uris as hits.
This is not working anymore, we are expected to return GtkSearchHit
structs.
2015-07-24 15:41:45 -04:00
Matthias Clasen
50dabbb60c Always pass a location into the query
Failure to do so was causing search to start from the home dir
when the current folder is not represented on the sidebar.
2015-07-24 15:39:31 -04:00
Matthias Clasen
3d2ad0851e Store locations as GFile
It is a bit pointless to have the file chooser get a uri from an
existing GFile to put in the query, only to have some of the search
engines reconstruct a GFile from it.
2015-07-24 15:39:31 -04:00
11 changed files with 188 additions and 134 deletions

View File

@@ -216,6 +216,7 @@ struct _GtkFileChooserWidgetPrivate {
GtkWidget *browse_files_stack;
GtkWidget *browse_files_swin;
GtkWidget *browse_files_tree_view;
GtkWidget *remote_warning_bar;
GtkWidget *browse_files_popover;
GtkWidget *add_shortcut_item;
@@ -3024,6 +3025,7 @@ operation_mode_stop (GtkFileChooserWidget *impl,
g_clear_object (&impl->priv->model_for_search);
search_stop_searching (impl, TRUE);
search_clear_model (impl, TRUE);
gtk_widget_hide (impl->priv->remote_warning_bar);
}
}
@@ -7011,9 +7013,7 @@ search_engine_hits_added_cb (GtkSearchEngine *engine,
for (l = hits; l; l = l->next)
{
GtkSearchHit *hit = (GtkSearchHit *)l->data;
file = g_file_new_for_uri (hit->uri);
if (!file)
continue;
file = g_object_ref (hit->file);
if (hit->info)
{
files_with_info = g_list_prepend (files_with_info, file);
@@ -7212,12 +7212,11 @@ search_start_query (GtkFileChooserWidget *impl,
file = gtk_places_sidebar_get_location (GTK_PLACES_SIDEBAR (priv->places_sidebar));
if (file)
{
gchar *location;
location = g_file_get_uri (file);
gtk_query_set_location (priv->search_query, location);
g_free (location);
gtk_query_set_location (priv->search_query, file);
g_object_unref (file);
}
else
gtk_query_set_location (priv->search_query, priv->current_folder);
_gtk_search_engine_set_model (priv->search_engine, priv->model_for_search);
_gtk_search_engine_set_query (priv->search_engine, priv->search_query);
@@ -7230,6 +7229,9 @@ search_start_query (GtkFileChooserWidget *impl,
G_CALLBACK (search_engine_error_cb), impl);
_gtk_search_engine_start (priv->search_engine);
if (_gtk_file_consider_as_remote (gtk_query_get_location (priv->search_query)))
gtk_widget_show (priv->remote_warning_bar);
}
/* Callback used when the user presses Enter while typing on the search
@@ -8359,6 +8361,7 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, rename_file_rename_button);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, rename_file_error_label);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, rename_file_popover);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, remote_warning_bar);
/* And a *lot* of callbacks to bind ... */
gtk_widget_class_bind_template_callback (widget_class, browse_files_key_press_event_cb);

View File

@@ -921,3 +921,34 @@ _gtk_file_has_native_path (GFile *file)
return has_native_path;
}
static const gchar * const remote_types[] = {
"sftp",
"webdav",
"ftp",
"nfs",
"cifs",
NULL
};
gboolean
_gtk_file_consider_as_remote (GFile *file)
{
GFileInfo *info;
gboolean is_remote;
info = g_file_query_filesystem_info (file, "filesystem::type", NULL, NULL);
if (info)
{
const gchar *type;
type = g_file_info_get_attribute_string (info, "filesystem::type");
is_remote = g_strv_contains (remote_types, type);
g_object_unref (info);
}
else
is_remote = FALSE;
return is_remote;
}

View File

@@ -118,6 +118,8 @@ gboolean _gtk_file_info_consider_as_directory (GFileInfo *info);
/* GFile helper functions */
gboolean _gtk_file_has_native_path (GFile *file);
gboolean _gtk_file_consider_as_remote (GFile *file);
G_END_DECLS
#endif /* __GTK_FILE_SYSTEM_H__ */

View File

@@ -27,7 +27,7 @@
struct _GtkQueryPrivate
{
gchar *text;
gchar *location_uri;
GFile *location;
GList *mime_types;
gchar **words;
};
@@ -41,8 +41,8 @@ finalize (GObject *object)
query = GTK_QUERY (object);
g_clear_object (&query->priv->location);
g_free (query->priv->text);
g_free (query->priv->location_uri);
g_strfreev (query->priv->words);
G_OBJECT_CLASS (gtk_query_parent_class)->finalize (object);
@@ -87,18 +87,17 @@ gtk_query_set_text (GtkQuery *query,
query->priv->words = NULL;
}
const gchar *
GFile *
gtk_query_get_location (GtkQuery *query)
{
return query->priv->location_uri;
return query->priv->location;
}
void
gtk_query_set_location (GtkQuery *query,
const gchar *uri)
gtk_query_set_location (GtkQuery *query,
GFile *file)
{
g_free (query->priv->location_uri);
query->priv->location_uri = g_strdup (uri);
g_set_object (&query->priv->location, file);
}
static gchar *

View File

@@ -22,7 +22,7 @@
#ifndef __GTK_QUERY_H__
#define __GTK_QUERY_H__
#include <glib-object.h>
#include <gio/gio.h>
G_BEGIN_DECLS
@@ -57,9 +57,9 @@ const gchar *gtk_query_get_text (GtkQuery *query);
void gtk_query_set_text (GtkQuery *query,
const gchar *text);
const gchar *gtk_query_get_location (GtkQuery *query);
GFile *gtk_query_get_location (GtkQuery *query);
void gtk_query_set_location (GtkQuery *query,
const gchar *uri);
GFile *file);
gboolean gtk_query_matches_string (GtkQuery *query,
const gchar *string);

View File

@@ -311,7 +311,7 @@ search_hit_equal (gconstpointer a, gconstpointer b)
const GtkSearchHit *ha = (const GtkSearchHit *)a;
const GtkSearchHit *hb = (const GtkSearchHit *)b;
return g_str_equal (ha->uri, hb->uri);
return g_file_equal (ha->file, hb->file);
}
@@ -320,7 +320,7 @@ search_hit_hash (gconstpointer a)
{
const GtkSearchHit *ha = (const GtkSearchHit *)a;
return g_str_hash (ha->uri);
return g_file_hash (ha->file);
}
GtkSearchHit *
@@ -329,7 +329,7 @@ _gtk_search_hit_dup (GtkSearchHit *hit)
GtkSearchHit *dup;
dup = g_new (GtkSearchHit, 1);
dup->uri = g_strdup (hit->uri);
dup->file = g_object_ref (hit->file);
if (hit->info)
dup->info = g_object_ref (hit->info);
else
@@ -341,7 +341,7 @@ _gtk_search_hit_dup (GtkSearchHit *hit)
void
_gtk_search_hit_free (GtkSearchHit *hit)
{
g_free (hit->uri);
g_clear_object (&hit->file);
g_clear_object (&hit->info);
g_free (hit);
}
@@ -481,6 +481,7 @@ _gtk_search_engine_set_model (GtkSearchEngine *engine,
if (model)
{
engine->priv->model = _gtk_search_engine_model_new (model);
connect_engine_signals (engine->priv->model, engine);
if (engine->priv->query)
_gtk_search_engine_set_query (engine->priv->model, engine->priv->query);
}

View File

@@ -42,7 +42,7 @@ typedef struct _GtkSearchHit GtkSearchHit;
struct _GtkSearchHit
{
gchar *uri;
GFile *file;
GFileInfo *info; /* may be NULL */
};

View File

@@ -90,23 +90,26 @@ do_search (gpointer data)
do
{
GFileInfo *info;
GFile *file;
gchar *uri;
info = _gtk_file_system_model_get_info (model->model, &iter);
if (info_matches_query (model->query, info))
{
GFile *file;
GtkSearchHit *hit;
file = _gtk_file_system_model_get_file (model->model, &iter);
uri = g_file_get_uri (file);
hits = g_list_prepend (hits, uri);
hit = g_new (GtkSearchHit, 1);
hit->file = g_object_ref (file);
hit->info = g_object_ref (info);
hits = g_list_prepend (hits, hit);
}
}
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model->model), &iter));
}
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model->model), &iter));
if (hits)
{
_gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (model), hits);
g_list_free_full (hits, g_free);
g_list_free_full (hits, (GDestroyNotify)_gtk_search_hit_free);
}
}
@@ -144,19 +147,11 @@ gtk_search_engine_model_stop (GtkSearchEngine *engine)
static void
gtk_search_engine_model_set_query (GtkSearchEngine *engine,
GtkQuery *query)
GtkQuery *query)
{
GtkSearchEngineModel *model;
GtkSearchEngineModel *model = GTK_SEARCH_ENGINE_MODEL (engine);
model = GTK_SEARCH_ENGINE_MODEL (engine);
if (query)
g_object_ref (query);
if (model->query)
g_object_unref (model->query);
model->query = query;
g_set_object (&model->query, query);
}
static void

View File

@@ -26,6 +26,7 @@
#include <gdk/gdk.h>
#include "gtksearchenginesimple.h"
#include "gtkfilesystem.h"
#include "gtkprivate.h"
#include <string.h>
@@ -87,13 +88,19 @@ gtk_search_engine_simple_dispose (GObject *object)
G_OBJECT_CLASS (_gtk_search_engine_simple_parent_class)->dispose (object);
}
static void
queue_if_local (SearchThreadData *data,
GFile *file)
{
if (!_gtk_file_consider_as_remote (file))
g_queue_push_tail (data->directories, g_object_ref (file));
}
static SearchThreadData *
search_thread_data_new (GtkSearchEngineSimple *engine,
GtkQuery *query)
{
SearchThreadData *data;
const gchar *uri;
GFile *location;
data = g_new0 (SearchThreadData, 1);
@@ -101,12 +108,7 @@ search_thread_data_new (GtkSearchEngineSimple *engine,
data->directories = g_queue_new ();
data->query = g_object_ref (query);
data->recursive = _gtk_search_engine_get_recursive (GTK_SEARCH_ENGINE (engine));
uri = gtk_query_get_location (query);
if (uri != NULL)
location = g_file_new_for_uri (uri);
else
location = g_file_new_for_path (g_get_home_dir ());
g_queue_push_tail (data->directories, location);
queue_if_local (data, gtk_query_get_location (query));
data->cancellable = g_cancellable_new ();
@@ -246,7 +248,7 @@ visit_directory (GFile *dir, SearchThreadData *data)
GtkSearchHit *hit;
hit = g_new (GtkSearchHit, 1);
hit->uri = g_file_get_uri (child);
hit->file = g_object_ref (child);
hit->info = g_object_ref (info);
data->hits = g_list_prepend (data->hits, hit);
}
@@ -258,7 +260,7 @@ visit_directory (GFile *dir, SearchThreadData *data)
if (data->recursive &&
g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY &&
!is_indexed (data->engine, child))
g_queue_push_tail (data->directories, g_object_ref (child));
queue_if_local (data, child);
}
g_object_unref (enumerator);

View File

@@ -300,7 +300,7 @@ query_callback (GObject *object,
v = g_variant_iter_next_value (&iter);
strv = g_variant_get_strv (v, NULL);
hit[i].uri = (gchar*)strv[0];
hit[i].file = g_file_new_for_uri (strv[0]);
hit[i].info = NULL;
g_free (strv);
hits = g_list_prepend (hits, &hit[i]);
@@ -321,7 +321,7 @@ gtk_search_engine_tracker_start (GtkSearchEngine *engine)
{
GtkSearchEngineTracker *tracker;
const gchar *search_text;
const gchar *location_uri;
GFile *location;
GString *sparql;
gboolean recursive;
@@ -340,7 +340,7 @@ gtk_search_engine_tracker_start (GtkSearchEngine *engine)
}
search_text = gtk_query_get_text (tracker->query);
location_uri = gtk_query_get_location (tracker->query);
location = gtk_query_get_location (tracker->query);
recursive = _gtk_search_engine_get_recursive (engine);
sparql = g_string_new ("SELECT nie:url(?urn) "
@@ -360,8 +360,9 @@ gtk_search_engine_tracker_start (GtkSearchEngine *engine)
sparql_append_string_literal_lower_case (sparql, search_text);
g_string_append (sparql, ")");
if (location_uri)
if (location)
{
gchar *location_uri = g_file_get_uri (location);
g_string_append (sparql, " && ");
if (recursive)
g_string_append (sparql, "tracker:uri-is-descendant(");
@@ -369,6 +370,7 @@ gtk_search_engine_tracker_start (GtkSearchEngine *engine)
g_string_append (sparql, "tracker:uri-is-parent(");
sparql_append_string_literal (sparql, location_uri, FALSE);
g_string_append (sparql, ",nie:url(?urn))");
g_free (location_uri);
}
g_string_append (sparql, ")");

View File

@@ -152,95 +152,114 @@
<class name="view"/>
</style>
<child>
<object class="GtkScrolledWindow" id="browse_files_swin">
<object class="GtkBox">
<property name="visible">True</property>
<property name="hscrollbar_policy">never</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkTreeView" id="browse_files_tree_view">
<object class="GtkScrolledWindow" id="browse_files_swin">
<property name="visible">True</property>
<property name="has_tooltip">True</property>
<property name="enable-search">False</property>
<child internal-child="accessible">
<object class="AtkObject" id="browse_files_tree_view-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Files</property>
</object>
</child>
<signal name="button-press-event" handler="list_button_press_event_cb" swapped="no"/>
<signal name="drag-data-received" handler="file_list_drag_data_received_cb" swapped="no"/>
<signal name="drag-drop" handler="file_list_drag_drop_cb" swapped="no"/>
<signal name="drag-begin" handler="file_list_drag_begin_cb" swapped="no"/>
<signal name="drag-motion" handler="file_list_drag_motion_cb" swapped="no"/>
<signal name="drag-end" handler="file_list_drag_end_cb" swapped="no"/>
<signal name="key-press-event" handler="browse_files_key_press_event_cb" swapped="no"/>
<signal name="popup-menu" handler="list_popup_menu_cb" swapped="no"/>
<signal name="query-tooltip" handler="file_list_query_tooltip_cb" swapped="no"/>
<signal name="row-activated" handler="list_row_activated" swapped="no"/>
<signal name="cursor-changed" handler="list_cursor_changed" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection2">
<signal name="changed" handler="list_selection_changed" swapped="no"/>
</object>
</child>
<property name="hscrollbar_policy">never</property>
<child>
<object class="GtkTreeViewColumn" id="list_name_column">
<property name="title" translatable="yes">Name</property>
<property name="resizable">True</property>
<property name="expand">True</property>
<child>
<object class="GtkCellRendererPixbuf" id="list_pixbuf_renderer">
<property name="xpad">6</property>
<object class="GtkTreeView" id="browse_files_tree_view">
<property name="visible">True</property>
<property name="has_tooltip">True</property>
<property name="enable-search">False</property>
<child internal-child="accessible">
<object class="AtkObject" id="browse_files_tree_view-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Files</property>
</object>
</child>
<signal name="button-press-event" handler="list_button_press_event_cb" swapped="no"/>
<signal name="drag-data-received" handler="file_list_drag_data_received_cb" swapped="no"/>
<signal name="drag-drop" handler="file_list_drag_drop_cb" swapped="no"/>
<signal name="drag-begin" handler="file_list_drag_begin_cb" swapped="no"/>
<signal name="drag-motion" handler="file_list_drag_motion_cb" swapped="no"/>
<signal name="drag-end" handler="file_list_drag_end_cb" swapped="no"/>
<signal name="key-press-event" handler="browse_files_key_press_event_cb" swapped="no"/>
<signal name="popup-menu" handler="list_popup_menu_cb" swapped="no"/>
<signal name="query-tooltip" handler="file_list_query_tooltip_cb" swapped="no"/>
<signal name="row-activated" handler="list_row_activated" swapped="no"/>
<signal name="cursor-changed" handler="list_cursor_changed" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection2">
<signal name="changed" handler="list_selection_changed" swapped="no"/>
</object>
</child>
<child>
<object class="GtkCellRendererText" id="list_name_renderer">
<property name="width-chars">10</property>
<property name="ellipsize">end</property>
<object class="GtkTreeViewColumn" id="list_name_column">
<property name="title" translatable="yes">Name</property>
<property name="resizable">True</property>
<property name="expand">True</property>
<child>
<object class="GtkCellRendererPixbuf" id="list_pixbuf_renderer">
<property name="xpad">6</property>
</object>
</child>
<child>
<object class="GtkCellRendererText" id="list_name_renderer">
<property name="width-chars">10</property>
<property name="ellipsize">end</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="list_location_column">
<property name="title" translatable="yes">Location</property>
<property name="resizable">True</property>
<property name="visible">False</property>
<property name="expand">True</property>
<child>
<object class="GtkCellRendererText" id="list_location_renderer">
<property name="xalign">0</property>
<property name="width-chars">10</property>
<property name="ellipsize">start</property>
<property name="xpad">6</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="list_size_column">
<property name="title" translatable="yes">Size</property>
<property name="sizing">fixed</property>
<child>
<object class="GtkCellRendererText" id="list_size_renderer">
<property name="xalign">0</property>
<property name="xpad">6</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="list_time_column">
<property name="title" translatable="yes">Modified</property>
<property name="sizing">fixed</property>
<child>
<object class="GtkCellRendererText" id="list_date_renderer">
<property name="xpad">6</property>
</object>
</child>
<child>
<object class="GtkCellRendererText" id="list_time_renderer">
<property name="xpad">6</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="list_location_column">
<property name="title" translatable="yes">Location</property>
<property name="resizable">True</property>
<property name="visible">False</property>
<property name="expand">True</property>
<child>
<object class="GtkCellRendererText" id="list_location_renderer">
<property name="xalign">0</property>
<property name="width-chars">10</property>
<property name="ellipsize">start</property>
<property name="xpad">6</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="list_size_column">
<property name="title" translatable="yes">Size</property>
<property name="sizing">fixed</property>
<child>
<object class="GtkCellRendererText" id="list_size_renderer">
<property name="xalign">0</property>
<property name="xpad">6</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="list_time_column">
<property name="title" translatable="yes">Modified</property>
<property name="sizing">fixed</property>
<child>
<object class="GtkCellRendererText" id="list_date_renderer">
<property name="xpad">6</property>
</object>
</child>
<child>
<object class="GtkCellRendererText" id="list_time_renderer">
<property name="xpad">6</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
</packing>
</child>
<child>
<object class="GtkActionBar" id="remote_warning_bar">
<child type="center">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Remote location — only searching the current folder</property>
</object>
</child>
</object>
@@ -253,7 +272,7 @@
<child>
<object class="GtkPlacesView" id="places_view">
<property name="visible">True</property>
<property name="local_only" bind-source="GtkFileChooserWidget" bind-property="local-only" bind-flags="default|sync-create" />
<property name="local_only" bind-source="GtkFileChooserWidget" bind-property="local-only" bind-flags="default|sync-create"/>
<signal name="open-location" handler="places_sidebar_open_location_cb" swapped="no"/>
<signal name="show-error-message" handler="places_sidebar_show_error_message_cb" swapped="no"/>
</object>