[nautilus/wip/gbsneto/search-popover: 3/7] query-editor: make it a GtkSearchBar subclass



commit a0ea25b41bcd37e6129ea6c23cff11d1d2ac2cf4
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Mon Oct 5 21:14:59 2015 -0300

    query-editor: make it a GtkSearchBar subclass
    
    The new query editor, as shown in the mockups, is
    actually an enhanced GtkSearchBar, since this widget
    was crafted for this exact use case.
    
    Make the current query editor a GtkSearchBar subclass
    and adapt the code to follow it.

 src/nautilus-query-editor.c | 1182 +++++++++++--------------------------------
 src/nautilus-query-editor.h |   26 +-
 src/nautilus-window-slot.c  |   31 +-
 3 files changed, 303 insertions(+), 936 deletions(-)
---
diff --git a/src/nautilus-query-editor.c b/src/nautilus-query-editor.c
index 7ac85e0..b0750e8 100644
--- a/src/nautilus-query-editor.c
+++ b/src/nautilus-query-editor.c
@@ -1,4 +1,4 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* -*- Mode: C; indent-tabs-mode: s; c-basic-offset: 8; tab-width: 8 -*- */
 /*
  * Copyright (C) 2005 Red Hat, Inc.
  *
@@ -17,11 +17,13 @@
  * see <http://www.gnu.org/licenses/>.
  *
  * Author: Alexander Larsson <alexl redhat com>
+ *         Georges Basile Stavracas Neto <gbsneto gnome org>
  *
  */
 
 #include <config.h>
 #include "nautilus-query-editor.h"
+#include "nautilus-search-popover.h"
 
 #include <string.h>
 #include <glib/gi18n.h>
@@ -32,169 +34,117 @@
 #include <eel/eel-glib-extensions.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
 
-typedef enum {
-       NAUTILUS_QUERY_EDITOR_ROW_TYPE,
-       
-       NAUTILUS_QUERY_EDITOR_ROW_LAST
-} NautilusQueryEditorRowType;
-
-typedef struct {
-       NautilusQueryEditorRowType type;
-       NautilusQueryEditor *editor;
-       GtkWidget *toolbar;
-       GtkWidget *hbox;
-       GtkWidget *combo;
-
-       GtkWidget *type_widget;
-} NautilusQueryEditorRow;
-
-
 typedef struct {
-       const char *name;
-       GtkWidget * (*create_widgets)      (NautilusQueryEditorRow *row);
-       void        (*add_to_query)        (NautilusQueryEditorRow *row,
-                                           NautilusQuery          *query);
-       void        (*add_rows_from_query) (NautilusQueryEditor *editor,
-                                           NautilusQuery *query);
-} NautilusQueryEditorRowOps;
-
-struct NautilusQueryEditorDetails {
        GtkWidget *entry;
+        GtkWidget *popover;
+        GtkWidget *label;
+        GtkWidget *spinner;
        gboolean change_frozen;
 
-       GtkWidget *search_current_button;
-       GtkWidget *search_all_button;
-        GFile *current_location;
+        GBinding *spinner_active_binding;
 
-       GList *rows;
+       GFile *location;
 
        NautilusQuery *query;
-};
+} NautilusQueryEditorPrivate;
 
 enum {
        ACTIVATED,
        CHANGED,
        CANCEL,
        LAST_SIGNAL
-}; 
+};
+
+enum {
+        PROP_0,
+        PROP_LOCATION,
+        PROP_QUERY,
+        LAST_PROP
+};
 
 static guint signals[LAST_SIGNAL];
 
 static void entry_activate_cb (GtkWidget *entry, NautilusQueryEditor *editor);
 static void entry_changed_cb  (GtkWidget *entry, NautilusQueryEditor *editor);
-static void nautilus_query_editor_changed_force (NautilusQueryEditor *editor,
-                                                gboolean             force);
 static void nautilus_query_editor_changed (NautilusQueryEditor *editor);
-static NautilusQueryEditorRow * nautilus_query_editor_add_row (NautilusQueryEditor *editor,
-                                                              NautilusQueryEditorRowType type);
-
-static GtkWidget *type_row_create_widgets      (NautilusQueryEditorRow *row);
-static void       type_row_add_to_query        (NautilusQueryEditorRow *row,
-                                               NautilusQuery          *query);
-static void       type_add_rows_from_query     (NautilusQueryEditor    *editor,
-                                               NautilusQuery          *query);
-
-
-
-static NautilusQueryEditorRowOps row_type[] = {
-       { N_("File Type"),
-         type_row_create_widgets,
-         type_row_add_to_query,
-         type_add_rows_from_query
-       },
-};
 
-G_DEFINE_TYPE (NautilusQueryEditor, nautilus_query_editor, GTK_TYPE_BOX);
+G_DEFINE_TYPE_WITH_PRIVATE (NautilusQueryEditor, nautilus_query_editor, GTK_TYPE_SEARCH_BAR);
 
-gboolean
-nautilus_query_editor_handle_event (NautilusQueryEditor *editor,
-                                   GdkEventKey         *event)
+static void
+nautilus_query_editor_dispose (GObject *object)
 {
-       GtkWidget *toplevel;
-       GtkWidget *old_focus;
-       GdkEvent *new_event;
-       gboolean retval;
-
-       /* if we're focused already, no need to handle the event manually */
-       if (gtk_widget_has_focus (editor->details->entry)) {
-               return FALSE;
-       }
-
-       /* never handle these events */
-       if (event->keyval == GDK_KEY_slash || event->keyval == GDK_KEY_Delete) {
-               return FALSE;
-       }
-
-       /* don't activate search for these events */
-       if (!gtk_widget_get_visible (GTK_WIDGET (editor)) && event->keyval == GDK_KEY_space) {
-               return FALSE;
-       }
+       NautilusQueryEditorPrivate *priv;
 
-       /* if it's not printable we don't need it */
-       if (!g_unichar_isprint (gdk_keyval_to_unicode (event->keyval))) {
-               return FALSE;
-       }
-
-       if (!gtk_widget_get_realized (editor->details->entry)) {
-               gtk_widget_realize (editor->details->entry);
-       }
+        priv = nautilus_query_editor_get_instance_private (NAUTILUS_QUERY_EDITOR (object));
 
-       toplevel = gtk_widget_get_toplevel (GTK_WIDGET (editor));
-       if (gtk_widget_is_toplevel (toplevel)) {
-               old_focus = gtk_window_get_focus (GTK_WINDOW (toplevel));
-       } else {
-               old_focus = NULL;
-       }
+        g_clear_object (&priv->location);
+        g_clear_object (&priv->query);
 
-       /* input methods will typically only process events after getting focus */
-       gtk_widget_grab_focus (editor->details->entry);
-
-       new_event = gdk_event_copy ((GdkEvent *) event);
-       g_object_unref (((GdkEventKey *) new_event)->window);
-       ((GdkEventKey *) new_event)->window = g_object_ref
-               (gtk_widget_get_window (editor->details->entry));
-       retval = gtk_widget_event (editor->details->entry, new_event);
-       gdk_event_free (new_event);
-
-       if (!retval && old_focus) {
-               gtk_widget_grab_focus (old_focus);
-       }
-
-       return retval;
+       G_OBJECT_CLASS (nautilus_query_editor_parent_class)->dispose (object);
 }
 
 static void
