[nautilus] implement fts



commit 11cbe223a554549dc1b42d0c91a3d5b569bc3971
Author: Alexandru Pandelea <alexandru pandelea gmail com>
Date:   Fri May 26 23:22:12 2017 +0300

    implement fts
    
    The search text can now also match the contents of a file, besides
    the file name.
    
    This is done with the help of a Tracker query, using fts:match, which
    matces both the contents of a file and the filename.
    
    The user also has the option to choose whether to use or not the
    Full Text Search. This can be done with a preference, which represents
    the default option when opening a new tab/window or from the search
    popover.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=775961

 data/org.gnome.nautilus.gschema.xml             |    5 ++
 src/nautilus-file-private.h                     |    1 +
 src/nautilus-file.c                             |   15 +++++
 src/nautilus-file.h                             |    4 +
 src/nautilus-global-preferences.h               |    3 +
 src/nautilus-list-view.c                        |   68 +++++++++++++++++++++-
 src/nautilus-preferences-window.c               |    5 ++
 src/nautilus-query-editor.c                     |   37 ++++++++++++
 src/nautilus-search-directory.c                 |    1 +
 src/nautilus-search-engine-tracker.c            |   39 +++++++++---
 src/nautilus-search-hit.c                       |   39 +++++++++++++
 src/nautilus-search-hit.h                       |    4 +-
 src/nautilus-search-popover.c                   |   70 +++++++++++++++++++++++
 src/nautilus-search-popover.h                   |    4 +
 src/resources/ui/nautilus-preferences-window.ui |   30 ++++++++++
 src/resources/ui/nautilus-search-popover.ui     |    4 +
 16 files changed, 316 insertions(+), 13 deletions(-)
---
diff --git a/data/org.gnome.nautilus.gschema.xml b/data/org.gnome.nautilus.gschema.xml
index e162ebb..f093c3c 100644
--- a/data/org.gnome.nautilus.gschema.xml
+++ b/data/org.gnome.nautilus.gschema.xml
@@ -217,6 +217,11 @@
       <summary>Enable new experimental views</summary>
       <description>Whether to use the new experimental views using the latest GTK+ widgets to help giving 
feedback and shaping their future.</description>
     </key>
+    <key type="b" name="fts-default">
+      <default>true</default>
+      <summary>Whether to have full text search enabled by default when opening a new window/tab</summary>
+      <description>If set to true, then Nautilus will also match the file contents besides the name. This 
toggles the default active state, which can still be overriden in the search popover</description>
+    </key>
   </schema>
 
   <schema path="/org/gnome/nautilus/compression/" id="org.gnome.nautilus.compression" 
gettext-domain="nautilus">
diff --git a/src/nautilus-file-private.h b/src/nautilus-file-private.h
index d040a51..adcfacf 100644
--- a/src/nautilus-file-private.h
+++ b/src/nautilus-file-private.h
@@ -208,6 +208,7 @@ struct NautilusFileDetails
        time_t recency; /* 0 is unknown */
 
        gdouble search_relevance;
+       gchar *fts_snippet;
 
        guint64 free_space; /* (guint)-1 for unknown */
        time_t free_space_read; /* The time free_space was updated, or 0 for never */
diff --git a/src/nautilus-file.c b/src/nautilus-file.c
index e7e96dc..55c44aa 100644
--- a/src/nautilus-file.c
+++ b/src/nautilus-file.c
@@ -922,6 +922,8 @@ finalize (GObject *object)
         metadata_hash_free (file->details->metadata);
     }
 
+    g_free (file->details->fts_snippet);
+
     G_OBJECT_CLASS (nautilus_file_parent_class)->finalize (object);
 }
 
@@ -6149,6 +6151,19 @@ nautilus_file_set_search_relevance (NautilusFile *file,
     file->details->search_relevance = relevance;
 }
 
