/*
* Copyright (C) 2005 Red Hat, Inc
*
* Nautilus is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* Nautilus is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; see the file COPYING. If not,
* see .
*
* Author: Alexander Larsson
*
*/
#define G_LOG_DOMAIN "nautilus-search"
#include
#include "nautilus-search-engine-simple.h"
#include "nautilus-file-utilities.h"
#include "nautilus-query.h"
#include "nautilus-search-hit.h"
#include "nautilus-search-provider.h"
#include "nautilus-ui-utilities.h"
#include
#include
#include
#define FLUSH_TIME_SPAN (250 * G_TIME_SPAN_MILLISECOND)
struct _NautilusSearchEngineSimple
{
NautilusSearchProvider parent_instance;
gint64 last_saved_time;
};
G_DEFINE_FINAL_TYPE (NautilusSearchEngineSimple,
nautilus_search_engine_simple,
NAUTILUS_TYPE_SEARCH_PROVIDER)
#define STD_ATTRIBUTES \
G_FILE_ATTRIBUTE_STANDARD_NAME "," \
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," \
G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP "," \
G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN "," \
G_FILE_ATTRIBUTE_STANDARD_TYPE "," \
G_FILE_ATTRIBUTE_TIME_MODIFIED "," \
G_FILE_ATTRIBUTE_TIME_ACCESS "," \
G_FILE_ATTRIBUTE_TIME_CREATED "," \
G_FILE_ATTRIBUTE_ID_FILE
#define STD_ATTRIBUTES_WITH_CONTENT_TYPE \
STD_ATTRIBUTES "," \
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \
G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE
static void
iterate_file (GFileInfo *info,
GFile *location,
NautilusSearchEngineSimple *self)
{
NautilusQuery *query = nautilus_search_provider_get_query (self);
NautilusSearchTimeType type = nautilus_query_get_search_type (query);
g_autoptr (GPtrArray) date_range = nautilus_query_get_date_range (query);
gboolean show_hidden = nautilus_query_get_show_hidden_files (query);
const char *display_name = g_file_info_get_display_name (info);
if (display_name == NULL)
{
return;
}
if (!show_hidden &&
(g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN) ||
g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP)))
{
return;
}
gdouble match = nautilus_query_matches_string (query, display_name);
gboolean found = (match > -1);
gint64 current_time;
if (found && nautilus_query_has_mime_types (query))
{
const char *mime_type = g_file_info_get_attribute_string (
info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
if (mime_type == NULL)
{
mime_type = g_file_info_get_attribute_string (info,
G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE);
}
found = nautilus_query_matches_mime_type (query, mime_type);
}
g_autoptr (GDateTime) mtime = g_file_info_get_modification_date_time (info);
g_autoptr (GDateTime) atime = g_file_info_get_access_date_time (info);
g_autoptr (GDateTime) ctime = g_file_info_get_creation_date_time (info);
if (found && date_range != NULL)
{
GDateTime *target_date;
GDateTime *initial_date = g_ptr_array_index (date_range, 0);
GDateTime *end_date = g_ptr_array_index (date_range, 1);
switch (type)
{
case NAUTILUS_SEARCH_TIME_TYPE_LAST_ACCESS:
{
target_date = atime;
}
break;
case NAUTILUS_SEARCH_TIME_TYPE_LAST_MODIFIED:
{
target_date = mtime;
}
break;
case NAUTILUS_SEARCH_TIME_TYPE_CREATED:
{
target_date = ctime;
}
break;
default:
{
target_date = NULL;
}
}
found = nautilus_date_time_is_between_dates (target_date,
initial_date,
end_date);
}
if (found)
{
g_autofree gchar *uri = g_file_get_uri (location);
NautilusSearchHit *hit = nautilus_search_hit_new (uri);
nautilus_search_hit_set_fts_rank (hit, match);
nautilus_search_hit_set_modification_time (hit, mtime);
nautilus_search_hit_set_access_time (hit, atime);
nautilus_search_hit_set_creation_time (hit, ctime);
nautilus_search_provider_add_hit (self, hit);
}
current_time = g_get_monotonic_time ();
if (current_time - self->last_saved_time >= FLUSH_TIME_SPAN)
{
self->last_saved_time = current_time;
nautilus_search_provider_flush_hits (self);
}
}
static void
iterate_finish (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
NautilusSearchEngineSimple *self = user_data;
g_idle_add_once ((GSourceOnceFunc) nautilus_search_provider_finished, self);
}
static const char *
get_name (NautilusSearchProvider *provider)
{
return "simple";
}
static gboolean
run_in_thread (NautilusSearchProvider *provider)
{
return TRUE;
}
static guint
search_delay (NautilusSearchProvider *provider)
{
return 500;
}
static gboolean
should_search (NautilusSearchProvider *provider,
NautilusQuery *query)
{
g_autoptr (GFile) location = nautilus_query_get_location (query);
return location != NULL;
}
static void
start_search (NautilusSearchProvider *provider)
{
NautilusSearchEngineSimple *self = NAUTILUS_SEARCH_ENGINE_SIMPLE (provider);
GCancellable *cancellable = nautilus_search_provider_get_cancellable (self);
NautilusQuery *query = nautilus_search_provider_get_query (self);
g_autoptr (GFile) toplevel = nautilus_query_get_location (query);
gboolean local_only = nautilus_query_recursive_local_only (query);
const char *attributes = nautilus_query_has_mime_types (query)
? STD_ATTRIBUTES_WITH_CONTENT_TYPE
: STD_ATTRIBUTES;
gboolean recursion_enabled = nautilus_query_recursive (query);
nautilus_iterate_directory_recursive (toplevel,
recursion_enabled ? G_MAXUINT : 0,
attributes,
local_only,
cancellable,
(IterationFileCallback) iterate_file,
iterate_finish,
self);
}
static void
nautilus_search_engine_simple_class_init (NautilusSearchEngineSimpleClass *class)
{
NautilusSearchProviderClass *search_provider_class = NAUTILUS_SEARCH_PROVIDER_CLASS (class);
search_provider_class->get_name = get_name;
search_provider_class->run_in_thread = run_in_thread;
search_provider_class->search_delay = search_delay;
search_provider_class->should_search = should_search;
search_provider_class->start_search = start_search;
}
static void
nautilus_search_engine_simple_init (NautilusSearchEngineSimple *self)
{
self->last_saved_time = g_get_monotonic_time ();
}
NautilusSearchEngineSimple *
nautilus_search_engine_simple_new (void)
{
NautilusSearchEngineSimple *engine;
engine = g_object_new (NAUTILUS_TYPE_SEARCH_ENGINE_SIMPLE, NULL);
return engine;
}