-row_destroy (NautilusQueryEditorRow *row)
+nautilus_query_editor_grab_focus (GtkWidget *widget)
 {
-       gtk_widget_destroy (row->toolbar);
-       g_free (row);
+       NautilusQueryEditorPrivate *priv;
+
+        priv = nautilus_query_editor_get_instance_private (NAUTILUS_QUERY_EDITOR (widget));
+
+       if (gtk_widget_get_visible (widget) && !gtk_widget_is_focus (priv->entry)) {
+               /* avoid selecting the entry text */
+               gtk_widget_grab_focus (priv->entry);
+               gtk_editable_set_position (GTK_EDITABLE (priv->entry), -1);
+       }
 }
 
 static void
-nautilus_query_editor_dispose (GObject *object)
+nautilus_query_editor_get_property (GObject    *object,
+                                    guint       prop_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
 {
-       NautilusQueryEditor *editor;
+        NautilusQueryEditorPrivate *priv;
 
-       editor = NAUTILUS_QUERY_EDITOR (object);
+        priv = nautilus_query_editor_get_instance_private (NAUTILUS_QUERY_EDITOR (object));
 
-       g_clear_object (&editor->details->query);
+        switch (prop_id)
+        {
+        case PROP_LOCATION:
+                g_value_set_object (value, priv->location);
+                break;
 
-       g_list_free_full (editor->details->rows, (GDestroyNotify) row_destroy);
-       editor->details->rows = NULL;
+        case PROP_QUERY:
+                g_value_set_object (value, priv->query);
+                break;
 
-       G_OBJECT_CLASS (nautilus_query_editor_parent_class)->dispose (object);
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        }
 }
 
 static void
-nautilus_query_editor_grab_focus (GtkWidget *widget)
+nautilus_query_editor_set_property (GObject      *object,
+                                    guint         prop_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
 {
-       NautilusQueryEditor *editor = NAUTILUS_QUERY_EDITOR (widget);
+        NautilusQueryEditor *self;
 
-       if (gtk_widget_get_visible (widget) && !gtk_widget_is_focus (editor->details->entry)) {
-               /* avoid selecting the entry text */
-               gtk_widget_grab_focus (editor->details->entry);
-               gtk_editable_set_position (GTK_EDITABLE (editor->details->entry), -1);
-       }
+        self = NAUTILUS_QUERY_EDITOR (object);
+
+        switch (prop_id)
+        {
+        case PROP_LOCATION:
+                nautilus_query_editor_set_location (self, g_value_get_object (value));
+                break;
+
+        case PROP_QUERY:
+                nautilus_query_editor_set_query (self, g_value_get_object (value));
+                break;
+
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        }
 }
 
 static void
@@ -205,6 +155,8 @@ nautilus_query_editor_class_init (NautilusQueryEditorClass *class)
 
        gobject_class = G_OBJECT_CLASS (class);
         gobject_class->dispose = nautilus_query_editor_dispose;
+        gobject_class->get_property = nautilus_query_editor_get_property;
+        gobject_class->set_property = nautilus_query_editor_set_property;
 
        widget_class = GTK_WIDGET_CLASS (class);
        widget_class->grab_focus = nautilus_query_editor_grab_focus;
@@ -236,815 +188,259 @@ nautilus_query_editor_class_init (NautilusQueryEditorClass *class)
                              g_cclosure_marshal_VOID__VOID,
                              G_TYPE_NONE, 0);
 
-       g_type_class_add_private (class, sizeof (NautilusQueryEditorDetails));
+        /**
+         * NautilusQueryEditor::location:
+         *
+         * The current location of the query editor.
+         */
+        g_object_class_install_property (gobject_class,
+                                         PROP_LOCATION,
+                                         g_param_spec_object ("location",
+                                                              "Location of the search",
+                                                              "The current location of the editor",
+                                                              G_TYPE_FILE,
+                                                              G_PARAM_READWRITE));
+
+        /**
+         * NautilusQueryEditor::query:
+         *
+         * The current query of the query editor. It it always synchronized
+         * with the filter popover's query.
+         */
+        g_object_class_install_property (gobject_class,
+                                         PROP_QUERY,
+                                         g_param_spec_object ("query",
+                                                              "Query of the search",
+                                                              "The query that the editor is handling",
+                                                              NAUTILUS_TYPE_QUERY,
+                                                              G_PARAM_READWRITE));
 }
 
 GFile *
 nautilus_query_editor_get_location (NautilusQueryEditor *editor)
 {
-       GFile *file = NULL;
-        if (editor->details->current_location != NULL)
-                file = g_object_ref (editor->details->current_location);
-       return file;
-}
-
-static void
-entry_activate_cb (GtkWidget *entry, NautilusQueryEditor *editor)
-{
-       g_signal_emit (editor, signals[ACTIVATED], 0);
-}
+        NautilusQueryEditorPrivate *priv;
 
-static void
-entry_changed_cb (GtkWidget *entry, NautilusQueryEditor *editor)
-{
-       if (editor->details->change_frozen) {
-               return;
-       }
+       g_return_val_if_fail (NAUTILUS_IS_QUERY_EDITOR (editor), NULL);
 
-       nautilus_query_editor_changed (editor);
-}
+        priv = nautilus_query_editor_get_instance_private (editor);
 
-static void
-nautilus_query_editor_on_stop_search (GtkWidget           *entry,
-                                      NautilusQueryEditor *editor)
-{
-       g_signal_emit (editor, signals[CANCEL], 0);
+        return g_object_ref (priv->location);
 }
 
-/* Type */
-
-static gboolean
-type_separator_func (GtkTreeModel      *model,
-                    GtkTreeIter       *iter,
-                    gpointer           data)
+static NautilusQuery*
+create_and_get_query (NautilusQueryEditor *editor)
 {
-       char *text;
-       gboolean res;
-       
-       gtk_tree_model_get (model, iter, 0, &text, -1);
+        NautilusQueryEditorPrivate *priv;
 
-       res = text != NULL && strcmp (text, "---") == 0;
-       
-       g_free (text);
-       return res;
-}
+        priv = nautilus_query_editor_get_instance_private (editor);
 