+void
+nautilus_file_set_search_fts_snippet (NautilusFile *file,
+                                      const gchar  *fts_snippet)
+{
+    file->details->fts_snippet = g_strdup (fts_snippet);
+}
+
+const gchar*
+nautilus_file_get_search_fts_snippet (NautilusFile *file)
+{
+    return file->details->fts_snippet;
+}
+
 /**
  * nautilus_file_can_get_permissions:
  *
diff --git a/src/nautilus-file.h b/src/nautilus-file.h
index e941e7a..c4d1780 100644
--- a/src/nautilus-file.h
+++ b/src/nautilus-file.h
@@ -237,6 +237,10 @@ gboolean                nautilus_file_should_show_directory_item_count  (Nautilu
 
 void                    nautilus_file_set_search_relevance              (NautilusFile                   
*file,
                                                                         gdouble                         
relevance);
+void                    nautilus_file_set_search_fts_snippet            (NautilusFile                   
*file,
+                                                                         const gchar                    
*fts_snippet);
+const gchar*            nautilus_file_get_search_fts_snippet            (NautilusFile                   
*file);
+
 void                    nautilus_file_set_attributes                    (NautilusFile                   
*file, 
                                                                         GFileInfo                      
*attributes,
                                                                         NautilusFileOperationCallback   
callback,
diff --git a/src/nautilus-global-preferences.h b/src/nautilus-global-preferences.h
index 7e52f6c..f508f7d 100644
--- a/src/nautilus-global-preferences.h
+++ b/src/nautilus-global-preferences.h
@@ -177,6 +177,9 @@ typedef enum
 #define NAUTILUS_PREFERENCES_SHOW_DELETE_PERMANENTLY "show-delete-permanently"
 #define NAUTILUS_PREFERENCES_SHOW_CREATE_LINK "show-create-link"
 
+/* Full Text Search as default */
+#define NAUTILUS_PREFERENCES_FTS_DEFAULT "fts-default"
+
 void nautilus_global_preferences_init                      (void);
 
 extern GSettings *nautilus_preferences;
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c
index aa0e5a3..14a074a 100644
--- a/src/nautilus-list-view.c
+++ b/src/nautilus-list-view.c
@@ -37,6 +37,7 @@
 #include <eel/eel-vfs-extensions.h>
 #include <eel/eel-gdk-extensions.h>
 #include <eel/eel-glib-extensions.h>
