1 /*
2 * Copyright (C) 2005 Red Hat, Inc.
3 *
4 * Nautilus is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * Nautilus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public
15 * License along with this program; see the file COPYING. If not,
16 * see <http://www.gnu.org/licenses/>.
17 *
18 * Author: Alexander Larsson <alexl@redhat.com>
19 * Georges Basile Stavracas Neto <gbsneto@gnome.org>
20 *
21 */
22
23 #include "nautilus-query-editor.h"
24
25 #include <gdk/gdkkeysyms.h>
26 #include <gio/gio.h>
27 #include <glib/gi18n.h>
28 #include <gtk/gtk.h>
29 #include <libgd/gd.h>
30 #include <string.h>
31
32 #include "nautilus-file.h"
33 #include "nautilus-file-utilities.h"
34 #include "nautilus-global-preferences.h"
35 #include "nautilus-search-directory.h"
36 #include "nautilus-search-popover.h"
37 #include "nautilus-mime-actions.h"
38 #include "nautilus-ui-utilities.h"
39
40 struct _NautilusQueryEditor
41 {
42 GtkBox parent_instance;
43
44 GtkWidget *entry;
45 GtkWidget *popover;
46 GtkWidget *dropdown_button;
47
48 GdTaggedEntryTag *mime_types_tag;
49 GdTaggedEntryTag *date_range_tag;
50
51 gboolean change_frozen;
52
53 GFile *location;
54
55 NautilusQuery *query;
56 };
57
58 enum
59 {
60 ACTIVATED,
61 FOCUS_VIEW,
62 CHANGED,
63 CANCEL,
64 LAST_SIGNAL
65 };
66
67 enum
68 {
69 PROP_0,
70 PROP_LOCATION,
71 PROP_QUERY,
72 LAST_PROP
73 };
74
75 static guint signals[LAST_SIGNAL];
76
77 static void entry_activate_cb (GtkWidget *entry,
78 NautilusQueryEditor *editor);
79 static void entry_changed_cb (GtkWidget *entry,
80 NautilusQueryEditor *editor);
81 static void nautilus_query_editor_changed (NautilusQueryEditor *editor);
82
83 G_DEFINE_TYPE (NautilusQueryEditor, nautilus_query_editor, GTK_TYPE_BOX);
84
85 static void
update_fts_sensitivity(NautilusQueryEditor * editor)86 update_fts_sensitivity (NautilusQueryEditor *editor)
87 {
88 gboolean fts_sensitive = TRUE;
89
90 if (editor->location)
91 {
92 g_autoptr (NautilusFile) file = NULL;
93 g_autofree gchar *uri = NULL;
94
95 file = nautilus_file_get (editor->location);
96 uri = g_file_get_uri (editor->location);
97
98 fts_sensitive = !nautilus_file_is_other_locations (file) &&
99 !g_str_has_prefix (uri, "network://") &&
100 !(nautilus_file_is_remote (file) &&
101 location_settings_search_get_recursive_for_location (editor->location) == NAUTILUS_QUERY_RECURSIVE_NEVER);
102 nautilus_search_popover_set_fts_sensitive (NAUTILUS_SEARCH_POPOVER (editor->popover),
103 fts_sensitive);
104 }
105 }
106
107 static void
recursive_search_preferences_changed(GSettings * settings,gchar * key,NautilusQueryEditor * editor)108 recursive_search_preferences_changed (GSettings *settings,
109 gchar *key,
110 NautilusQueryEditor *editor)
111 {
112 NautilusQueryRecursive recursive;
113
114 if (!editor->query)
115 {
116 return;
117 }
118
119 recursive = location_settings_search_get_recursive ();
120 if (recursive != nautilus_query_get_recursive (editor->query))
121 {
122 nautilus_query_set_recursive (editor->query, recursive);
123 nautilus_query_editor_changed (editor);
124 }
125
126 update_fts_sensitivity (editor);
127 }
128
129
130 static void
nautilus_query_editor_dispose(GObject * object)131 nautilus_query_editor_dispose (GObject *object)
132 {
133 NautilusQueryEditor *editor;
134
135 editor = NAUTILUS_QUERY_EDITOR (object);
136
137 g_clear_object (&editor->location);
138 g_clear_object (&editor->query);
139
140 g_signal_handlers_disconnect_by_func (nautilus_preferences,
141 recursive_search_preferences_changed,
142 object);
143
144 G_OBJECT_CLASS (nautilus_query_editor_parent_class)->dispose (object);
145 }
146
147 static void
nautilus_query_editor_grab_focus(GtkWidget * widget)148 nautilus_query_editor_grab_focus (GtkWidget *widget)
149 {
150 NautilusQueryEditor *editor;
151
152 editor = NAUTILUS_QUERY_EDITOR (widget);
153
154 if (gtk_widget_get_visible (widget) && !gtk_widget_is_focus (editor->entry))
155 {
156 /* avoid selecting the entry text */
157 gtk_widget_grab_focus (editor->entry);
158 gtk_editable_set_position (GTK_EDITABLE (editor->entry), -1);
159 }
160 }
161
162 static void
nautilus_query_editor_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)163 nautilus_query_editor_get_property (GObject *object,
164 guint prop_id,
165 GValue *value,
166 GParamSpec *pspec)
167 {
168 NautilusQueryEditor *editor;
169
170 editor = NAUTILUS_QUERY_EDITOR (object);
171
172 switch (prop_id)
173 {
174 case PROP_LOCATION:
175 {
176 g_value_set_object (value, editor->location);
177 }
178 break;
179
180 case PROP_QUERY:
181 {
182 g_value_set_object (value, editor->query);
183 }
184 break;
185
186 default:
187 {
188 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
189 }
190 }
191 }
192
193 static void
nautilus_query_editor_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)194 nautilus_query_editor_set_property (GObject *object,
195 guint prop_id,
196 const GValue *value,
197 GParamSpec *pspec)
198 {
199 NautilusQueryEditor *self;
200
201 self = NAUTILUS_QUERY_EDITOR (object);
202
203 switch (prop_id)
204 {
205 case PROP_LOCATION:
206 {
207 nautilus_query_editor_set_location (self, g_value_get_object (value));
208 }
209 break;
210
211 case PROP_QUERY:
212 {
213 nautilus_query_editor_set_query (self, g_value_get_object (value));
214 }
215 break;
216
217 default:
218 {
219 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
220 }
221 }
222 }
223
224 static void
nautilus_query_editor_finalize(GObject * object)225 nautilus_query_editor_finalize (GObject *object)
226 {
227 NautilusQueryEditor *editor;
228
229 editor = NAUTILUS_QUERY_EDITOR (object);
230
231 g_clear_object (&editor->date_range_tag);
232 g_clear_object (&editor->mime_types_tag);
233
234 G_OBJECT_CLASS (nautilus_query_editor_parent_class)->finalize (object);
235 }
236
237 static void
nautilus_query_editor_class_init(NautilusQueryEditorClass * class)238 nautilus_query_editor_class_init (NautilusQueryEditorClass *class)
239 {
240 GObjectClass *gobject_class;
241 GtkWidgetClass *widget_class;
242
243 gobject_class = G_OBJECT_CLASS (class);
244 gobject_class->finalize = nautilus_query_editor_finalize;
245 gobject_class->dispose = nautilus_query_editor_dispose;
246 gobject_class->get_property = nautilus_query_editor_get_property;
247 gobject_class->set_property = nautilus_query_editor_set_property;
248
249 widget_class = GTK_WIDGET_CLASS (class);
250 widget_class->grab_focus = nautilus_query_editor_grab_focus;
251
252 signals[CHANGED] =
253 g_signal_new ("changed",
254 G_TYPE_FROM_CLASS (class),
255 G_SIGNAL_RUN_LAST,
256 0,
257 NULL, NULL,
258 g_cclosure_marshal_generic,
259 G_TYPE_NONE, 2, NAUTILUS_TYPE_QUERY, G_TYPE_BOOLEAN);
260
261 signals[CANCEL] =
262 g_signal_new ("cancel",
263 G_TYPE_FROM_CLASS (class),
264 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
265 0,
266 NULL, NULL,
267 g_cclosure_marshal_VOID__VOID,
268 G_TYPE_NONE, 0);
269
270 signals[ACTIVATED] =
271 g_signal_new ("activated",
272 G_TYPE_FROM_CLASS (class),
273 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
274 0,
275 NULL, NULL,
276 g_cclosure_marshal_VOID__VOID,
277 G_TYPE_NONE, 0);
278
279 signals[FOCUS_VIEW] =
280 g_signal_new ("focus-view",
281 G_TYPE_FROM_CLASS (class),
282 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
283 0,
284 NULL, NULL,
285 g_cclosure_marshal_VOID__VOID,
286 G_TYPE_NONE, 0);
287
288 gtk_binding_entry_add_signal (gtk_binding_set_by_class (class),
289 GDK_KEY_Down,
290 0,
291 "focus-view",
292 0);
293
294 /**
295 * NautilusQueryEditor::location:
296 *
297 * The current location of the query editor.
298 */
299 g_object_class_install_property (gobject_class,
300 PROP_LOCATION,
301 g_param_spec_object ("location",
302 "Location of the search",
303 "The current location of the editor",
304 G_TYPE_FILE,
305 G_PARAM_READWRITE));
306
307 /**
308 * NautilusQueryEditor::query:
309 *
310 * The current query of the query editor. It it always synchronized
311 * with the filter popover's query.
312 */
313 g_object_class_install_property (gobject_class,
314 PROP_QUERY,
315 g_param_spec_object ("query",
316 "Query of the search",
317 "The query that the editor is handling",
318 NAUTILUS_TYPE_QUERY,
319 G_PARAM_READWRITE));
320 }
321
322 GFile *
nautilus_query_editor_get_location(NautilusQueryEditor * editor)323 nautilus_query_editor_get_location (NautilusQueryEditor *editor)
324 {
325 g_return_val_if_fail (NAUTILUS_IS_QUERY_EDITOR (editor), NULL);
326
327 return g_object_ref (editor->location);
328 }
329
330 static void
create_query(NautilusQueryEditor * editor)331 create_query (NautilusQueryEditor *editor)
332 {
333 NautilusQuery *query;
334 g_autoptr (NautilusFile) file = NULL;
335 gboolean fts_enabled;
336
337 g_return_if_fail (editor->query == NULL);
338
339 fts_enabled = nautilus_search_popover_get_fts_enabled (NAUTILUS_SEARCH_POPOVER (editor->popover));
340
341 if (editor->location == NULL)
342 {
343 return;
344 }
345
346 file = nautilus_file_get (editor->location);
347 query = nautilus_query_new ();
348
349 nautilus_query_set_search_content (query, fts_enabled);
350
351 nautilus_query_set_text (query, gtk_entry_get_text (GTK_ENTRY (editor->entry)));
352 nautilus_query_set_location (query, editor->location);
353
354 /* We only set the query using the global setting for recursivity here,
355 * it's up to the search engine to check weather it can proceed with
356 * deep search in the current directory or not. */
357 nautilus_query_set_recursive (query, location_settings_search_get_recursive ());
358
359 nautilus_query_editor_set_query (editor, query);
360 }
361
362 static void
entry_activate_cb(GtkWidget * entry,NautilusQueryEditor * editor)363 entry_activate_cb (GtkWidget *entry,
364 NautilusQueryEditor *editor)
365 {
366 g_signal_emit (editor, signals[ACTIVATED], 0);
367 }
368
369 static void
entry_changed_cb(GtkWidget * entry,NautilusQueryEditor * editor)370 entry_changed_cb (GtkWidget *entry,
371 NautilusQueryEditor *editor)
372 {
373 if (editor->change_frozen)
374 {
375 return;
376 }
377
378 if (editor->query == NULL)
379 {
380 create_query (editor);
381 }
382 else
383 {
384 g_autofree gchar *text = NULL;
385
386 text = g_strdup (gtk_entry_get_text (GTK_ENTRY (editor->entry)));
387 text = g_strstrip (text);
388
389 nautilus_query_set_text (editor->query, text);
390 }
391
392 nautilus_query_editor_changed (editor);
393 }
394
395 static void
nautilus_query_editor_on_stop_search(GtkWidget * entry,NautilusQueryEditor * editor)396 nautilus_query_editor_on_stop_search (GtkWidget *entry,
397 NautilusQueryEditor *editor)
398 {
399 g_signal_emit (editor, signals[CANCEL], 0);
400 }
401
402 /* Type */
403
404 static void
nautilus_query_editor_init(NautilusQueryEditor * editor)405 nautilus_query_editor_init (NautilusQueryEditor *editor)
406 {
407 g_signal_connect (nautilus_preferences,
408 "changed::recursive-search",
409 G_CALLBACK (recursive_search_preferences_changed),
410 editor);
411 }
412
413 static void
search_popover_date_range_changed_cb(NautilusSearchPopover * popover,GPtrArray * date_range,gpointer user_data)414 search_popover_date_range_changed_cb (NautilusSearchPopover *popover,
415 GPtrArray *date_range,
416 gpointer user_data)
417 {
418 NautilusQueryEditor *editor;
419
420 editor = NAUTILUS_QUERY_EDITOR (user_data);
421
422 if (editor->query == NULL)
423 {
424 create_query (editor);
425 }
426
427 gd_tagged_entry_remove_tag (GD_TAGGED_ENTRY (editor->entry),
428 editor->date_range_tag);
429 if (date_range)
430 {
431 g_autofree gchar *text_for_date_range = NULL;
432
433 text_for_date_range = get_text_for_date_range (date_range, TRUE);
434 gd_tagged_entry_tag_set_label (editor->date_range_tag,
435 text_for_date_range);
436 gd_tagged_entry_add_tag (GD_TAGGED_ENTRY (editor->entry),
437 GD_TAGGED_ENTRY_TAG (editor->date_range_tag));
438 }
439
440 nautilus_query_set_date_range (editor->query, date_range);
441
442 nautilus_query_editor_changed (editor);
443 }
444
445 static void
search_popover_mime_type_changed_cb(NautilusSearchPopover * popover,gint mimetype_group,const gchar * mimetype,gpointer user_data)446 search_popover_mime_type_changed_cb (NautilusSearchPopover *popover,
447 gint mimetype_group,
448 const gchar *mimetype,
449 gpointer user_data)
450 {
451 NautilusQueryEditor *editor;
452 g_autoptr (GPtrArray) mimetypes = NULL;
453
454 editor = NAUTILUS_QUERY_EDITOR (user_data);
455
456 if (editor->query == NULL)
457 {
458 create_query (editor);
459 }
460
461 gd_tagged_entry_remove_tag (GD_TAGGED_ENTRY (editor->entry),
462 editor->mime_types_tag);
463 /* group 0 is anything */
464 if (mimetype_group == 0)
465 {
466 mimetypes = nautilus_mime_types_group_get_mimetypes (mimetype_group);
467 }
468 else if (mimetype_group > 0)
469 {
470 mimetypes = nautilus_mime_types_group_get_mimetypes (mimetype_group);
471 gd_tagged_entry_tag_set_label (editor->mime_types_tag,
472 nautilus_mime_types_group_get_name (mimetype_group));
473 gd_tagged_entry_add_tag (GD_TAGGED_ENTRY (editor->entry),
474 GD_TAGGED_ENTRY_TAG (editor->mime_types_tag));
475 }
476 else
477 {
478 g_autofree gchar *display_name = NULL;
479
480 mimetypes = g_ptr_array_new_full (1, g_free);
481 g_ptr_array_add (mimetypes, g_strdup (mimetype));
482 display_name = g_content_type_get_description (mimetype);
483 gd_tagged_entry_tag_set_label (editor->mime_types_tag, display_name);
484 gd_tagged_entry_add_tag (GD_TAGGED_ENTRY (editor->entry),
485 GD_TAGGED_ENTRY_TAG (editor->mime_types_tag));
486 }
487 nautilus_query_set_mime_types (editor->query, mimetypes);
488
489 nautilus_query_editor_changed (editor);
490 }
491
492 static void
search_popover_time_type_changed_cb(NautilusSearchPopover * popover,NautilusQuerySearchType data,gpointer user_data)493 search_popover_time_type_changed_cb (NautilusSearchPopover *popover,
494 NautilusQuerySearchType data,
495 gpointer user_data)
496 {
497 NautilusQueryEditor *editor;
498
499 editor = NAUTILUS_QUERY_EDITOR (user_data);
500
501 if (editor->query == NULL)
502 {
503 create_query (editor);
504 }
505
506 nautilus_query_set_search_type (editor->query, data);
507
508 nautilus_query_editor_changed (editor);
509 }
510
511 static void
search_popover_fts_changed_cb(GObject * popover,GParamSpec * pspec,gpointer user_data)512 search_popover_fts_changed_cb (GObject *popover,
513 GParamSpec *pspec,
514 gpointer user_data)
515 {
516 NautilusQueryEditor *editor;
517
518 editor = NAUTILUS_QUERY_EDITOR (user_data);
519
520 if (editor->query == NULL)
521 {
522 create_query (editor);
523 }
524
525 nautilus_query_set_search_content (editor->query,
526 nautilus_search_popover_get_fts_enabled (NAUTILUS_SEARCH_POPOVER (popover)));
527
528 nautilus_query_editor_changed (editor);
529 }
530
531 static void
entry_tag_clicked(NautilusQueryEditor * editor)532 entry_tag_clicked (NautilusQueryEditor *editor)
533 {
534 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (editor->dropdown_button),
535 TRUE);
536 }
537
538 static void
entry_tag_close_button_clicked(NautilusQueryEditor * editor,GdTaggedEntryTag * tag)539 entry_tag_close_button_clicked (NautilusQueryEditor *editor,
540 GdTaggedEntryTag *tag)
541 {
542 if (tag == editor->mime_types_tag)
543 {
544 nautilus_search_popover_reset_mime_types (NAUTILUS_SEARCH_POPOVER (editor->popover));
545 }
546 else
547 {
548 nautilus_search_popover_reset_date_range (NAUTILUS_SEARCH_POPOVER (editor->popover));
549 }
550 }
551
552 static void
setup_widgets(NautilusQueryEditor * editor)553 setup_widgets (NautilusQueryEditor *editor)
554 {
555 GtkWidget *hbox;
556 GtkWidget *vbox;
557
558 /* vertical box that holds the search entry and the label below */
559 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
560 gtk_container_add (GTK_CONTAINER (editor), vbox);
561
562 /* horizontal box */
563 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
564 gtk_style_context_add_class (gtk_widget_get_style_context (hbox), "linked");
565 gtk_container_add (GTK_CONTAINER (vbox), hbox);
566
567 /* create the search entry */
568 editor->entry = GTK_WIDGET (gd_tagged_entry_new ());
569 gtk_widget_set_hexpand (editor->entry, TRUE);
570
571 gtk_container_add (GTK_CONTAINER (hbox), editor->entry);
572
573 editor->mime_types_tag = gd_tagged_entry_tag_new (NULL);
574 editor->date_range_tag = gd_tagged_entry_tag_new (NULL);
575
576 g_signal_connect_swapped (editor->entry,
577 "tag-clicked",
578 G_CALLBACK (entry_tag_clicked),
579 editor);
580 g_signal_connect_swapped (editor->entry,
581 "tag-button-clicked",
582 G_CALLBACK (entry_tag_close_button_clicked),
583 editor);
584
585 /* setup the search popover */
586 editor->popover = nautilus_search_popover_new ();
587
588 g_signal_connect (editor->popover, "show",
589 G_CALLBACK (gtk_widget_grab_focus), NULL);
590 g_signal_connect_swapped (editor->popover, "closed",
591 G_CALLBACK (gtk_widget_grab_focus), editor);
592
593 g_object_bind_property (editor, "query",
594 editor->popover, "query",
595 G_BINDING_DEFAULT);
596
597 /* setup the filter menu button */
598 editor->dropdown_button = gtk_menu_button_new ();
599 gtk_menu_button_set_popover (GTK_MENU_BUTTON (editor->dropdown_button), editor->popover);
600 gtk_container_add (GTK_CONTAINER (hbox), editor->dropdown_button);
601
602 g_signal_connect (editor->entry, "activate",
603 G_CALLBACK (entry_activate_cb), editor);
604 g_signal_connect (editor->entry, "search-changed",
605 G_CALLBACK (entry_changed_cb), editor);
606 g_signal_connect (editor->entry, "stop-search",
607 G_CALLBACK (nautilus_query_editor_on_stop_search), editor);
608 g_signal_connect (editor->popover, "date-range",
609 G_CALLBACK (search_popover_date_range_changed_cb), editor);
610 g_signal_connect (editor->popover, "mime-type",
611 G_CALLBACK (search_popover_mime_type_changed_cb), editor);
612 g_signal_connect (editor->popover, "time-type",
613 G_CALLBACK (search_popover_time_type_changed_cb), editor);
614 g_signal_connect (editor->popover, "notify::fts-enabled",
615 G_CALLBACK (search_popover_fts_changed_cb), editor);
616
617 /* show everything */
618 gtk_widget_show_all (vbox);
619 }
620
621 static void
nautilus_query_editor_changed(NautilusQueryEditor * editor)622 nautilus_query_editor_changed (NautilusQueryEditor *editor)
623 {
624 if (editor->change_frozen)
625 {
626 return;
627 }
628
629 g_signal_emit (editor, signals[CHANGED], 0, editor->query, TRUE);
630 }
631
632 NautilusQuery *
nautilus_query_editor_get_query(NautilusQueryEditor * editor)633 nautilus_query_editor_get_query (NautilusQueryEditor *editor)
634 {
635 g_return_val_if_fail (NAUTILUS_IS_QUERY_EDITOR (editor), NULL);
636
637 if (editor->entry == NULL)
638 {
639 return NULL;
640 }
641
642 return editor->query;
643 }
644
645 GtkWidget *
nautilus_query_editor_new(void)646 nautilus_query_editor_new (void)
647 {
648 NautilusQueryEditor *editor;
649
650 editor = g_object_new (NAUTILUS_TYPE_QUERY_EDITOR, NULL);
651
652 setup_widgets (editor);
653
654 return GTK_WIDGET (editor);
655 }
656
657 void
nautilus_query_editor_set_location(NautilusQueryEditor * editor,GFile * location)658 nautilus_query_editor_set_location (NautilusQueryEditor *editor,
659 GFile *location)
660 {
661 g_autoptr (NautilusDirectory) directory = NULL;
662 NautilusDirectory *base_model;
663 gboolean should_notify;
664
665 g_return_if_fail (NAUTILUS_IS_QUERY_EDITOR (editor));
666
667 /* The client could set us a location that is actually a search directory,
668 * like what happens with the slot when updating the query editor location.
669 * However here we want the real location used as a model for the search,
670 * not the search directory invented uri. */
671 directory = nautilus_directory_get (location);
672 if (NAUTILUS_IS_SEARCH_DIRECTORY (directory))
673 {
674 g_autoptr (GFile) real_location = NULL;
675
676 base_model = nautilus_search_directory_get_base_model (NAUTILUS_SEARCH_DIRECTORY (directory));
677 real_location = nautilus_directory_get_location (base_model);
678
679 should_notify = g_set_object (&editor->location, real_location);
680 }
681 else
682 {
683 should_notify = g_set_object (&editor->location, location);
684 }
685
686 if (editor->query == NULL)
687 {
688 create_query (editor);
689 }
690 nautilus_query_set_location (editor->query, editor->location);
691
692 update_fts_sensitivity (editor);
693
694 if (should_notify)
695 {
696 g_object_notify (G_OBJECT (editor), "location");
697 }
698 }
699
700 void
nautilus_query_editor_set_query(NautilusQueryEditor * self,NautilusQuery * query)701 nautilus_query_editor_set_query (NautilusQueryEditor *self,
702 NautilusQuery *query)
703 {
704 g_autofree char *text = NULL;
705 g_autofree char *current_text = NULL;
706
707 g_return_if_fail (NAUTILUS_IS_QUERY_EDITOR (self));
708
709 if (query != NULL)
710 {
711 text = nautilus_query_get_text (query);
712 }
713
714 if (!text)
715 {
716 text = g_strdup ("");
717 }
718
719 self->change_frozen = TRUE;
720
721 current_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->entry)));
722 current_text = g_strstrip (current_text);
723 if (!g_str_equal (current_text, text))
724 {
725 gtk_entry_set_text (GTK_ENTRY (self->entry), text);
726 }
727
728 if (g_set_object (&self->query, query))
729 {
730 g_object_notify (G_OBJECT (self), "query");
731 }
732
733 self->change_frozen = FALSE;
734 }
735
736 void
nautilus_query_editor_set_text(NautilusQueryEditor * self,const gchar * text)737 nautilus_query_editor_set_text (NautilusQueryEditor *self,
738 const gchar *text)
739 {
740 g_return_if_fail (NAUTILUS_IS_QUERY_EDITOR (self));
741 g_return_if_fail (text != NULL);
742
743 /* The handler of the entry will take care of everything */
744 gtk_entry_set_text (GTK_ENTRY (self->entry), text);
745 }
746
747 gboolean
nautilus_query_editor_handle_event(NautilusQueryEditor * self,GdkEvent * event)748 nautilus_query_editor_handle_event (NautilusQueryEditor *self,
749 GdkEvent *event)
750 {
751 g_return_val_if_fail (NAUTILUS_IS_QUERY_EDITOR (self), GDK_EVENT_PROPAGATE);
752 g_return_val_if_fail (event != NULL, GDK_EVENT_PROPAGATE);
753
754 return gtk_search_entry_handle_event (GTK_SEARCH_ENTRY (self->entry), event);
755 }
756