-struct {
-       char *name;
-       char *mimetypes[20];
-} mime_type_groups[] = {
-       { N_("Documents"),
-         { "application/rtf",
-           "application/msword",
-           "application/vnd.sun.xml.writer",
-           "application/vnd.sun.xml.writer.global",
-           "application/vnd.sun.xml.writer.template",
-           "application/vnd.oasis.opendocument.text",
-           "application/vnd.oasis.opendocument.text-template",
-           "application/x-abiword",
-           "application/x-applix-word",
-           "application/x-mswrite",
-           "application/docbook+xml",
-           "application/x-kword",
-           "application/x-kword-crypt",
-           "application/x-lyx",
-           NULL
-         }
-       },
-       { N_("Music"),
-         { "application/ogg",
-           "audio/x-vorbis+ogg",
-           "audio/ac3",
-           "audio/basic",
-           "audio/midi",
-           "audio/x-flac",
-           "audio/mp4",
-           "audio/mpeg",
-           "audio/x-mpeg",
-           "audio/x-ms-asx",
-           "audio/x-pn-realaudio",
-           NULL
-         }
-       },
-       { N_("Video"),
-         { "video/mp4",
-           "video/3gpp",
-           "video/mpeg",
-           "video/quicktime",
-           "video/vivo",
-           "video/x-avi",
-           "video/x-mng",
-           "video/x-ms-asf",
-           "video/x-ms-wmv",
-           "video/x-msvideo",
-           "video/x-nsv",
-           "video/x-real-video",
-           NULL
-         }
-       },
-       { N_("Picture"),
-         { "application/vnd.oasis.opendocument.image",
-           "application/x-krita",
-           "image/bmp",
-           "image/cgm",
-           "image/gif",
-           "image/jpeg",
-           "image/jpeg2000",
-           "image/png",
-           "image/svg+xml",
-           "image/tiff",
-           "image/x-compressed-xcf",
-           "image/x-pcx",
-           "image/x-photo-cd",
-           "image/x-psd",
-           "image/x-tga",
-           "image/x-xcf",
-           NULL
-         }
-       },
-       { N_("Illustration"),
-         { "application/illustrator",
-           "application/vnd.corel-draw",
-           "application/vnd.stardivision.draw",
-           "application/vnd.oasis.opendocument.graphics",
-           "application/x-dia-diagram",
-           "application/x-karbon",
-           "application/x-killustrator",
-           "application/x-kivio",
-           "application/x-kontour",
-           "application/x-wpg",
-           NULL
-         }
-       },
-       { N_("Spreadsheet"),
-         { "application/vnd.lotus-1-2-3",
-           "application/vnd.ms-excel",
-           "application/vnd.stardivision.calc",
-           "application/vnd.sun.xml.calc",
-           "application/vnd.oasis.opendocument.spreadsheet",
-           "application/x-applix-spreadsheet",
-           "application/x-gnumeric",
-           "application/x-kspread",
-           "application/x-kspread-crypt",
-           "application/x-quattropro",
-           "application/x-sc",
-           "application/x-siag",
-           NULL
-         }
-       },
-       { N_("Presentation"),
-         { "application/vnd.ms-powerpoint",
-           "application/vnd.sun.xml.impress",
-           "application/vnd.oasis.opendocument.presentation",
-           "application/x-magicpoint",
-           "application/x-kpresenter",
-           NULL
-         }
-       },
-       { N_("PDF / PostScript"),
-         { "application/pdf",
-           "application/postscript",
-           "application/x-dvi",
-           "image/x-eps",
-           NULL
-         }
-       },
-       { N_("Text File"),
-         { "text/plain",
-           NULL
-         }
-       }
-};
+        if (!priv->query) {
+                NautilusQuery *query;
 
-static void
-type_add_custom_type (NautilusQueryEditorRow *row,
-                     const char *mime_type,
-                     const char *description,
-                     GtkTreeIter *iter)
-{
-       GtkTreeModel *model;
-       GtkListStore *store;
-       
-       model = gtk_combo_box_get_model (GTK_COMBO_BOX (row->type_widget));
-       store = GTK_LIST_STORE (model);
-
-       gtk_list_store_append (store, iter);
-       gtk_list_store_set (store, iter,
-                           0, description,
-                           2, mime_type,
-                           -1);
-}
-
-
-static void
-type_combo_changed (GtkComboBox *combo_box, NautilusQueryEditorRow *row)
-{
-       GtkTreeIter iter;
-       gboolean other;
-       GtkTreeModel *model;
+                query = nautilus_query_new ();
 
-       if (!gtk_combo_box_get_active_iter  (GTK_COMBO_BOX (row->type_widget),
-                                            &iter)) {
-               return;
-       }
+                nautilus_query_set_text (query, gtk_entry_get_text (GTK_ENTRY (priv->entry)));
+                nautilus_query_set_location (query, priv->location);
 
-       model = gtk_combo_box_get_model (GTK_COMBO_BOX (row->type_widget));
-       gtk_tree_model_get (model, &iter, 3, &other, -1);
-
-       if (other) {
-               GList *mime_infos, *l;
-               GtkWidget *dialog;
-               GtkWidget *scrolled, *treeview;
-               GtkListStore *store;
-               GtkTreeViewColumn *column;
-               GtkCellRenderer *renderer;
-               GtkWidget *toplevel;
-               GtkTreeSelection *selection;
-
-               mime_infos = g_content_types_get_registered ();
-
-               store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
-               for (l = mime_infos; l != NULL; l = l->next) {
-                       GtkTreeIter iter;
-                       char *mime_type = l->data;
-                       char *description;
-
-                       description = g_content_type_get_description (mime_type);
-                       if (description == NULL) {
-                               description = g_strdup (mime_type);
-                       }
-                       
-                       gtk_list_store_append (store, &iter);
-                       gtk_list_store_set (store, &iter,
-                                           0, description,
-                                           1, mime_type,
-                                           -1);
-                       
-                       g_free (mime_type);
-                       g_free (description);
-               }
-               g_list_free (mime_infos);
-               
-
-               
-               toplevel = gtk_widget_get_toplevel (GTK_WIDGET (combo_box));
-               dialog = gtk_dialog_new_with_buttons (_("Select type"),
-                                                     GTK_WINDOW (toplevel),
-                                                     GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | 
GTK_DIALOG_USE_HEADER_BAR,
-                                                     _("_Cancel"), GTK_RESPONSE_CANCEL,
-                                                     _("Select"), GTK_RESPONSE_OK,
-                                                     NULL);
-               gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 600);
-                       
-               scrolled = gtk_scrolled_window_new (NULL, NULL);
-               gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
-                                               GTK_POLICY_AUTOMATIC,
-                                               GTK_POLICY_AUTOMATIC);
-
-               gtk_widget_show (scrolled);
-               gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG 
(dialog))), 0);
-               gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), scrolled, 
TRUE, TRUE, 0);
-
-               treeview = gtk_tree_view_new ();
-               gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
-                                        GTK_TREE_MODEL (store));
-               gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), 0,
-                                                     GTK_SORT_ASCENDING);
-               
-               selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
-               gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
-
-
-               renderer = gtk_cell_renderer_text_new ();
-               column = gtk_tree_view_column_new_with_attributes ("Name",
-                                                                  renderer,
-                                                                  "text",
-                                                                  0,
-                                                                  NULL);
-               gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
-               gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
-               
-               gtk_widget_show (treeview);
-               gtk_container_add (GTK_CONTAINER (scrolled), treeview);
-
-               if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
-                       char *mimetype, *description;
-
-                       gtk_tree_selection_get_selected (selection, NULL, &iter);
-                       gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
-                                           0, &description,
-                                           1, &mimetype,
-                                           -1);
-
-                       type_add_custom_type (row, mimetype, description, &iter);
-                       gtk_combo_box_set_active_iter  (GTK_COMBO_BOX (row->type_widget),
-                                                       &iter);
-               } else {
-                       gtk_combo_box_set_active (GTK_COMBO_BOX (row->type_widget), 0);
-               }
+                nautilus_query_editor_set_query (editor, query);
+        }
 