+#include <eel/eel-string.h>
 #include <gdk/gdk.h>
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
@@ -1552,13 +1553,37 @@ filename_cell_data_func (GtkTreeViewColumn *column,
                          NautilusListView  *view)
 {
     char *text;
+    g_autofree gchar *escaped_text = NULL;
+    g_autofree gchar *escaped_name = NULL;
+    g_autofree gchar *replaced_text = NULL;
     GtkTreePath *path;
     PangoUnderline underline;
+    GString *display_text;
+    NautilusDirectory *directory;
+    NautilusQuery *query = NULL;
+    NautilusQuerySearchContent content;
+    NautilusFile *file;
+    const gchar *snippet;
 
     gtk_tree_model_get (model, iter,
                         view->details->file_name_column_num, &text,
                         -1);
 
+    escaped_name = g_markup_escape_text (text, -1);
+    display_text = g_string_new(escaped_name);
+
+    directory = nautilus_files_view_get_model (NAUTILUS_FILES_VIEW (view));
+
+    if (NAUTILUS_IS_SEARCH_DIRECTORY (directory))
+    {
+        query = nautilus_search_directory_get_query (NAUTILUS_SEARCH_DIRECTORY (directory));
+    }
+
+    if (query)
+    {
+        content = nautilus_query_get_search_content (query);
+    }
+
     if (get_click_policy () == NAUTILUS_CLICK_POLICY_SINGLE)
     {
         path = gtk_tree_model_get_path (model, iter);
@@ -1580,11 +1605,30 @@ filename_cell_data_func (GtkTreeViewColumn *column,
         underline = PANGO_UNDERLINE_NONE;
     }
 
+    if (query && content == NAUTILUS_QUERY_SEARCH_CONTENT_FULL_TEXT)
+    {
+        gtk_tree_model_get (model, iter,
+                            NAUTILUS_LIST_MODEL_FILE_COLUMN, &file,
+                            -1);
+
+        snippet = nautilus_file_get_search_fts_snippet (file);
+        if (snippet)
+        {
+            replaced_text = eel_str_replace_substring (snippet, "\n", "");
+            escaped_text = g_markup_escape_text (replaced_text, -1);
+            g_string_append_printf (display_text, "\n<small><span color='grey'>%s</span></small>", 
escaped_text);
+        }
+
+        nautilus_file_unref (file);
+    }
+
     g_object_set (G_OBJECT (renderer),
-                  "text", text,
+                  "markup", display_text->str,
                   "underline", underline,
                   NULL);
+
     g_free (text);
+    g_string_free (display_text, TRUE);
 }
 
 static void
@@ -1798,6 +1842,9 @@ create_and_set_up_tree_view (NautilusListView *view)
     GList *l;
     gchar **default_column_order, **default_visible_columns;
     GtkWidget *content_widget;
+    NautilusDirectory *directory = NULL;
+    NautilusQuery *query = NULL;
+    NautilusQuerySearchContent content;
 
     content_widget = nautilus_files_view_get_content_widget (NAUTILUS_FILES_VIEW (view));
     view->details->tree_view = GTK_TREE_VIEW (gtk_tree_view_new ());
@@ -1953,11 +2000,28 @@ create_and_set_up_tree_view (NautilusListView *view)
             view->details->file_name_cell = (GtkCellRendererText *) cell;
             g_object_set (cell,
                           "ellipsize", PANGO_ELLIPSIZE_END,
-                          "single-paragraph-mode", TRUE,
+                          "single-paragraph-mode", FALSE,
                           "width-chars", 30,
                           "xpad", 5,
                           NULL);
 
+            directory = nautilus_files_view_get_model (NAUTILUS_FILES_VIEW (view));
+            if (NAUTILUS_IS_SEARCH_DIRECTORY (directory))
+            {
+                query = nautilus_search_directory_get_query (NAUTILUS_SEARCH_DIRECTORY (directory));
+            }
+
+            if (query)
+            {
+                content = nautilus_query_get_search_content (query);
+            }
+
+            if (query && content == NAUTILUS_QUERY_SEARCH_CONTENT_FULL_TEXT)
+            {
+                gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (cell), 2);
+                g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_MIDDLE, NULL);
+            }
+
             gtk_tree_view_column_pack_start (view->details->file_name_column, cell, TRUE);
             gtk_tree_view_column_set_cell_data_func (view->details->file_name_column, cell,
                                                      (GtkTreeCellDataFunc) filename_cell_data_func,
diff --git a/src/nautilus-preferences-window.c b/src/nautilus-preferences-window.c
index c4952e9..680254f 100644
--- a/src/nautilus-preferences-window.c
+++ b/src/nautilus-preferences-window.c
@@ -61,6 +61,8 @@
     "automatic_decompression_checkbutton"
 #define NAUTILUS_PREFERENCES_DIALOG_USE_NEW_VIEWS_WIDGET                    \
     "use_new_views_checkbutton"
+#define NAUTILUS_PREFERENCES_FTS_DEFAULT_WIDGET                                \
+    "fts_checkbutton"
 
 /* int enums */
 #define NAUTILUS_PREFERENCES_DIALOG_THUMBNAIL_LIMIT_WIDGET                     \
@@ -506,6 +508,9 @@ static void nautilus_preferences_window_setup(GtkBuilder *builder,
     bind_builder_bool (builder, nautilus_preferences,
                        NAUTILUS_PREFERENCES_DIALOG_USE_NEW_VIEWS_WIDGET,
                        NAUTILUS_PREFERENCES_USE_EXPERIMENTAL_VIEWS);
+    bind_builder_bool (builder, nautilus_preferences,
+                       NAUTILUS_PREFERENCES_FTS_DEFAULT_WIDGET,
+                       NAUTILUS_PREFERENCES_FTS_DEFAULT);
 
     bind_builder_radio (
         builder, nautilus_preferences, (const char **) click_behavior_components,
diff --git a/src/nautilus-query-editor.c b/src/nautilus-query-editor.c
index 5d9eca9..94b9c4d 100644
--- a/src/nautilus-query-editor.c
+++ b/src/nautilus-query-editor.c
@@ -115,6 +115,7 @@ static void
 update_information_label (NautilusQueryEditor *editor)
 {
     NautilusQueryEditorPrivate *priv;
+    gboolean fts_sensitive = TRUE;
 
     priv = nautilus_query_editor_get_instance_private (editor);
 
@@ -131,6 +132,7 @@ update_information_label (NautilusQueryEditor *editor)
         if (nautilus_file_is_other_locations (file))
         {
             label = _("Searching locations only");
+            fts_sensitive = FALSE;
         }
         else if (g_str_has_prefix (uri, "computer://"))
         {
@@ -139,17 +141,22 @@ update_information_label (NautilusQueryEditor *editor)
         else if (g_str_has_prefix (uri, "network://"))
         {
             label = _("Searching network locations only");
+            fts_sensitive = FALSE;
         }
         else if (nautilus_file_is_remote (file) &&
                  !settings_search_is_recursive (editor))
         {
             label = _("Remote location — only searching the current folder");
+            fts_sensitive = FALSE;
         }
         else if (!settings_search_is_recursive (editor))
         {
             label = _("Only searching the current folder");
         }
 
+        nautilus_search_popover_set_fts_sensitive (NAUTILUS_SEARCH_POPOVER (priv->popover),
+                                                   fts_sensitive);
+
         gtk_widget_set_visible (priv->label, label != NULL);
         gtk_label_set_label (GTK_LABEL (priv->label), label);
 
@@ -376,14 +383,19 @@ create_query (NautilusQueryEditor *editor)
     NautilusQuery *query;
     NautilusFile *file;
     gboolean recursive;
+    gboolean fts_enabled;
 
     priv = nautilus_query_editor_get_instance_private (editor);
 
     g_return_if_fail (!priv->query);
 
+    fts_enabled = nautilus_search_popover_get_fts_enabled (NAUTILUS_SEARCH_POPOVER (priv->popover));
+
     file = nautilus_file_get (priv->location);
     query = nautilus_query_new ();
 
+    nautilus_query_set_search_content (query, fts_enabled);
+
     recursive = settings_search_is_recursive (editor);
 
     nautilus_query_set_text (query, gtk_entry_get_text (GTK_ENTRY (priv->entry)));
@@ -571,6 +583,29 @@ search_popover_time_type_changed_cb (NautilusSearchPopover   *popover,
 }
 
 static void
+search_popover_fts_changed_cb (GObject                    *popover,
+                               GParamSpec                 *pspec,
+                               gpointer                    user_data)
+{
+    NautilusQueryEditorPrivate *priv;
+    NautilusQueryEditor *editor;
+
+    editor = user_data;
+
+    priv = nautilus_query_editor_get_instance_private (NAUTILUS_QUERY_EDITOR (editor));
+
+    if (!priv->query)
+    {
+        create_query (editor);
+    }
+
+    nautilus_query_set_search_content (priv->query,
+                                       nautilus_search_popover_get_fts_enabled (NAUTILUS_SEARCH_POPOVER 
(popover)));
+
+    nautilus_query_editor_changed (editor);
+}
+
+static void
 entry_tag_clicked (NautilusQueryEditor *editor)
 {
     NautilusQueryEditorPrivate *priv;
@@ -672,6 +707,8 @@ setup_widgets (NautilusQueryEditor *editor)
                       G_CALLBACK (search_popover_mime_type_changed_cb), editor);
     g_signal_connect (priv->popover, "time-type",
                       G_CALLBACK (search_popover_time_type_changed_cb), editor);
+    g_signal_connect (priv->popover, "notify::fts-enabled",
+                      G_CALLBACK (search_popover_fts_changed_cb), editor);
 
     /* show everything */
     gtk_widget_show_all (vbox);
diff --git a/src/nautilus-search-directory.c b/src/nautilus-search-directory.c
index 959193b..d51f4f8 100644
--- a/src/nautilus-search-directory.c
+++ b/src/nautilus-search-directory.c
@@ -628,6 +628,7 @@ search_engine_hits_added (NautilusSearchEngine    *engine,
 
         file = nautilus_file_get_by_uri (uri);
         nautilus_file_set_search_relevance (file, nautilus_search_hit_get_relevance (hit));
+        nautilus_file_set_search_fts_snippet (file, nautilus_search_hit_get_fts_snippet (hit));
 
         for (monitor_list = search->details->monitor_list; monitor_list; monitor_list = monitor_list->next)
         {
diff --git a/src/nautilus-search-engine-tracker.c b/src/nautilus-search-engine-tracker.c
index 38126bb..b868dbf 100644
--- a/src/nautilus-search-engine-tracker.c
+++ b/src/nautilus-search-engine-tracker.c
@@ -41,6 +41,7 @@ struct NautilusSearchEngineTrackerDetails
     GQueue *hits_pending;
 
     gboolean recursive;
+    gboolean fts_enabled;
 
     GCancellable *cancellable;
 };
@@ -174,6 +175,7 @@ cursor_callback (GObject      *object,
     const char *uri;
     const char *mtime_str;
     const char *atime_str;
+    const gchar *snippet;
     GTimeVal tv;
     gdouble rank, match;
     gboolean success;
@@ -206,6 +208,12 @@ cursor_callback (GObject      *object,
     nautilus_search_hit_set_fts_rank (hit, rank + match);
     g_free (basename);
 
+    if (tracker->details->fts_enabled)
+    {
+        snippet = tracker_sparql_cursor_get_string (cursor, 4, NULL);
+        nautilus_search_hit_set_fts_snippet (hit, snippet);
+    }
+
     if (g_time_val_from_iso8601 (mtime_str, &tv))
     {
         GDateTime *date;
@@ -311,6 +319,8 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
                 g_settings_get_enum (nautilus_preferences, "recursive-search") == 
NAUTILUS_SPEED_TRADEOFF_ALWAYS;
     tracker->details->recursive = recursive;
 
+    tracker->details->fts_enabled = nautilus_query_get_search_content (tracker->details->query);
+
     query_text = nautilus_query_get_text (tracker->details->query);
     downcase = g_utf8_strdown (query_text, -1);
     search_text = tracker_sparql_escape_string (downcase);
@@ -322,13 +332,19 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
     mimetypes = nautilus_query_get_mime_types (tracker->details->query);
     mime_count = g_list_length (mimetypes);
 
-    sparql = g_string_new ("SELECT DISTINCT nie:url(?urn) fts:rank(?urn) nfo:fileLastModified(?urn) 
nfo:fileLastAccessed(?urn)\n"
-                           "WHERE {"
-                           "  ?urn a nfo:FileDataObject;"
-                           "  nfo:fileLastModified ?mtime;"
-                           "  nfo:fileLastAccessed ?atime;"
-                           "  tracker:available true;"
-                           "  nie:url ?url");
+    sparql = g_string_new ("SELECT DISTINCT nie:url(?urn) fts:rank(?urn) nfo:fileLastModified(?urn) 
nfo:fileLastAccessed(?urn)");
+
+    if (tracker->details->fts_enabled)
+    {
+        g_string_append (sparql, " fts:snippet(?urn)");
+    }
+
+    g_string_append (sparql, "\nWHERE {"
+                             "  ?urn a nfo:FileDataObject;"
+                             "  nfo:fileLastModified ?mtime;"
+                             "  nfo:fileLastAccessed ?atime;"
+                             "  tracker:available true;"
+                             "  nie:url ?url");
 
     if (*search_text)
     {
@@ -344,14 +360,17 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
 
     if (!tracker->details->recursive)
     {
-        g_string_append_printf (sparql, "tracker:uri-is-parent('%s', ?url) && ", location_uri);
+        g_string_append_printf (sparql, "tracker:uri-is-parent('%s', ?url)", location_uri);
     }
     else
     {
-        g_string_append_printf (sparql, "tracker:uri-is-descendant('%s', ?url) && ", location_uri);
+        g_string_append_printf (sparql, "tracker:uri-is-descendant('%s', ?url)", location_uri);
     }
 
-    g_string_append_printf (sparql, "fn:contains(fn:lower-case(nfo:fileName(?urn)), '%s')", search_text);
+    if (!tracker->details->fts_enabled)
+    {
+            g_string_append_printf (sparql, " && fn:contains(fn:lower-case(nfo:fileName(?urn)), '%s')", 
search_text);
+    }
 
     date_range = nautilus_query_get_date_range (tracker->details->query);
     if (date_range)
diff --git a/src/nautilus-search-hit.c b/src/nautilus-search-hit.c
index 6ae9ae9..4eb2e39 100644
--- a/src/nautilus-search-hit.c
+++ b/src/nautilus-search-hit.c
@@ -36,6 +36,7 @@ struct _NautilusSearchHit
     GDateTime *modification_time;
     GDateTime *access_time;
     gdouble fts_rank;
+    gchar *fts_snippet;
 
     gdouble relevance;
 };
@@ -47,6 +48,7 @@ enum
     PROP_MODIFICATION_TIME,
     PROP_ACCESS_TIME,
     PROP_FTS_RANK,
+    PROP_FTS_SNIPPET,
     NUM_PROPERTIES
 };
 
@@ -158,6 +160,12 @@ nautilus_search_hit_get_relevance (NautilusSearchHit *hit)
     return hit->relevance;
 }
 
+const gchar *
+nautilus_search_hit_get_fts_snippet (NautilusSearchHit *hit)
+{
+    return hit->fts_snippet;
+}
+
 static void
 nautilus_search_hit_set_uri (NautilusSearchHit *hit,
                              const char        *uri)
@@ -209,6 +217,15 @@ nautilus_search_hit_set_access_time (NautilusSearchHit *hit,
     }
 }
 
+void
+nautilus_search_hit_set_fts_snippet (NautilusSearchHit *hit,
+                                     const gchar       *snippet)
+{
+    g_free (hit->fts_snippet);
+
+    hit->fts_snippet = g_strdup (snippet);
+}
+
 static void
 nautilus_search_hit_set_property (GObject      *object,
                                   guint         arg_id,
@@ -251,6 +268,13 @@ nautilus_search_hit_set_property (GObject      *object,
         }
         break;
 
+        case PROP_FTS_SNIPPET:
+        {
+            g_free (hit->fts_snippet);
+            hit->fts_snippet = g_strdup (g_value_get_string (value));
+        }
+        break;
+
         default:
         {
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, arg_id, pspec);
@@ -301,6 +325,12 @@ nautilus_search_hit_get_property (GObject    *object,
         }
         break;
 
+        case PROP_FTS_SNIPPET:
+        {
+            g_value_set_string (value, hit->fts_snippet);
+        }
+        break;
+
         default:
         {
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, arg_id, pspec);
@@ -325,6 +355,8 @@ nautilus_search_hit_finalize (GObject *object)
         g_date_time_unref (hit->modification_time);
     }
 
+    g_free (hit->fts_snippet);
+
     G_OBJECT_CLASS (nautilus_search_hit_parent_class)->finalize (object);
 }
 
@@ -376,6 +408,13 @@ nautilus_search_hit_class_init (NautilusSearchHitClass *class)
                                                           -G_MAXDOUBLE, G_MAXDOUBLE,
                                                           0,
                                                           G_PARAM_READWRITE));
+    g_object_class_install_property (object_class,
+                                     PROP_FTS_SNIPPET,
+                                     g_param_spec_string ("fts-snippet",
+                                                          "fts-snippet",
+                                                          "fts-snippet",
+                                                          NULL,
+                                                          G_PARAM_READWRITE));
 }
 
 static void
diff --git a/src/nautilus-search-hit.h b/src/nautilus-search-hit.h
index 100c7da..1aecf77 100644
--- a/src/nautilus-search-hit.h
+++ b/src/nautilus-search-hit.h
@@ -37,12 +37,14 @@ void                nautilus_search_hit_set_modification_time (NautilusSearchHit
                                                               GDateTime         *date);
 void                nautilus_search_hit_set_access_time       (NautilusSearchHit *hit,
                                                               GDateTime         *date);
-
+void                nautilus_search_hit_set_fts_snippet       (NautilusSearchHit *hit,
+                                                               const gchar       *snippet);
 void                nautilus_search_hit_compute_scores        (NautilusSearchHit *hit,
                                                               NautilusQuery     *query);
 
 const char *        nautilus_search_hit_get_uri               (NautilusSearchHit *hit);
 gdouble             nautilus_search_hit_get_relevance         (NautilusSearchHit *hit);
+const gchar *       nautilus_search_hit_get_fts_snippet       (NautilusSearchHit *hit);
 
 G_END_DECLS
 
diff --git a/src/nautilus-search-popover.c b/src/nautilus-search-popover.c
index db95a2b..7f8136a 100644
--- a/src/nautilus-search-popover.c
+++ b/src/nautilus-search-popover.c
@@ -45,8 +45,12 @@ struct _NautilusSearchPopover
     GtkWidget *type_stack;
     GtkWidget *last_used_button;
     GtkWidget *last_modified_button;
+    GtkWidget *full_text_search_button;
+    GtkWidget *filename_search_button;
 
     NautilusQuery *query;
+
+    gboolean fts_enabled;
 };
 
 static void          show_date_selection_widgets (NautilusSearchPopover *popover,
@@ -63,6 +67,7 @@ enum
 {
     PROP_0,
     PROP_QUERY,
+    PROP_FTS_ENABLED,
     LAST_PROP
 };
 
@@ -346,6 +351,24 @@ search_time_type_changed (GtkToggleButton       *button,
     g_signal_emit_by_name (popover, "time-type", type, NULL);
 }
 
+static void
+search_fts_mode_changed (GtkToggleButton       *button,
+                         NautilusSearchPopover *popover)
+{
+    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (popover->full_text_search_button)) &&
+        popover->fts_enabled == FALSE)
+    {
+        popover->fts_enabled = TRUE;
+        g_object_notify (G_OBJECT (popover), "fts-enabled");
+    }
+    else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (popover->filename_search_button)) &&
+             popover->fts_enabled == TRUE)
+    {
+        popover->fts_enabled = FALSE;
+        g_object_notify (G_OBJECT (popover), "fts-enabled");
+    }
+}
+
 /* Auxiliary methods */
 
 static GtkWidget *
