1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
3 * Copyright (C) 2005 Red Hat, Inc.
5 * Nautilus is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * Nautilus is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; see the file COPYING. If not,
17 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: Alexander Larsson <alexl@redhat.com>
25 #include "nautilus-query-editor.h"
28 #include <libnautilus-private/nautilus-marshal.h>
29 #include <glib/gi18n.h>
31 #include <eel/eel-gtk-macros.h>
32 #include <eel/eel-glib-extensions.h>
33 #include <gdk/gdkkeysyms.h>
34 #include <gtk/gtkbindings.h>
35 #include <gtk/gtkbutton.h>
36 #include <gtk/gtkentry.h>
37 #include <gtk/gtkframe.h>
38 #include <gtk/gtkhbox.h>
39 #include <gtk/gtklabel.h>
40 #include <gtk/gtkstock.h>
41 #include <gtk/gtkcombobox.h>
42 #include <gtk/gtkdialog.h>
43 #include "gtk/gtkliststore.h"
44 #include "gtk/gtktreeselection.h"
45 #include "gtk/gtkscrolledwindow.h"
46 #include <gtk/gtkfilechooserbutton.h>
47 #include "gtk/gtkcelllayout.h"
48 #include "gtk/gtkcellrenderertext.h"
51 NAUTILUS_QUERY_EDITOR_ROW_LOCATION
,
52 NAUTILUS_QUERY_EDITOR_ROW_TYPE
,
54 NAUTILUS_QUERY_EDITOR_ROW_LAST
55 } NautilusQueryEditorRowType
;
58 NautilusQueryEditorRowType type
;
59 NautilusQueryEditor
*editor
;
63 GtkWidget
*type_widget
;
66 } NautilusQueryEditorRow
;
71 GtkWidget
* (*create_widgets
) (NautilusQueryEditorRow
*row
);
72 void (*add_to_query
) (NautilusQueryEditorRow
*row
,
73 NautilusQuery
*query
);
74 void (*free_data
) (NautilusQueryEditorRow
*row
);
75 void (*add_rows_from_query
) (NautilusQueryEditor
*editor
,
76 NautilusQuery
*query
);
77 } NautilusQueryEditorRowOps
;
79 struct NautilusQueryEditorDetails
{
82 gboolean change_frozen
;
83 guint typing_timeout_id
;
85 GtkWidget
*invisible_vbox
;
86 GtkWidget
*visible_vbox
;
90 NautilusSearchBar
*bar
;
99 static guint signals
[LAST_SIGNAL
];
101 static void nautilus_query_editor_class_init (NautilusQueryEditorClass
*class);
102 static void nautilus_query_editor_init (NautilusQueryEditor
*editor
);
104 static void entry_activate_cb (GtkWidget
*entry
, NautilusQueryEditor
*editor
);
105 static void entry_changed_cb (GtkWidget
*entry
, NautilusQueryEditor
*editor
);
106 static void nautilus_query_editor_changed_force (NautilusQueryEditor
*editor
,
108 static void nautilus_query_editor_changed (NautilusQueryEditor
*editor
);
109 static NautilusQueryEditorRow
* nautilus_query_editor_add_row (NautilusQueryEditor
*editor
,
110 NautilusQueryEditorRowType type
);
112 static GtkWidget
*location_row_create_widgets (NautilusQueryEditorRow
*row
);
113 static void location_row_add_to_query (NautilusQueryEditorRow
*row
,
114 NautilusQuery
*query
);
115 static void location_row_free_data (NautilusQueryEditorRow
*row
);
116 static void location_add_rows_from_query (NautilusQueryEditor
*editor
,
117 NautilusQuery
*query
);
118 static GtkWidget
*type_row_create_widgets (NautilusQueryEditorRow
*row
);
119 static void type_row_add_to_query (NautilusQueryEditorRow
*row
,
120 NautilusQuery
*query
);
121 static void type_row_free_data (NautilusQueryEditorRow
*row
);
122 static void type_add_rows_from_query (NautilusQueryEditor
*editor
,
123 NautilusQuery
*query
);
127 static NautilusQueryEditorRowOps row_type
[] = {
129 location_row_create_widgets
,
130 location_row_add_to_query
,
131 location_row_free_data
,
132 location_add_rows_from_query
135 type_row_create_widgets
,
136 type_row_add_to_query
,
138 type_add_rows_from_query
142 EEL_CLASS_BOILERPLATE (NautilusQueryEditor
,
143 nautilus_query_editor
,
147 nautilus_query_editor_finalize (GObject
*object
)
149 NautilusQueryEditor
*editor
;
151 editor
= NAUTILUS_QUERY_EDITOR (object
);
153 g_free (editor
->details
);
155 EEL_CALL_PARENT (G_OBJECT_CLASS
, finalize
, (object
));
159 nautilus_query_editor_dispose (GObject
*object
)
161 NautilusQueryEditor
*editor
;
163 editor
= NAUTILUS_QUERY_EDITOR (object
);
166 if (editor
->details
->bar
!= NULL
) {
167 g_signal_handlers_disconnect_by_func (editor
->details
->entry
,
170 g_signal_handlers_disconnect_by_func (editor
->details
->entry
,
174 nautilus_search_bar_return_entry (editor
->details
->bar
);
175 eel_remove_weak_pointer (&editor
->details
->bar
);
178 EEL_CALL_PARENT (G_OBJECT_CLASS
, dispose
, (object
));
182 nautilus_query_editor_class_init (NautilusQueryEditorClass
*class)
184 GObjectClass
*gobject_class
;
185 GtkBindingSet
*binding_set
;
187 gobject_class
= G_OBJECT_CLASS (class);
188 gobject_class
->finalize
= nautilus_query_editor_finalize
;
189 gobject_class
->dispose
= nautilus_query_editor_dispose
;
192 g_signal_new ("changed",
193 G_TYPE_FROM_CLASS (class),
195 G_STRUCT_OFFSET (NautilusQueryEditorClass
, changed
),
197 nautilus_marshal_VOID__OBJECT_BOOLEAN
,
198 G_TYPE_NONE
, 2, NAUTILUS_TYPE_QUERY
, G_TYPE_BOOLEAN
);
201 g_signal_new ("cancel",
202 G_TYPE_FROM_CLASS (class),
203 G_SIGNAL_RUN_LAST
| G_SIGNAL_ACTION
,
204 G_STRUCT_OFFSET (NautilusQueryEditorClass
, cancel
),
206 g_cclosure_marshal_VOID__VOID
,
209 binding_set
= gtk_binding_set_by_class (class);
210 gtk_binding_entry_add_signal (binding_set
, GDK_Escape
, 0, "cancel", 0);
214 entry_activate_cb (GtkWidget
*entry
, NautilusQueryEditor
*editor
)
216 if (editor
->details
->typing_timeout_id
) {
217 g_source_remove (editor
->details
->typing_timeout_id
);
218 editor
->details
->typing_timeout_id
= 0;
221 nautilus_query_editor_changed_force (editor
, TRUE
);
225 typing_timeout_cb (gpointer user_data
)
227 NautilusQueryEditor
*editor
;
229 editor
= NAUTILUS_QUERY_EDITOR (user_data
);
231 nautilus_query_editor_changed (editor
);
233 editor
->details
->typing_timeout_id
= 0;
238 #define TYPING_TIMEOUT 750
241 entry_changed_cb (GtkWidget
*entry
, NautilusQueryEditor
*editor
)
243 if (editor
->details
->change_frozen
) {
247 if (editor
->details
->typing_timeout_id
) {
248 g_source_remove (editor
->details
->typing_timeout_id
);
251 editor
->details
->typing_timeout_id
=
252 g_timeout_add (TYPING_TIMEOUT
,
258 edit_clicked (GtkButton
*button
, NautilusQueryEditor
*editor
)
260 nautilus_query_editor_set_visible (editor
, TRUE
);
261 nautilus_query_editor_grab_focus (editor
);
267 location_row_create_widgets (NautilusQueryEditorRow
*row
)
271 chooser
= gtk_file_chooser_button_new (_("Select folder to search in"),
272 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
);
273 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser
), TRUE
);
274 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser
),
276 gtk_widget_show (chooser
);
278 g_signal_connect_swapped (chooser
, "current-folder-changed",
279 G_CALLBACK (nautilus_query_editor_changed
),
282 gtk_box_pack_start (GTK_BOX (row
->hbox
), chooser
, FALSE
, FALSE
, 0);
288 location_row_add_to_query (NautilusQueryEditorRow
*row
,
289 NautilusQuery
*query
)
293 folder
= gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (row
->type_widget
));
294 if (folder
== NULL
) {
295 /* I don't know why, but i got NULL here on initial search in browser mode
296 even with the location set to the homedir in create_widgets... */
297 folder
= g_strdup (g_get_home_dir ());
300 uri
= g_filename_to_uri (folder
, NULL
, NULL
);
303 nautilus_query_set_location (query
, uri
);
308 location_row_free_data (NautilusQueryEditorRow
*row
)
313 location_add_rows_from_query (NautilusQueryEditor
*editor
,
314 NautilusQuery
*query
)
316 NautilusQueryEditorRow
*row
;
319 uri
= nautilus_query_get_location (query
);
324 folder
= g_filename_from_uri (uri
, NULL
, NULL
);
326 if (folder
== NULL
) {
330 row
= nautilus_query_editor_add_row (editor
,
331 NAUTILUS_QUERY_EDITOR_ROW_LOCATION
);
332 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (row
->type_widget
),
342 type_separator_func (GtkTreeModel
*model
,
349 gtk_tree_model_get (model
, iter
, 0, &text
, -1);
351 res
= text
!= NULL
&& strcmp (text
, "---") == 0;
360 } mime_type_groups
[] = {
363 "application/msword",
364 "application/vnd.sun.xml.writer",
365 "application/vnd.sun.xml.writer.global",
366 "application/vnd.sun.xml.writer.template",
367 "application/vnd.oasis.opendocument.text",
368 "application/vnd.oasis.opendocument.text-template",
369 "application/x-abiword",
370 "application/x-applix-word",
371 "application/x-mswrite",
372 "application/docbook+xml",
373 "application/x-kword",
374 "application/x-kword-crypt",
389 "audio/x-pn-realaudio",
405 "video/x-real-video",
410 { "application/vnd.oasis.opendocument.image",
411 "application/x-krita",
420 "image/x-compressed-xcf",
429 { N_("Illustration"),
430 { "application/illustrator",
431 "application/vnd.corel-draw",
432 "application/vnd.stardivision.draw",
433 "application/vnd.oasis.opendocument.graphics",
434 "application/x-dia-diagram",
435 "application/x-karbon",
436 "application/x-killustrator",
437 "application/x-kivio",
438 "application/x-kontour",
444 { "application/vnd.lotus-1-2-3",
445 "application/vnd.ms-excel",
446 "application/vnd.stardivision.calc",
447 "application/vnd.sun.xml.calc",
448 "application/vnd.oasis.opendocument.spreadsheet",
449 "application/x-applix-spreadsheet",
450 "application/x-gnumeric",
451 "application/x-kspread",
452 "application/x-kspread-crypt",
453 "application/x-quattropro",
455 "application/x-siag",
459 { N_("Presentation"),
460 { "application/vnd.ms-powerpoint",
461 "application/vnd.sun.xml.impress",
462 "application/vnd.oasis.opendocument.presentation",
463 "application/x-magicpoint",
464 "application/x-kpresenter",
468 { N_("Pdf / Postscript"),
470 "application/postscript",
484 type_add_custom_type (NautilusQueryEditorRow
*row
,
485 const char *mime_type
,
486 const char *description
,
492 model
= gtk_combo_box_get_model (GTK_COMBO_BOX (row
->type_widget
));
493 store
= GTK_LIST_STORE (model
);
495 gtk_list_store_append (store
, iter
);
496 gtk_list_store_set (store
, iter
,
504 type_combo_changed (GtkComboBox
*combo_box
, NautilusQueryEditorRow
*row
)
510 if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (row
->type_widget
),
515 model
= gtk_combo_box_get_model (GTK_COMBO_BOX (row
->type_widget
));
516 gtk_tree_model_get (model
, &iter
, 3, &other
, -1);
519 GList
*mime_infos
, *l
;
521 GtkWidget
*scrolled
, *treeview
;
523 GtkTreeViewColumn
*column
;
524 GtkCellRenderer
*renderer
;
526 GtkTreeSelection
*selection
;
528 mime_infos
= g_content_types_get_registered ();
530 store
= gtk_list_store_new (2, G_TYPE_STRING
, G_TYPE_STRING
);
531 for (l
= mime_infos
; l
!= NULL
; l
= l
->next
) {
533 char *mime_type
= l
->data
;
536 description
= g_content_type_get_description (mime_type
);
537 if (description
== NULL
) {
538 description
= g_strdup (mime_type
);
541 gtk_list_store_append (store
, &iter
);
542 gtk_list_store_set (store
, &iter
,
548 g_free (description
);
550 g_list_free (mime_infos
);
554 toplevel
= gtk_widget_get_toplevel (GTK_WIDGET (combo_box
));
555 dialog
= gtk_dialog_new_with_buttons (_("Select type"),
556 GTK_WINDOW (toplevel
),
557 GTK_DIALOG_NO_SEPARATOR
,
558 GTK_STOCK_OK
, GTK_RESPONSE_OK
,
560 gtk_window_set_default_size (GTK_WINDOW (dialog
), 400, 600);
562 scrolled
= gtk_scrolled_window_new (NULL
, NULL
);
563 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled
),
564 GTK_POLICY_AUTOMATIC
,
565 GTK_POLICY_AUTOMATIC
);
566 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled
),
569 gtk_widget_show (scrolled
);
570 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog
)->vbox
), scrolled
, TRUE
, TRUE
, 6);
572 treeview
= gtk_tree_view_new ();
573 gtk_tree_view_set_model (GTK_TREE_VIEW (treeview
),
574 GTK_TREE_MODEL (store
));
575 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store
), 0,
578 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview
));
579 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_BROWSE
);
582 renderer
= gtk_cell_renderer_text_new ();
583 column
= gtk_tree_view_column_new_with_attributes ("Name",
588 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview
), column
);
589 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview
), FALSE
);
591 gtk_widget_show (treeview
);
592 gtk_container_add (GTK_CONTAINER (scrolled
), treeview
);
594 if (gtk_dialog_run (GTK_DIALOG (dialog
)) == GTK_RESPONSE_OK
) {
595 char *mimetype
, *description
;
597 gtk_tree_selection_get_selected (selection
, NULL
, &iter
);
598 gtk_tree_model_get (GTK_TREE_MODEL (store
), &iter
,
603 type_add_custom_type (row
, mimetype
, description
, &iter
);
604 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (row
->type_widget
),
607 gtk_combo_box_set_active (GTK_COMBO_BOX (row
->type_widget
), 0);
610 gtk_widget_destroy (dialog
);
613 nautilus_query_editor_changed (row
->editor
);
617 type_row_create_widgets (NautilusQueryEditorRow
*row
)
620 GtkCellRenderer
*cell
;
625 store
= gtk_list_store_new (4, G_TYPE_STRING
, G_TYPE_POINTER
, G_TYPE_STRING
, G_TYPE_BOOLEAN
);
626 combo
= gtk_combo_box_new_with_model (GTK_TREE_MODEL (store
));
627 g_object_unref (store
);
629 cell
= gtk_cell_renderer_text_new ();
630 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo
), cell
, TRUE
);
631 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo
), cell
,
634 gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo
),
638 gtk_list_store_append (store
, &iter
);
639 gtk_list_store_set (store
, &iter
, 0, _("Any"), -1);
640 gtk_list_store_append (store
, &iter
);
641 gtk_list_store_set (store
, &iter
, 0, "---", -1);
643 for (i
= 0; i
< G_N_ELEMENTS (mime_type_groups
); i
++) {
644 gtk_list_store_append (store
, &iter
);
645 gtk_list_store_set (store
, &iter
,
646 0, gettext (mime_type_groups
[i
].name
),
647 1, mime_type_groups
[i
].mimetypes
,
651 gtk_list_store_append (store
, &iter
);
652 gtk_list_store_set (store
, &iter
, 0, "---", -1);
653 gtk_list_store_append (store
, &iter
);
654 gtk_list_store_set (store
, &iter
, 0, _("Other Type..."), 3, TRUE
, -1);
656 gtk_combo_box_set_active (GTK_COMBO_BOX (combo
), 0);
658 g_signal_connect (combo
, "changed",
659 G_CALLBACK (type_combo_changed
),
662 gtk_widget_show (combo
);
664 gtk_box_pack_start (GTK_BOX (row
->hbox
), combo
, FALSE
, FALSE
, 0);
670 type_row_add_to_query (NautilusQueryEditorRow
*row
,
671 NautilusQuery
*query
)
678 if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (row
->type_widget
),
683 model
= gtk_combo_box_get_model (GTK_COMBO_BOX (row
->type_widget
));
684 gtk_tree_model_get (model
, &iter
, 1, &mimetypes
, 2, &mimetype
, -1);
686 if (mimetypes
!= NULL
) {
687 while (*mimetypes
!= NULL
) {
688 nautilus_query_add_mime_type (query
, *mimetypes
);
693 nautilus_query_add_mime_type (query
, mimetype
);
699 type_row_free_data (NautilusQueryEditorRow
*row
)
704 all_group_types_in_list (char **group_types
, GList
*mime_types
)
711 group_type
= group_types
;
712 while (*group_type
!= NULL
) {
715 for (l
= mime_types
; l
!= NULL
; l
= l
->next
) {
718 if (strcmp (mime_type
, *group_type
) == 0) {
733 remove_group_types_from_list (char **group_types
, GList
*mime_types
)
740 group_type
= group_types
;
741 while (*group_type
!= NULL
) {
744 for (l
= mime_types
; l
!= NULL
; l
= next
) {
748 if (strcmp (mime_type
, *group_type
) == 0) {
749 mime_types
= g_list_remove_link (mime_types
, l
);
762 type_add_rows_from_query (NautilusQueryEditor
*editor
,
763 NautilusQuery
*query
)
768 NautilusQueryEditorRow
*row
;
774 mime_types
= nautilus_query_get_mime_types (query
);
776 if (mime_types
== NULL
) {
780 for (i
= 0; i
< G_N_ELEMENTS (mime_type_groups
); i
++) {
781 if (all_group_types_in_list (mime_type_groups
[i
].mimetypes
,
783 mime_types
= remove_group_types_from_list (mime_type_groups
[i
].mimetypes
,
786 row
= nautilus_query_editor_add_row (editor
,
787 NAUTILUS_QUERY_EDITOR_ROW_TYPE
);
789 model
= gtk_combo_box_get_model (GTK_COMBO_BOX (row
->type_widget
));
791 gtk_tree_model_iter_nth_child (model
, &iter
, NULL
, i
+ 2);
792 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (row
->type_widget
),
797 for (l
= mime_types
; l
!= NULL
; l
= l
->next
) {
800 desc
= g_content_type_get_description (mime_type
);
805 row
= nautilus_query_editor_add_row (editor
,
806 NAUTILUS_QUERY_EDITOR_ROW_TYPE
);
807 model
= gtk_combo_box_get_model (GTK_COMBO_BOX (row
->type_widget
));
809 type_add_custom_type (row
, mime_type
, desc
, &iter
);
810 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (row
->type_widget
),
814 eel_g_list_free_deep (mime_types
);
818 /* End of row types */
820 static NautilusQueryEditorRowType
821 get_next_free_type (NautilusQueryEditor
*editor
)
823 NautilusQueryEditorRow
*row
;
824 NautilusQueryEditorRowType type
;
829 for (type
= 0; type
< NAUTILUS_QUERY_EDITOR_ROW_LAST
; type
++) {
831 for (l
= editor
->details
->rows
; l
!= NULL
; l
= l
->next
) {
833 if (row
->type
== type
) {
842 return NAUTILUS_QUERY_EDITOR_ROW_TYPE
;
846 remove_row_cb (GtkButton
*clicked_button
, NautilusQueryEditorRow
*row
)
848 NautilusQueryEditor
*editor
;
850 editor
= row
->editor
;
851 gtk_container_remove (GTK_CONTAINER (editor
->details
->visible_vbox
),
854 editor
->details
->rows
= g_list_remove (editor
->details
->rows
, row
);
856 row_type
[row
->type
].free_data (row
);
859 nautilus_query_editor_changed (editor
);
863 create_type_widgets (NautilusQueryEditorRow
*row
)
865 row
->type_widget
= row_type
[row
->type
].create_widgets (row
);
869 row_type_combo_changed_cb (GtkComboBox
*combo_box
, NautilusQueryEditorRow
*row
)
871 NautilusQueryEditorRowType type
;
873 type
= gtk_combo_box_get_active (combo_box
);
875 if (type
== row
->type
) {
879 if (row
->type_widget
!= NULL
) {
880 gtk_widget_destroy (row
->type_widget
);
881 row
->type_widget
= NULL
;
884 row_type
[row
->type
].free_data (row
);
889 create_type_widgets (row
);
891 nautilus_query_editor_changed (row
->editor
);
894 static NautilusQueryEditorRow
*
895 nautilus_query_editor_add_row (NautilusQueryEditor
*editor
,
896 NautilusQueryEditorRowType type
)
898 GtkWidget
*hbox
, *button
, *image
, *combo
;
899 NautilusQueryEditorRow
*row
;
902 row
= g_new0 (NautilusQueryEditorRow
, 1);
903 row
->editor
= editor
;
906 hbox
= gtk_hbox_new (FALSE
, 6);
908 gtk_widget_show (hbox
);
909 gtk_box_pack_start (GTK_BOX (editor
->details
->visible_vbox
), hbox
, FALSE
, FALSE
, 0);
911 combo
= gtk_combo_box_new_text ();
913 for (i
= 0; i
< NAUTILUS_QUERY_EDITOR_ROW_LAST
; i
++) {
914 gtk_combo_box_append_text (GTK_COMBO_BOX (combo
), gettext (row_type
[i
].name
));
916 gtk_widget_show (combo
);
917 gtk_box_pack_start (GTK_BOX (hbox
), combo
, FALSE
, FALSE
, 0);
919 gtk_combo_box_set_active (GTK_COMBO_BOX (combo
), row
->type
);
921 editor
->details
->rows
= g_list_append (editor
->details
->rows
, row
);
923 g_signal_connect (combo
, "changed",
924 G_CALLBACK (row_type_combo_changed_cb
), row
);
926 create_type_widgets (row
);
928 button
= gtk_button_new ();
929 image
= gtk_image_new_from_stock (GTK_STOCK_REMOVE
,
930 GTK_ICON_SIZE_SMALL_TOOLBAR
);
931 gtk_container_add (GTK_CONTAINER (button
), image
);
932 gtk_widget_show (image
);
933 gtk_button_set_relief (GTK_BUTTON (button
), GTK_RELIEF_NONE
);
934 gtk_widget_show (button
);
936 g_signal_connect (button
, "clicked",
937 G_CALLBACK (remove_row_cb
), row
);
938 gtk_widget_set_tooltip_text (button
,
939 _("Remove this criterion from the search"));
941 gtk_box_pack_end (GTK_BOX (hbox
), button
, FALSE
, FALSE
, 0);
947 go_search_cb (GtkButton
*clicked_button
, NautilusQueryEditor
*editor
)
949 nautilus_query_editor_changed_force (editor
, TRUE
);
953 add_new_row_cb (GtkButton
*clicked_button
, NautilusQueryEditor
*editor
)
955 nautilus_query_editor_add_row (editor
, get_next_free_type (editor
));
956 nautilus_query_editor_changed (editor
);
960 nautilus_query_editor_init (NautilusQueryEditor
*editor
)
962 GtkWidget
*hbox
, *label
, *button
;
965 editor
->details
= g_new0 (NautilusQueryEditorDetails
, 1);
966 editor
->details
->is_visible
= TRUE
;
968 editor
->details
->invisible_vbox
= gtk_vbox_new (FALSE
, 6);
969 gtk_box_pack_start (GTK_BOX (editor
), editor
->details
->invisible_vbox
,
971 editor
->details
->visible_vbox
= gtk_vbox_new (FALSE
, 6);
972 gtk_box_pack_start (GTK_BOX (editor
), editor
->details
->visible_vbox
,
974 /* Only show visible vbox */
975 gtk_widget_show (editor
->details
->visible_vbox
);
977 /* Create invisible part: */
978 hbox
= gtk_hbox_new (FALSE
, 6);
979 gtk_box_pack_start (GTK_BOX (editor
->details
->invisible_vbox
),
980 hbox
, FALSE
, FALSE
, 0);
981 gtk_widget_show (hbox
);
983 label
= gtk_label_new ("");
984 label_markup
= g_strconcat ("<b>", _("Search Folder"), "</b>", NULL
);
985 gtk_label_set_markup (GTK_LABEL (label
), label_markup
);
986 g_free (label_markup
);
987 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
988 gtk_widget_show (label
);
990 button
= gtk_button_new_with_label (_("Edit"));
991 gtk_box_pack_end (GTK_BOX (hbox
), button
, FALSE
, FALSE
, 0);
992 gtk_widget_show (button
);
994 g_signal_connect (button
, "clicked",
995 G_CALLBACK (edit_clicked
), editor
);
997 gtk_widget_set_tooltip_text (button
,
998 _("Edit the saved search"));
1002 nautilus_query_editor_set_default_query (NautilusQueryEditor
*editor
)
1004 if (!editor
->details
->is_indexed
) {
1005 nautilus_query_editor_add_row (editor
, NAUTILUS_QUERY_EDITOR_ROW_LOCATION
);
1006 nautilus_query_editor_changed (editor
);
1011 finish_first_line (NautilusQueryEditor
*editor
, GtkWidget
*hbox
, gboolean use_go
)
1013 GtkWidget
*button
, *image
;
1015 button
= gtk_button_new ();
1016 image
= gtk_image_new_from_stock (GTK_STOCK_ADD
,
1017 GTK_ICON_SIZE_SMALL_TOOLBAR
);
1018 gtk_container_add (GTK_CONTAINER (button
), image
);
1019 gtk_widget_show (image
);
1020 gtk_button_set_relief (GTK_BUTTON (button
), GTK_RELIEF_NONE
);
1021 gtk_widget_show (button
);
1023 g_signal_connect (button
, "clicked",
1024 G_CALLBACK (add_new_row_cb
), editor
);
1026 gtk_box_pack_end (GTK_BOX (hbox
), button
, FALSE
, FALSE
, 0);
1028 gtk_widget_set_tooltip_text (button
,
1029 _("Add a new criterion to this search"));
1031 if (!editor
->details
->is_indexed
) {
1033 button
= gtk_button_new_with_label (_("Go"));
1035 button
= gtk_button_new_with_label (_("Reload"));
1037 gtk_widget_show (button
);
1039 gtk_widget_set_tooltip_text (button
,
1040 _("Perform or update the search"));
1042 g_signal_connect (button
, "clicked",
1043 G_CALLBACK (go_search_cb
), editor
);
1045 gtk_box_pack_end (GTK_BOX (hbox
), button
, FALSE
, FALSE
, 0);
1050 setup_internal_entry (NautilusQueryEditor
*editor
)
1052 GtkWidget
*hbox
, *label
;
1055 /* Create visible part: */
1056 hbox
= gtk_hbox_new (FALSE
, 6);
1057 gtk_widget_show (hbox
);
1058 gtk_box_pack_start (GTK_BOX (editor
->details
->visible_vbox
), hbox
, FALSE
, FALSE
, 0);
1060 label
= gtk_label_new ("");
1061 label_markup
= g_strconcat ("<b>", _("_Search for:"), "</b>", NULL
);
1062 gtk_label_set_markup_with_mnemonic (GTK_LABEL (label
), label_markup
);
1063 g_free (label_markup
);
1064 gtk_widget_show (label
);
1065 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
1067 editor
->details
->entry
= gtk_entry_new ();
1068 gtk_label_set_mnemonic_widget (GTK_LABEL (label
), editor
->details
->entry
);
1069 gtk_box_pack_start (GTK_BOX (hbox
), editor
->details
->entry
, TRUE
, TRUE
, 0);
1071 g_signal_connect (editor
->details
->entry
, "activate",
1072 G_CALLBACK (entry_activate_cb
), editor
);
1073 g_signal_connect (editor
->details
->entry
, "changed",
1074 G_CALLBACK (entry_changed_cb
), editor
);
1075 gtk_widget_show (editor
->details
->entry
);
1077 finish_first_line (editor
, hbox
, TRUE
);
1081 setup_external_entry (NautilusQueryEditor
*editor
, GtkWidget
*entry
)
1083 GtkWidget
*hbox
, *label
;
1085 /* Create visible part: */
1086 hbox
= gtk_hbox_new (FALSE
, 6);
1087 gtk_widget_show (hbox
);
1088 gtk_box_pack_start (GTK_BOX (editor
->details
->visible_vbox
), hbox
, FALSE
, FALSE
, 0);
1090 label
= gtk_label_new (_("Search results"));
1091 gtk_widget_show (label
);
1092 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
1094 editor
->details
->entry
= entry
;
1095 g_signal_connect (editor
->details
->entry
, "activate",
1096 G_CALLBACK (entry_activate_cb
), editor
);
1097 g_signal_connect (editor
->details
->entry
, "changed",
1098 G_CALLBACK (entry_changed_cb
), editor
);
1100 finish_first_line (editor
, hbox
, FALSE
);
1105 nautilus_query_editor_set_visible (NautilusQueryEditor
*editor
,
1108 editor
->details
->is_visible
= visible
;
1110 gtk_widget_show (editor
->details
->visible_vbox
);
1111 gtk_widget_hide (editor
->details
->invisible_vbox
);
1113 gtk_widget_hide (editor
->details
->visible_vbox
);
1114 gtk_widget_show (editor
->details
->invisible_vbox
);
1119 query_is_valid (NautilusQueryEditor
*editor
)
1123 text
= gtk_entry_get_text (GTK_ENTRY (editor
->details
->entry
));
1125 return text
!= NULL
&& text
[0] != '\0';
1129 nautilus_query_editor_changed_force (NautilusQueryEditor
*editor
, gboolean force_reload
)
1131 NautilusQuery
*query
;
1133 if (editor
->details
->change_frozen
) {
1137 if (query_is_valid (editor
)) {
1138 query
= nautilus_query_editor_get_query (editor
);
1139 g_signal_emit (editor
, signals
[CHANGED
], 0,
1140 query
, editor
->details
->is_indexed
|| force_reload
);
1141 g_object_unref (query
);
1146 nautilus_query_editor_changed (NautilusQueryEditor
*editor
)
1148 nautilus_query_editor_changed_force (editor
, FALSE
);
1152 nautilus_query_editor_grab_focus (NautilusQueryEditor
*editor
)
1154 if (editor
->details
->is_visible
) {
1155 gtk_widget_grab_focus (editor
->details
->entry
);
1160 nautilus_query_editor_get_query (NautilusQueryEditor
*editor
)
1162 const char *query_text
;
1163 NautilusQuery
*query
;
1165 NautilusQueryEditorRow
*row
;
1167 query_text
= gtk_entry_get_text (GTK_ENTRY (editor
->details
->entry
));
1169 /* Empty string is a NULL query */
1170 if (query_text
&& query_text
[0] == '\0') {
1174 query
= nautilus_query_new ();
1175 nautilus_query_set_text (query
, query_text
);
1177 for (l
= editor
->details
->rows
; l
!= NULL
; l
= l
->next
) {
1180 row_type
[row
->type
].add_to_query (row
, query
);
1187 nautilus_query_editor_clear_query (NautilusQueryEditor
*editor
)
1189 editor
->details
->change_frozen
= TRUE
;
1190 gtk_entry_set_text (GTK_ENTRY (editor
->details
->entry
), "");
1191 editor
->details
->change_frozen
= FALSE
;
1195 nautilus_query_editor_new (gboolean start_hidden
, gboolean is_indexed
)
1199 editor
= g_object_new (NAUTILUS_TYPE_QUERY_EDITOR
, NULL
);
1201 NAUTILUS_QUERY_EDITOR (editor
)->details
->is_indexed
= is_indexed
;
1203 nautilus_query_editor_set_visible (NAUTILUS_QUERY_EDITOR (editor
),
1206 setup_internal_entry (NAUTILUS_QUERY_EDITOR (editor
));
1212 nautilus_query_editor_new_with_bar (gboolean start_hidden
,
1213 gboolean is_indexed
,
1214 NautilusSearchBar
*bar
)
1217 NautilusQueryEditor
*editor
;
1219 editor
= NAUTILUS_QUERY_EDITOR (g_object_new (NAUTILUS_TYPE_QUERY_EDITOR
, NULL
));
1220 editor
->details
->is_indexed
= is_indexed
;
1222 nautilus_query_editor_set_visible (editor
, !start_hidden
);
1224 editor
->details
->bar
= bar
;
1225 eel_add_weak_pointer (&editor
->details
->bar
);
1227 entry
= nautilus_search_bar_borrow_entry (bar
);
1228 setup_external_entry (editor
, entry
);
1230 return GTK_WIDGET (editor
);
1234 nautilus_query_editor_set_query (NautilusQueryEditor
*editor
, NautilusQuery
*query
)
1236 NautilusQueryEditorRowType type
;
1240 nautilus_query_editor_clear_query (editor
);
1244 text
= nautilus_query_get_text (query
);
1249 editor
->details
->change_frozen
= TRUE
;
1250 gtk_entry_set_text (GTK_ENTRY (editor
->details
->entry
), text
);
1252 for (type
= 0; type
< NAUTILUS_QUERY_EDITOR_ROW_LAST
; type
++) {
1253 row_type
[type
].add_rows_from_query (editor
, query
);
1256 editor
->details
->change_frozen
= FALSE
;