-               gtk_widget_destroy (dialog);
-       }
-       
-       nautilus_query_editor_changed (row->editor);
+        return priv->query;
 }
 
-static GtkWidget *
-type_row_create_widgets (NautilusQueryEditorRow *row)
+static void
+entry_activate_cb (GtkWidget *entry, NautilusQueryEditor *editor)
 {
-       GtkWidget *combo;
-       GtkCellRenderer *cell;
-       GtkListStore *store;
-       GtkTreeIter iter;
-       int i;
-
-       store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_BOOLEAN);
-       combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
-       g_object_unref (store);
-       
-       cell = gtk_cell_renderer_text_new ();
-       gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
-       gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
-                                       "text", 0,
-                                       NULL);
-       gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo),
-                                             type_separator_func,
-                                             NULL, NULL);
-
-       gtk_list_store_append (store, &iter);
-       gtk_list_store_set (store, &iter, 0, _("Any"), -1);
-       gtk_list_store_append (store, &iter);
-       gtk_list_store_set (store, &iter, 0, "---",  -1);
-
-       for (i = 0; i < G_N_ELEMENTS (mime_type_groups); i++) {
-               gtk_list_store_append (store, &iter);
-               gtk_list_store_set (store, &iter,
-                                   0, gettext (mime_type_groups[i].name),
-                                   1, mime_type_groups[i].mimetypes,
-                                   -1);
-       }
-
-       gtk_list_store_append (store, &iter);
-       gtk_list_store_set (store, &iter, 0, "---",  -1);
-       gtk_list_store_append (store, &iter);
-       gtk_list_store_set (store, &iter, 0, _("Other Type…"), 3, TRUE, -1);
-
-       gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
-       
-       g_signal_connect (combo, "changed",
-                         G_CALLBACK (type_combo_changed),
-                         row);
-
-       gtk_widget_show (combo);
-       
-       gtk_box_pack_start (GTK_BOX (row->hbox), combo, FALSE, FALSE, 0);
-       
-       return combo;
+       g_signal_emit (editor, signals[ACTIVATED], 0);
 }
 
 static void
-type_row_add_to_query (NautilusQueryEditorRow *row,
-                      NautilusQuery          *query)
+entry_changed_cb (GtkWidget *entry, NautilusQueryEditor *editor)
 {
-       GtkTreeIter iter;
-       char **mimetypes;
-       char *mimetype;
-       GtkTreeModel *model;
+        NautilusQueryEditorPrivate *priv;
+        NautilusQuery *query;
+        gchar *text;
+
+        priv = nautilus_query_editor_get_instance_private (editor);
 
-       if (!gtk_combo_box_get_active_iter  (GTK_COMBO_BOX (row->type_widget),
-                                            &iter)) {
+       if (priv->change_frozen || !gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (editor))) {
                return;
        }
 
-       model = gtk_combo_box_get_model (GTK_COMBO_BOX (row->type_widget));
-       gtk_tree_model_get (model, &iter, 1, &mimetypes, 2, &mimetype, -1);
+        text = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry))));
+        query = create_and_get_query (editor);
 
-       if (mimetypes != NULL) {
-               while (*mimetypes != NULL) {
-                       nautilus_query_add_mime_type (query, *mimetypes);
-                       mimetypes++;
-               }
-       }
-       if (mimetype) {
-               nautilus_query_add_mime_type (query, mimetype);
-               g_free (mimetype);
-       }
-}
+        nautilus_query_set_text (query, text);
+       nautilus_query_editor_changed (editor);
 
-static gboolean
-all_group_types_in_list (char **group_types, GList *mime_types)
-{
-       GList *l;
-       char **group_type;
-       char *mime_type;
-       gboolean found;
-
-       group_type = group_types;
-       while (*group_type != NULL) {
-               found = FALSE;
-
-               for (l = mime_types; l != NULL; l = l->next) {
-                       mime_type = l->data;
-
-                       if (strcmp (mime_type, *group_type) == 0) {
-                               found = TRUE;
-                               break;
-                       }
-               }
-               
-               if (!found) {
-                       return FALSE;
-               }
-               group_type++;
-       }
-       return TRUE;
+        g_free (text);
 }
 
-static GList *
-remove_group_types_from_list (char **group_types, GList *mime_types)
+static void
+nautilus_query_editor_on_stop_search (GtkWidget           *entry,
+                                      NautilusQueryEditor *editor)
 {
-       GList *l, *next;
-       char **group_type;
-       char *mime_type;
-
-       group_type = group_types;
-       while (*group_type != NULL) {
-               for (l = mime_types; l != NULL; l = next) {
-                       mime_type = l->data;
-                       next = l->next;
-
-                       if (strcmp (mime_type, *group_type) == 0) {
-                               mime_types = g_list_remove_link (mime_types, l);
-                               g_free (mime_type);
-                               break;
-                       }
-               }
-               
-               group_type++;
-       }
-       return mime_types;
+       g_signal_emit (editor, signals[CANCEL], 0);
 }
 
+/* Type */
 
 static void
-type_add_rows_from_query (NautilusQueryEditor    *editor,
-                         NautilusQuery          *query)
+nautilus_query_editor_init (NautilusQueryEditor *editor)
 {
-       GList *mime_types;
-       char *mime_type;
-       const char *desc;
-       NautilusQueryEditorRow *row;
-       GtkTreeIter iter;
-       int i;
-       GtkTreeModel *model;
-       GList *l;
-
-       mime_types = nautilus_query_get_mime_types (query);
-
-       if (mime_types == NULL) {
-               return;
-       }
-       
-       for (i = 0; i < G_N_ELEMENTS (mime_type_groups); i++) {
-               if (all_group_types_in_list (mime_type_groups[i].mimetypes,
-                                            mime_types)) {
-                       mime_types = remove_group_types_from_list (mime_type_groups[i].mimetypes,
-                                                                  mime_types);
-
-                       row = nautilus_query_editor_add_row (editor,
-                                                            NAUTILUS_QUERY_EDITOR_ROW_TYPE);
-
-                       model = gtk_combo_box_get_model (GTK_COMBO_BOX (row->type_widget));
-
-                       gtk_tree_model_iter_nth_child (model, &iter, NULL, i + 2);
-                       gtk_combo_box_set_active_iter  (GTK_COMBO_BOX (row->type_widget),
-                                                       &iter);
-               }
-       }
-
-       for (l = mime_types; l != NULL; l = l->next) {
-               mime_type = l->data;
-
-               desc = g_content_type_get_description (mime_type);
-               if (desc == NULL) {
-                       desc = mime_type;
-               }
-
-               row = nautilus_query_editor_add_row (editor,
-                                                    NAUTILUS_QUERY_EDITOR_ROW_TYPE);
-               
-               type_add_custom_type (row, mime_type, desc, &iter);
-               gtk_combo_box_set_active_iter  (GTK_COMBO_BOX (row->type_widget),
-                                               &iter);
-       }
-
-       g_list_free_full (mime_types, g_free);
 }
 