@@ -639,6 +662,14 @@ update_date_label (NautilusSearchPopover *popover,
     }
 }
 
+void
+nautilus_search_popover_set_fts_sensitive (NautilusSearchPopover *popover,
+                                           gboolean               sensitive)
+{
+    gtk_widget_set_sensitive (popover->full_text_search_button, sensitive);
+    gtk_widget_set_sensitive (popover->filename_search_button, sensitive);
+}
+
 static void
 nautilus_search_popover_closed (GtkPopover *popover)
 {
@@ -690,6 +721,12 @@ nautilus_search_popover_get_property (GObject    *object,
         }
         break;
 
+        case PROP_FTS_ENABLED:
+        {
+            g_value_set_boolean (value, self->fts_enabled);
+        }
+        break;
+
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -713,6 +750,12 @@ nautilus_search_popover_set_property (GObject      *object,
         }
         break;
 
+        case PROP_FTS_ENABLED:
+        {
+            self->fts_enabled = g_value_get_boolean (value);
+        }
+        break;
+
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -778,6 +821,14 @@ nautilus_search_popover_class_init (NautilusSearchPopoverClass *klass)
                                                           NAUTILUS_TYPE_QUERY,
                                                           G_PARAM_READWRITE));
 
+    g_object_class_install_property (object_class,
+                                     PROP_FTS_ENABLED,
+                                     g_param_spec_boolean ("fts-enabled",
+                                                           "fts enabled",
+                                                           "fts enabled",
+                                                           FALSE,
+                                                           G_PARAM_READWRITE));
+
     gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/nautilus/ui/nautilus-search-popover.ui");
 
     gtk_widget_class_bind_template_child (widget_class, NautilusSearchPopover, around_revealer);
@@ -794,6 +845,8 @@ nautilus_search_popover_class_init (NautilusSearchPopoverClass *klass)
     gtk_widget_class_bind_template_child (widget_class, NautilusSearchPopover, type_stack);
     gtk_widget_class_bind_template_child (widget_class, NautilusSearchPopover, last_used_button);
     gtk_widget_class_bind_template_child (widget_class, NautilusSearchPopover, last_modified_button);
+    gtk_widget_class_bind_template_child (widget_class, NautilusSearchPopover, full_text_search_button);
+    gtk_widget_class_bind_template_child (widget_class, NautilusSearchPopover, filename_search_button);
 
     gtk_widget_class_bind_template_callback (widget_class, calendar_day_selected);
     gtk_widget_class_bind_template_callback (widget_class, clear_date_button_clicked);
@@ -804,6 +857,7 @@ nautilus_search_popover_class_init (NautilusSearchPopoverClass *klass)
     gtk_widget_class_bind_template_callback (widget_class, toggle_calendar_icon_clicked);
     gtk_widget_class_bind_template_callback (widget_class, types_listbox_row_activated);
     gtk_widget_class_bind_template_callback (widget_class, search_time_type_changed);
+    gtk_widget_class_bind_template_callback (widget_class, search_fts_mode_changed);
 }
 
 static void