-/* End of row types */
-
-static NautilusQueryEditorRowType
-get_next_free_type (NautilusQueryEditor *editor)
+static gboolean
+entry_key_press_event_cb (GtkWidget           *widget,
+                         GdkEventKey         *event,
+                         NautilusQueryEditor *editor)
 {
-       NautilusQueryEditorRow *row;
-       NautilusQueryEditorRowType type;
-       gboolean found;
-       GList *l;
-
-       
-       for (type = 0; type < NAUTILUS_QUERY_EDITOR_ROW_LAST; type++) {
-               found = FALSE;
-               for (l = editor->details->rows; l != NULL; l = l->next) {
-                       row = l->data;
-                       if (row->type == type) {
-                               found = TRUE;
-                               break;
-                       }
-               }
-               if (!found) {
-                       return type;
-               }
+       if (event->keyval == GDK_KEY_Down) {
+               gtk_widget_grab_focus (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
        }
-       return NAUTILUS_QUERY_EDITOR_ROW_TYPE;
+       return FALSE;
 }
 
 static void
-remove_row_cb (GtkButton *clicked_button, NautilusQueryEditorRow *row)
+search_mode_changed_cb (GObject    *editor,
+                        GParamSpec *pspec,
+                        gpointer    user_data)
 {
-       NautilusQueryEditor *editor;
+        NautilusQueryEditorPrivate *priv;
 
-       editor = row->editor;
-       editor->details->rows = g_list_remove (editor->details->rows, row);
-       row_destroy (row);
-
-       nautilus_query_editor_changed (editor);
-}
+        priv = nautilus_query_editor_get_instance_private (NAUTILUS_QUERY_EDITOR (editor));
 
-static void
-create_type_widgets (NautilusQueryEditorRow *row)
-{
-       row->type_widget = row_type[row->type].create_widgets (row);
+        if (!gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (editor))) {
+                g_signal_emit (editor, signals[CANCEL], 0);
+                gtk_widget_hide (priv->popover);
+        }
 }
 
 static void
-row_type_combo_changed_cb (GtkComboBox *combo_box, NautilusQueryEditorRow *row)
+search_popover_changed_cb (NautilusSearchPopover *popover,
+                           NautilusSearchFilter   filter,
+                           gpointer               data,
+                           NautilusQueryEditor   *editor)
 {
-       NautilusQueryEditorRowType type;
+        NautilusQuery *query;
 
-       type = gtk_combo_box_get_active (combo_box);
+        query = create_and_get_query (editor);
 
-       if (type == row->type) {
-               return;
-       }
+        switch (filter) {
+        case NAUTILUS_SEARCH_FILTER_DATE:
+                nautilus_query_set_date (query, data);
+                break;
 
-       if (row->type_widget != NULL) {
-               gtk_widget_destroy (row->type_widget);
-               row->type_widget = NULL;
-       }
+        case NAUTILUS_SEARCH_FILTER_TYPE:
+                nautilus_query_set_mime_types (query, data);
+                break;
 
-       row->type = type;
-       
-       create_type_widgets (row);
+        default:
+                break;
+        }
 
-       nautilus_query_editor_changed (row->editor);
+        nautilus_query_editor_changed (editor);
 }
 
-static NautilusQueryEditorRow *
-nautilus_query_editor_add_row (NautilusQueryEditor *editor,
-                              NautilusQueryEditorRowType type)
+static void
+setup_widgets (NautilusQueryEditor *editor)
 {
-       GtkWidget *hbox, *button, *image, *combo;
-       GtkToolItem *item;
-       NautilusQueryEditorRow *row;
-       int i;
-
-       row = g_new0 (NautilusQueryEditorRow, 1);
-       row->editor = editor;
-       row->type = type;
-
-       /* create the toolbar and the box container for its contents */
-       row->toolbar = gtk_toolbar_new ();
-       gtk_style_context_add_class (gtk_widget_get_style_context (row->toolbar),
-                                    "search-bar");
-       gtk_box_pack_start (GTK_BOX (editor), row->toolbar, TRUE, TRUE, 0);
-
-       item = gtk_tool_item_new ();
-       gtk_tool_item_set_expand (item, TRUE);
-       gtk_toolbar_insert (GTK_TOOLBAR (row->toolbar), item, -1);
-
-       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-       gtk_container_add (GTK_CONTAINER (item), hbox);
-       row->hbox = hbox;
-
-       /* create the criterion selector combobox */
-       combo = gtk_combo_box_text_new ();
-       row->combo = combo;
-       for (i = 0; i < NAUTILUS_QUERY_EDITOR_ROW_LAST; i++) {
-               gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), gettext (row_type[i].name));
-       }
-       gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
-
-       gtk_combo_box_set_active (GTK_COMBO_BOX (combo), row->type);
-
-       editor->details->rows = g_list_append (editor->details->rows, row);
-
-       g_signal_connect (combo, "changed",
-                         G_CALLBACK (row_type_combo_changed_cb), row);
-       
-       create_type_widgets (row);
-
-       /* create the remove row button */
-       button = gtk_button_new ();
-       gtk_style_context_add_class (gtk_widget_get_style_context (button),
-                                    GTK_STYLE_CLASS_RAISED);
-       gtk_widget_set_tooltip_text (button,
-                                    _("Remove this criterion from the search"));
-       gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+        NautilusQueryEditorPrivate *priv;
+       GtkWidget *button, *hbox, *vbox;
 
-       image = gtk_image_new_from_icon_name ("window-close-symbolic",
-                                             GTK_ICON_SIZE_MENU);
-       gtk_container_add (GTK_CONTAINER (button), image);
+        priv = nautilus_query_editor_get_instance_private (editor);
 
-       g_signal_connect (button, "clicked",
-                         G_CALLBACK (remove_row_cb), row);
+        /* Spinner for when the search is happening */
+        priv->spinner = gtk_spinner_new ();
+        gtk_widget_set_margin_end (priv->spinner, 18);
+        gtk_widget_show (priv->spinner);
 
-       /* show everything */
-       gtk_widget_show_all (row->toolbar);
-
-       return row;
-}
+        /* HACK: we're invasively adding the spinner to GtkSearchBar > GtkRevealer > GtkBox */
+        gtk_box_pack_end (GTK_BOX (gtk_bin_get_child (GTK_BIN (gtk_bin_get_child (GTK_BIN (editor))))), 
priv->spinner, FALSE, TRUE, 0);
 
-static void
-add_new_row_cb (GtkButton *clicked_button, NautilusQueryEditor *editor)
-{
-       nautilus_query_editor_add_row (editor, get_next_free_type (editor));
-       nautilus_query_editor_changed (editor);
-}
+        /* vertical box that holds the search entry and the label below */
+       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+       gtk_container_add (GTK_CONTAINER (editor), vbox);
 