@@ -840,6 +894,16 @@ nautilus_search_popover_init (NautilusSearchPopover *self)
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->last_modified_button), FALSE);
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->last_used_button), TRUE);
     }
+
+    self->fts_enabled = g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_FTS_DEFAULT);
+    if (self->fts_enabled)
+    {
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->full_text_search_button), TRUE);
+    }
+    else
+    {
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->filename_search_button), TRUE);
+    }
 }
 
 GtkWidget *
@@ -937,3 +1001,9 @@ nautilus_search_popover_reset_date_range (NautilusSearchPopover *popover)
     show_date_selection_widgets (popover, FALSE);
     g_signal_emit_by_name (popover, "date-range", NULL);
 }
+
+gboolean
+nautilus_search_popover_get_fts_enabled (NautilusSearchPopover *popover)
+{
+    return popover->fts_enabled;
+}
diff --git a/src/nautilus-search-popover.h b/src/nautilus-search-popover.h
index 1d872f1..91845cd 100644
--- a/src/nautilus-search-popover.h
+++ b/src/nautilus-search-popover.h
@@ -46,6 +46,10 @@ void                 nautilus_search_popover_set_query           (NautilusSearch
 void                 nautilus_search_popover_reset_date_range    (NautilusSearchPopover *popover);
 void                 nautilus_search_popover_reset_mime_types    (NautilusSearchPopover *popover);
 
+gboolean             nautilus_search_popover_get_fts_enabled     (NautilusSearchPopover *popover);
+void                 nautilus_search_popover_set_fts_sensitive   (NautilusSearchPopover *popover,
+                                                                  gboolean               sensitive);
+
 G_END_DECLS
 
 #endif /* NAUTILUS_SEARCH_POPOVER_H */
diff --git a/src/resources/ui/nautilus-preferences-window.ui b/src/resources/ui/nautilus-preferences-window.ui
index a8f15bc..fcbffe0 100644
--- a/src/resources/ui/nautilus-preferences-window.ui
+++ b/src/resources/ui/nautilus-preferences-window.ui
@@ -1028,6 +1028,36 @@
                         <property name="position">4</property>
                       </packing>
                     </child>
+                    <child>
+                      <object class="GtkLabel" id="fts_label">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Full Text Search:</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">5</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="fts_checkbutton">
+                        <property name="label" translatable="yes">Set as _default</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="xalign">0</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">6</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
diff --git a/src/resources/ui/nautilus-search-popover.ui b/src/resources/ui/nautilus-search-popover.ui
index 72fd99d..82a948a 100644
--- a/src/resources/ui/nautilus-search-popover.ui
+++ b/src/resources/ui/nautilus-search-popover.ui
@@ -354,6 +354,7 @@
           <object class="GtkBox">
             <property name="can_focus">False</property>
             <property name="hexpand">True</property>
+            <property name="visible">True</property>
             <child>
               <object class="GtkRadioButton" id="full_text_search_button">
                 <property name="label" translatable="yes">Full Text</property>
@@ -365,6 +366,7 @@
                 <property name="xalign">0</property>
                 <property name="active">True</property>
                 <property name="draw_indicator">False</property>
+                <signal name="toggled" handler="search_fts_mode_changed" object="NautilusSearchPopover" 
swapped="no" />
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -383,6 +385,8 @@
                 <property name="xalign">0</property>
                 <property name="draw_indicator">False</property>
                 <property name="group">full_text_search_button</property>
+                <property name="active">True</property>
+                <signal name="toggled" handler="search_fts_mode_changed" object="NautilusSearchPopover" 
swapped="no" />
               </object>
               <packing>
                 <property name="expand">False</property>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]