-static void
-nautilus_query_editor_init (NautilusQueryEditor *editor)
-{
-       editor->details = G_TYPE_INSTANCE_GET_PRIVATE (editor, NAUTILUS_TYPE_QUERY_EDITOR,
-                                                      NautilusQueryEditorDetails);
+        /* horizontal box */
+       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+        gtk_style_context_add_class (gtk_widget_get_style_context (hbox), "linked");
+       gtk_container_add (GTK_CONTAINER (vbox), hbox);
 
-       gtk_orientable_set_orientation (GTK_ORIENTABLE (editor), GTK_ORIENTATION_VERTICAL);
-}
+       /* create the search entry */
+       priv->entry = gtk_search_entry_new ();
+        gtk_entry_set_width_chars (GTK_ENTRY (priv->entry), 40);
+        gtk_search_bar_connect_entry (GTK_SEARCH_BAR (editor), GTK_ENTRY (priv->entry));
 
-static void
-on_location_button_toggled (GtkToggleButton     *button,
-                      NautilusQueryEditor *editor)
-{
-       nautilus_query_editor_changed (editor);
-}
+        gtk_container_add (GTK_CONTAINER (hbox), priv->entry);
 
-static gboolean
-entry_key_press_event_cb (GtkWidget           *widget,
-                         GdkEventKey         *event,
-                         NautilusQueryEditor *editor)
-{
-       if (event->keyval == GDK_KEY_Down) {
-               gtk_widget_grab_focus (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
-       }
-       return FALSE;
-}
+        /* additional information label */
+        priv->label = gtk_label_new (NULL);
+        gtk_widget_set_no_show_all (priv->label, TRUE);
+        gtk_style_context_add_class (gtk_widget_get_style_context (priv->label), "dim-label");
 
-static void
-setup_widgets (NautilusQueryEditor *editor)
-{
-       GtkToolItem *item;
-       GtkWidget *toolbar, *button_box, *hbox;
-       GtkWidget *button, *image;
+       gtk_container_add (GTK_CONTAINER (vbox), priv->label);
 
-       /* create the toolbar and the box container for its contents */
-       toolbar = gtk_toolbar_new ();
-       gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), FALSE);
-       gtk_style_context_add_class (gtk_widget_get_style_context (toolbar),
-                                    "search-bar");
-       gtk_box_pack_start (GTK_BOX (editor), toolbar, TRUE, TRUE, 0);
+        /* setup the search popover */
+        priv->popover = nautilus_search_popover_new ();
 
-       item = gtk_tool_item_new ();
-       gtk_tool_item_set_expand (item, TRUE);
-       gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
+        g_object_bind_property (editor, "location",
+                                priv->popover, "location",
+                                G_BINDING_DEFAULT);
 
-       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-       gtk_container_add (GTK_CONTAINER (item), hbox);
+        g_object_bind_property (editor, "query",
+                                priv->popover, "query",
+                                G_BINDING_DEFAULT);
 
-       /* create the search entry */
-       editor->details->entry = gtk_search_entry_new ();
-       gtk_box_pack_start (GTK_BOX (hbox), editor->details->entry, TRUE, TRUE, 0);
+        /* setup the filter menu button */
+        button = gtk_menu_button_new ();
+        gtk_menu_button_set_popover (GTK_MENU_BUTTON (button), priv->popover);
+        gtk_container_add (GTK_CONTAINER (hbox), button);
 
-       g_signal_connect (editor->details->entry, "key-press-event",
+        g_signal_connect (editor, "notify::search-mode-enabled",
+                          G_CALLBACK (search_mode_changed_cb), NULL);
+       g_signal_connect (priv->entry, "key-press-event",
                          G_CALLBACK (entry_key_press_event_cb), editor);
-       g_signal_connect (editor->details->entry, "activate",
+       g_signal_connect (priv->entry, "activate",
                          G_CALLBACK (entry_activate_cb), editor);
-       g_signal_connect (editor->details->entry, "search-changed",
+       g_signal_connect (priv->entry, "search-changed",
                          G_CALLBACK (entry_changed_cb), editor);
-       g_signal_connect (editor->details->entry, "stop-search",
+       g_signal_connect (priv->entry, "stop-search",
                           G_CALLBACK (nautilus_query_editor_on_stop_search), editor);
-
-       /* create the Current/All Files selector */
-       editor->details->search_current_button = gtk_radio_button_new_with_label (NULL, _("Current"));
-       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (editor->details->search_current_button), FALSE);
-       editor->details->search_all_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON 
(editor->details->search_current_button),
-                                                                                         _("All Files"));
-       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (editor->details->search_all_button), FALSE);
-
-       /* connect to the signal only on one of the two, since they're mutually exclusive */
-       g_signal_connect (editor->details->search_current_button, "toggled",
-                         G_CALLBACK (on_location_button_toggled), editor);
-
-       button_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-       gtk_box_pack_start (GTK_BOX (hbox), button_box, FALSE, FALSE, 0);
-       gtk_style_context_add_class (gtk_widget_get_style_context (button_box),
-                                    GTK_STYLE_CLASS_LINKED);
-       gtk_style_context_add_class (gtk_widget_get_style_context (button_box),
-                                    GTK_STYLE_CLASS_RAISED);
-
-       gtk_box_pack_start (GTK_BOX (button_box), editor->details->search_current_button, FALSE, FALSE, 0);
-       gtk_box_pack_start (GTK_BOX (button_box), editor->details->search_all_button, FALSE, FALSE, 0);
-
-       /* finally, create the add new row button */
-       button = gtk_button_new ();
-       gtk_style_context_add_class (gtk_widget_get_style_context (button),
-                                    GTK_STYLE_CLASS_RAISED);
-       gtk_widget_set_tooltip_text (button,
-                                    _("Add a new criterion to this search"));
-       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
-
-       image = gtk_image_new_from_icon_name ("list-add-symbolic",
-                                             GTK_ICON_SIZE_MENU);
-       gtk_container_add (GTK_CONTAINER (button), image);
-
-       g_signal_connect (button, "clicked",
-                         G_CALLBACK (add_new_row_cb), editor);
+        g_signal_connect (priv->popover, "changed",
+                          G_CALLBACK (search_popover_changed_cb), editor);
 
        /* show everything */
-       gtk_widget_show_all (toolbar);
-}
-
-static void
-nautilus_query_editor_changed_force (NautilusQueryEditor *editor, gboolean force_reload)
-{
-       NautilusQuery *query;
-
-       if (editor->details->change_frozen) {
-               return;
-       }
-
-       query = nautilus_query_editor_get_query (editor);
-       g_signal_emit (editor, signals[CHANGED], 0,
-                      query, force_reload);
-       g_object_unref (query);
+       gtk_widget_show_all (vbox);
 }
 
 static void
 nautilus_query_editor_changed (NautilusQueryEditor *editor)
 {
-       nautilus_query_editor_changed_force (editor, TRUE);
-}
+        NautilusQueryEditorPrivate *priv;
 
-static void
-add_location_to_query (NautilusQueryEditor *editor,
-                      NautilusQuery       *query)
-{
-        GFile *location;
+        priv = nautilus_query_editor_get_instance_private (editor);
 
-       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (editor->details->search_all_button))) {
-               location = g_file_new_for_uri (nautilus_get_home_directory_uri ());
-       } else {
-                location = nautilus_query_editor_get_location (editor);
+        if (priv->change_frozen) {
+               return;
        }
 
-       nautilus_query_set_location (query, location);
-       g_clear_object (&location);
+       g_signal_emit (editor, signals[CHANGED], 0, priv->query, TRUE);
 }
 
 NautilusQuery *
 nautilus_query_editor_get_query (NautilusQueryEditor *editor)
 {
-       const char *query_text;
-       NautilusQuery *query;
-       GList *l;
-       NautilusQueryEditorRow *row;
+        NautilusQueryEditorPrivate *priv;
 
-       if (editor == NULL || editor->details == NULL || editor->details->entry == NULL) {
+        priv = nautilus_query_editor_get_instance_private (editor);
+
+        if (editor == NULL || priv->entry == NULL || priv->query == NULL) {
                return NULL;
        }
 
-       query_text = gtk_entry_get_text (GTK_ENTRY (editor->details->entry));
-
-       query = nautilus_query_new ();
-       nautilus_query_set_text (query, query_text);
-
-       add_location_to_query (editor, query);
-
-       for (l = editor->details->rows; l != NULL; l = l->next) {
-               row = l->data;
-               
-               row_type[row->type].add_to_query (row, query);
-       }
-       
-       return query;
+        return g_object_ref (priv->query);
 }
 
 GtkWidget *
@@ -1058,41 +454,17 @@ nautilus_query_editor_new (void)
        return editor;
 }
 
-static void
-update_location (NautilusQueryEditor *editor)
-{
-       NautilusFile *file;
-       GtkWidget *label;
-
-        file = nautilus_file_get (editor->details->current_location);
-
-       if (file != NULL) {
-               char *name;
-               if (nautilus_file_is_home (file)) {
-                       name = g_strdup (_("Home"));
-               } else {
-                       name = nautilus_file_get_display_name (file);
-               }
-
-               gtk_button_set_label (GTK_BUTTON (editor->details->search_current_button), name);
-               g_free (name);
-
-               label = gtk_bin_get_child (GTK_BIN (editor->details->search_current_button));
-               gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
-               g_object_set (label, "max-width-chars", 30, NULL);
-
-               nautilus_file_unref (file);
-       }
-}
-
 void
 nautilus_query_editor_set_location (NautilusQueryEditor *editor,
                                    GFile               *location)
 {
+        NautilusQueryEditorPrivate *priv;
         NautilusDirectory *directory;
         NautilusDirectory *base_model;
+        gboolean should_notify;
 
-       g_clear_object (&editor->details->current_location);
+        priv = nautilus_query_editor_get_instance_private (editor);
+        should_notify = FALSE;
 
         /* The client could set us a location that is actually a search directory,
          * like what happens with the slot when updating the query editor location.
@@ -1100,42 +472,62 @@ nautilus_query_editor_set_location (NautilusQueryEditor *editor,
          * not the search directory invented uri. */
         directory = nautilus_directory_get (location);
         if (NAUTILUS_IS_SEARCH_DIRECTORY (directory)) {
+                GFile *real_location;
+
                 base_model = nautilus_search_directory_get_base_model (NAUTILUS_SEARCH_DIRECTORY 
(directory));
-                editor->details->current_location = nautilus_directory_get_location (base_model);
+                real_location = nautilus_directory_get_location (base_model);
+
+                should_notify = g_set_object (&priv->location, real_location);
+
+                g_object_unref (real_location);
         } else {
-                editor->details->current_location = g_object_ref (location);
+                should_notify = g_set_object (&priv->location, location);
+        }
+
+        /* Update label if needed */
+        if (priv->location) {
+                NautilusFile *file;
+                gchar *label;
+                gchar *uri;
+
+                file = nautilus_file_get (priv->location);
+                label = NULL;
+                uri = g_file_get_uri (priv->location);
+
+                if (nautilus_file_is_other_locations (file)) {
+                        label = _("Searching locations only");
+                } else if (g_str_has_prefix (uri, "computer://")) {
+                        label = _("Searching devices only");
+                } else if (g_str_has_prefix (uri, "network://")) {
+                        label = _("Searching network locations only");
+                } else if (!nautilus_file_is_local (file)) {
+                        label = _("Remote location - only searching the current folder");
+                }
+
+               gtk_widget_set_visible (priv->label, label != NULL);
+               gtk_label_set_label (GTK_LABEL (priv->label), label);
+
+               g_free (uri);
+        }
+
+        if (should_notify) {
+                g_object_notify (G_OBJECT (editor), "location");
         }
-       update_location (editor);
 
         g_clear_object (&directory);
-}
 
-static void
-update_rows (NautilusQueryEditor *editor,
-            NautilusQuery       *query)
-{
-       NautilusQueryEditorRowType type;
-
-       /* if we were just created, set the rows from query,
-        * otherwise, re-use the query setting we have already.
-        */
-       if (query != NULL && editor->details->query == NULL) {
-               for (type = 0; type < NAUTILUS_QUERY_EDITOR_ROW_LAST; type++) {
-                       row_type[type].add_rows_from_query (editor, query);
-               }
-       } else if (query == NULL && editor->details->query != NULL) {
-               g_list_free_full (editor->details->rows, (GDestroyNotify) row_destroy);
-               editor->details->rows = NULL;
-       }
 }
 
 void
 nautilus_query_editor_set_query (NautilusQueryEditor   *editor,
                                 NautilusQuery          *query)
 {
+        NautilusQueryEditorPrivate *priv;
        char *text = NULL;
        char *current_text = NULL;
 
+        priv = nautilus_query_editor_get_instance_private (editor);
+
        if (query != NULL) {
                text = nautilus_query_get_text (query);
        }
@@ -1144,26 +536,28 @@ nautilus_query_editor_set_query (NautilusQueryEditor     *editor,
                text = g_strdup ("");
        }
 
-       editor->details->change_frozen = TRUE;
+       priv->change_frozen = TRUE;
 
-       current_text = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (editor->details->entry))));
+       current_text = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry))));
        if (!g_str_equal (current_text, text)) {
-               gtk_entry_set_text (GTK_ENTRY (editor->details->entry), text);
+               gtk_entry_set_text (GTK_ENTRY (priv->entry), text);
        }
        g_free (current_text);
 
-        g_clear_object (&editor->details->current_location);
+        /* Clear bindings */
+        g_clear_pointer (&priv->spinner_active_binding, g_binding_unbind);
 
-       update_rows (editor, query);
-       g_clear_object (&editor->details->query);
+        if (g_set_object (&priv->query, query)) {
+                if (query) {
+                       priv->spinner_active_binding = g_object_bind_property (query, "searching",
+                                                                               priv->spinner, "active",
+                                                                               G_BINDING_DEFAULT | 
G_BINDING_SYNC_CREATE);
+               }
 
-       if (query != NULL) {
-               editor->details->query = g_object_ref (query);
-               editor->details->current_location = nautilus_query_get_location (query);
-               update_location (editor);
-       }
+                g_object_notify (G_OBJECT (editor), "query");
+        }
 
-       editor->details->change_frozen = FALSE;
+       priv->change_frozen = FALSE;
 
        g_free (text);
 }
diff --git a/src/nautilus-query-editor.h b/src/nautilus-query-editor.h
index 4733953..d166c6d 100644
--- a/src/nautilus-query-editor.h
+++ b/src/nautilus-query-editor.h
@@ -28,42 +28,24 @@
 #include <libnautilus-private/nautilus-query.h>
 
 #define NAUTILUS_TYPE_QUERY_EDITOR nautilus_query_editor_get_type()
-#define NAUTILUS_QUERY_EDITOR(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_QUERY_EDITOR, NautilusQueryEditor))
-#define NAUTILUS_QUERY_EDITOR_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_QUERY_EDITOR, NautilusQueryEditorClass))
-#define NAUTILUS_IS_QUERY_EDITOR(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_QUERY_EDITOR))
-#define NAUTILUS_IS_QUERY_EDITOR_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_QUERY_EDITOR))
-#define NAUTILUS_QUERY_EDITOR_GET_CLASS(obj) \
-  (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_QUERY_EDITOR, NautilusQueryEditorClass))
 
-typedef struct NautilusQueryEditorDetails NautilusQueryEditorDetails;
+G_DECLARE_DERIVABLE_TYPE (NautilusQueryEditor, nautilus_query_editor, NAUTILUS, QUERY_EDITOR, GtkSearchBar)
 
-typedef struct NautilusQueryEditor {
-       GtkBox parent;
-       NautilusQueryEditorDetails *details;
-} NautilusQueryEditor;
-
-typedef struct {
-       GtkBoxClass parent_class;
+struct _NautilusQueryEditorClass {
+        GtkSearchBarClass parent_class;
 
        void (* changed)   (NautilusQueryEditor  *editor,
                            NautilusQuery        *query,
                            gboolean              reload);
        void (* cancel)    (NautilusQueryEditor *editor);
        void (* activated) (NautilusQueryEditor *editor);
-} NautilusQueryEditorClass;
+};
 
 #include "nautilus-window-slot.h"
 
 GType      nautilus_query_editor_get_type         (void);
 GtkWidget* nautilus_query_editor_new              (void);
 
-gboolean       nautilus_query_editor_handle_event (NautilusQueryEditor *editor,
-                                                  GdkEventKey         *event);
-
 NautilusQuery *nautilus_query_editor_get_query   (NautilusQueryEditor *editor);
 void           nautilus_query_editor_set_query   (NautilusQueryEditor *editor,
                                                  NautilusQuery       *query);
diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c
index f775a14..dd9d080 100644
--- a/src/nautilus-window-slot.c
+++ b/src/nautilus-window-slot.c
@@ -100,7 +100,6 @@ struct NautilusWindowSlotDetails {
 
        /* Query editor */
        NautilusQueryEditor *query_editor;
-       GtkWidget *query_editor_revealer;
        gulong qe_changed_id;
        gulong qe_cancel_id;
        gulong qe_activated_id;
@@ -357,8 +356,7 @@ hide_query_editor (NautilusWindowSlot *slot)
 
         view = nautilus_window_slot_get_current_view (slot);
 
-       gtk_revealer_set_reveal_child (GTK_REVEALER (slot->details->query_editor_revealer),
-                                      FALSE);
+       gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (slot->details->query_editor), FALSE);
 
        if (slot->details->qe_changed_id > 0) {
                g_signal_handler_disconnect (slot->details->query_editor, slot->details->qe_changed_id);
@@ -412,11 +410,9 @@ static void
 show_query_editor (NautilusWindowSlot *slot)
 {
         NautilusView *view;
-        GFile *location;
 
         view = nautilus_window_slot_get_current_view (slot);
 
-        location = nautilus_window_slot_get_current_location (slot);
         if (nautilus_view_is_searching (view)) {
                 NautilusQuery *query;
 
@@ -425,13 +421,9 @@ show_query_editor (NautilusWindowSlot *slot)
                 if (query != NULL) {
                         nautilus_query_editor_set_query (slot->details->query_editor, query);
                 }
-        } else {
-                /* In this way, when the query changes it will open the actual search */
-                nautilus_query_editor_set_location (slot->details->query_editor, location);
         }
 
-       gtk_revealer_set_reveal_child (GTK_REVEALER (slot->details->query_editor_revealer),
-                                      TRUE);
+        gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (slot->details->query_editor), TRUE);
        gtk_widget_grab_focus (GTK_WIDGET (slot->details->query_editor));
 
        if (slot->details->qe_changed_id == 0) {
@@ -489,7 +481,8 @@ nautilus_window_slot_handle_event (NautilusWindowSlot *slot,
        retval = FALSE;
        window = nautilus_window_slot_get_window (slot);
        if (!NAUTILUS_IS_DESKTOP_WINDOW (window)) {
-               retval = nautilus_query_editor_handle_event (slot->details->query_editor, event);
+                retval = gtk_search_bar_handle_event (GTK_SEARCH_BAR (slot->details->query_editor),
+                                                      (GdkEvent*) event);
        }
 
        if (retval) {
@@ -540,7 +533,7 @@ remove_all_extra_location_widgets (GtkWidget *widget,
        NautilusDirectory *directory;
 
        directory = nautilus_directory_get (slot->details->location);
-       if (widget != GTK_WIDGET (slot->details->query_editor_revealer)) {
+       if (widget != GTK_WIDGET (slot->details->query_editor)) {
                gtk_container_remove (GTK_CONTAINER (slot->details->extra_location_widgets), widget);
        }
 
@@ -639,11 +632,12 @@ nautilus_window_slot_constructed (GObject *object)
        gtk_widget_show (extras_vbox);
 
        slot->details->query_editor = NAUTILUS_QUERY_EDITOR (nautilus_query_editor_new ());
-       slot->details->query_editor_revealer = gtk_revealer_new ();
-       gtk_container_add (GTK_CONTAINER (slot->details->query_editor_revealer),
-                          GTK_WIDGET (slot->details->query_editor));
-       gtk_widget_show_all (slot->details->query_editor_revealer);
-       nautilus_window_slot_add_extra_location_widget (slot, slot->details->query_editor_revealer);
+        gtk_widget_show (GTK_WIDGET (slot->details->query_editor));
+        nautilus_window_slot_add_extra_location_widget (slot, GTK_WIDGET (slot->details->query_editor));
+
+        g_object_bind_property (slot, "location",
+                                slot->details->query_editor, "location",
+                                G_BINDING_DEFAULT);
 
        slot->details->title = g_strdup (_("Loading…"));
 }
@@ -980,8 +974,6 @@ nautilus_window_slot_set_location (NautilusWindowSlot *slot,
 
        nautilus_window_slot_update_title (slot);
 
-        nautilus_query_editor_set_location (slot->details->query_editor, location);
-
        if (old_location) {
                g_object_unref (old_location);
        }
@@ -2083,7 +2075,6 @@ view_started_loading (NautilusWindowSlot *slot,
                 nautilus_window_slot_set_allow_stop (slot, TRUE);
         }
 
-        nautilus_query_editor_set_location (slot->details->query_editor, nautilus_view_get_location (view));
         gtk_widget_grab_focus (GTK_WIDGET (slot->details->window));
 
         gtk_widget_show (GTK_WIDGET (slot->details->window));


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