Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:dliang
nautilus
nautilus-search-20060510.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File nautilus-search-20060510.patch of Package nautilus
diff -ruNp nautilus-2.12.2/configure.in nautilus-2.12.2.joe/configure.in --- nautilus-2.12.2/configure.in 2005-10-27 09:25:42.000000000 +0200 +++ nautilus-2.12.2.joe/configure.in 2006-04-14 23:06:09.498296245 +0200 @@ -19,6 +19,7 @@ m4_define(rsvg_minver, 2 m4_define(xml_minver, 2.4.7) m4_define(startup_notification_minver, 0.8) m4_define(exif_minver, 0.5.12) +m4_define(beagle_minver, 0.2.1) AC_INIT(nautilus, 2.12.2, [http://bugzilla.gnome.org/enter_bug.cgi?product=nautilus]) @@ -224,6 +225,20 @@ PKG_CHECK_MODULES(EXIF, libexif > exif_m AC_SUBST(EXIF_LIBS) ])]) + +dnl ========================================================================== + +dnl libbeagle checking + +AC_MSG_CHECKING(for libbeagle) + +PKG_CHECK_MODULES(BEAGLE, libbeagle-0.0 >= beagle_minver, [ + AC_DEFINE(HAVE_BEAGLE, 1, [Define to enable beagle support]) + AC_SUBST(BEAGLE_CFLAGS) + AC_SUBST(BEAGLE_LIBS) + AM_CONDITIONAL(HAVE_BEAGLE, true) +], []) + dnl ========================================================================== dnl Turn on the additional warnings last, so -Werror doesn't affect other tests. diff -ruNp nautilus-2.12.2/libnautilus-private/Makefile.am nautilus-2.12.2.joe/libnautilus-private/Makefile.am --- nautilus-2.12.2/libnautilus-private/Makefile.am 2005-10-27 09:25:52.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/Makefile.am 2006-04-14 23:02:12.103563232 +0200 @@ -11,6 +11,7 @@ INCLUDES = \ -I$(top_srcdir)/cut-n-paste-code \ $(CORE_CFLAGS) \ $(DISABLE_DEPRECATED_CFLAGS) \ + $(BEAGLE_CFLAGS) \ -DDATADIR=\""$(datadir)"\" \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ -DNAUTILUS_DATADIR=\""$(datadir)/nautilus"\" \ @@ -28,6 +29,7 @@ libnautilus_private_la_LDFLAGS = \ -no-undefined \ $(dependency_static_libs) \ $(CORE_LIBS) \ + $(BEAGLE_LIBS) \ $(NULL) nautilus_metafile_server_idl_sources = \ @@ -151,10 +153,18 @@ libnautilus_private_la_SOURCES = \ nautilus-program-choosing.h \ nautilus-recent.c \ nautilus-recent.h \ + nautilus-search-directory.c \ + nautilus-search-directory.h \ + nautilus-search-directory-file.c \ + nautilus-search-directory-file.h \ + nautilus-search-engine.c \ + nautilus-search-engine.h \ nautilus-sidebar-provider.c \ nautilus-sidebar-provider.h \ nautilus-sidebar.c \ nautilus-sidebar.h \ + nautilus-query.c \ + nautilus-query.h \ nautilus-thumbnails.c \ nautilus-thumbnails.h \ nautilus-trash-directory.c \ @@ -188,6 +198,12 @@ libnautilus_private_la_SOURCES = \ nautilus-window-info.h \ $(NULL) +if HAVE_BEAGLE +libnautilus_private_la_SOURCES += \ + nautilus-search-engine-beagle.c + nautilus-search-engine-beagle.h +endif + $(lib_LTLIBRARIES): $(dependency_static_libs) $(nautilus_metafile_server_idl_sources): nautilus_metafile_server_idl_stamp diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-directory-async.c nautilus-2.12.2.joe/libnautilus-private/nautilus-directory-async.c --- nautilus-2.12.2/libnautilus-private/nautilus-directory-async.c 2005-09-06 17:12:46.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-directory-async.c 2006-04-14 23:02:12.121560104 +0200 @@ -1002,7 +1002,7 @@ directory_load_done (NautilusDirectory * } nautilus_directory_emit_load_error (directory, - result); + result, NULL); } /* Call the idle function right away. */ diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-directory.c nautilus-2.12.2.joe/libnautilus-private/nautilus-directory.c --- nautilus-2.12.2/libnautilus-private/nautilus-directory.c 2005-01-13 14:27:50.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-directory.c 2006-04-14 23:02:12.136557497 +0200 @@ -30,8 +30,10 @@ #include "nautilus-file-attributes.h" #include "nautilus-file-private.h" #include "nautilus-file-utilities.h" +#include "nautilus-search-directory.h" #include "nautilus-global-preferences.h" #include "nautilus-lib-self-check-functions.h" +#include "nautilus-marshal.h" #include "nautilus-metadata.h" #include "nautilus-metafile.h" #include "nautilus-desktop-directory.h" @@ -71,6 +73,7 @@ static void nautilus_direc static NautilusDirectory *nautilus_directory_new (const char *uri); static char * real_get_name_for_self_as_new_file (NautilusDirectory *directory); static GList * real_get_file_list (NautilusDirectory *directory); +static gboolean real_is_editable (NautilusDirectory *directory); static void set_directory_uri (NautilusDirectory *directory, const char *new_uri); @@ -117,11 +120,12 @@ nautilus_directory_class_init (NautilusD G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (NautilusDirectoryClass, load_error), NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); + nautilus_marshal_VOID__INT_STRING, + G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING); klass->get_name_for_self_as_new_file = real_get_name_for_self_as_new_file; klass->get_file_list = real_get_file_list; + klass->is_editable = real_is_editable; g_type_class_add_private (klass, sizeof (NautilusDirectoryDetails)); } @@ -515,12 +519,17 @@ nautilus_directory_new (const char *uri) directory = NAUTILUS_DIRECTORY (g_object_new (NAUTILUS_TYPE_TRASH_DIRECTORY, NULL)); } else if (eel_uri_is_desktop (uri)) { directory = NAUTILUS_DIRECTORY (g_object_new (NAUTILUS_TYPE_DESKTOP_DIRECTORY, NULL)); + } else if (eel_uri_is_search (uri)) { + directory = NAUTILUS_DIRECTORY (g_object_new (NAUTILUS_TYPE_SEARCH_DIRECTORY, NULL)); } else { directory = NAUTILUS_DIRECTORY (g_object_new (NAUTILUS_TYPE_VFS_DIRECTORY, NULL)); } set_directory_uri (directory, uri); + if (eel_uri_is_search (uri)) + nautilus_search_directory_load_search (NAUTILUS_SEARCH_DIRECTORY (directory)); + return directory; } @@ -764,11 +773,12 @@ nautilus_directory_emit_done_loading (Na void nautilus_directory_emit_load_error (NautilusDirectory *directory, - GnomeVFSResult error_result) + GnomeVFSResult error_result, + const char *error_message) { g_signal_emit (directory, signals[LOAD_ERROR], 0, - error_result); + error_result, error_message); } @@ -1652,6 +1662,20 @@ real_get_file_list (NautilusDirectory *d return non_tentative_files; } +static gboolean +real_is_editable (NautilusDirectory *directory) +{ + return TRUE; +} + +gboolean +nautilus_directory_is_editable (NautilusDirectory *directory) +{ + return EEL_CALL_METHOD_WITH_RETURN_VALUE + (NAUTILUS_DIRECTORY_CLASS, directory, + is_editable, (directory)); +} + GList * nautilus_directory_match_pattern (NautilusDirectory *directory, const char *pattern) { diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-directory.h nautilus-2.12.2.joe/libnautilus-private/nautilus-directory.h --- nautilus-2.12.2/libnautilus-private/nautilus-directory.h 2004-10-11 13:49:00.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-directory.h 2006-04-14 23:02:12.145555933 +0200 @@ -100,7 +100,9 @@ typedef struct */ void (* done_loading) (NautilusDirectory *directory); - void (* load_error) (NautilusDirectory *directory); + void (* load_error) (NautilusDirectory *directory, + GnomeVFSResult error_result, + const char *error_message); /*** Virtual functions for subclasses to override. ***/ gboolean (* contains_file) (NautilusDirectory *directory, @@ -134,6 +136,12 @@ typedef struct * the list of standard icons (Computer, Home, Trash) on the desktop. */ GList * (* get_file_list) (NautilusDirectory *directory); + + /* Should return FALSE if the directory is read-only and doesn't + * allow setting of metadata. + * An example of this is the search directory. + */ + gboolean (* is_editable) (NautilusDirectory *directory); } NautilusDirectoryClass; /* Basic GObject requirements. */ @@ -227,5 +235,7 @@ GList * nautilus_directory_li /* Fast way to check if a directory is the desktop directory */ gboolean nautilus_directory_is_desktop_directory (NautilusDirectory *directory); +gboolean nautilus_directory_is_editable (NautilusDirectory *directory); + #endif /* NAUTILUS_DIRECTORY_H */ diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-directory-metafile.c nautilus-2.12.2.joe/libnautilus-private/nautilus-directory-metafile.c --- nautilus-2.12.2/libnautilus-private/nautilus-directory-metafile.c 2005-10-03 10:28:43.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-directory-metafile.c 2006-04-14 23:02:12.160553326 +0200 @@ -158,8 +158,6 @@ get_metafile (NautilusDirectory *directo g_free (uri); } - g_assert (directory->details->metafile_corba_object != CORBA_OBJECT_NIL); - return directory->details->metafile_corba_object; } @@ -168,12 +166,19 @@ nautilus_directory_is_metadata_read (Nau { CORBA_Environment ev; gboolean result; + Nautilus_Metafile metafile; g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE); CORBA_exception_init (&ev); - result = Nautilus_Metafile_is_read (get_metafile (directory), &ev); + metafile = get_metafile (directory); + + if (metafile == CORBA_OBJECT_NIL) { + return TRUE; + } + + result = Nautilus_Metafile_is_read (metafile, &ev); /* FIXME bugzilla.gnome.org 46664: examine ev for errors */ CORBA_exception_free (&ev); @@ -191,6 +196,7 @@ nautilus_directory_get_file_metadata (Na char *result; const char *non_null_default; CORBA_char *corba_value; + Nautilus_Metafile metafile; g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), g_strdup (default_metadata)); g_return_val_if_fail (!eel_str_is_empty (file_name), g_strdup (default_metadata)); @@ -201,7 +207,13 @@ nautilus_directory_get_file_metadata (Na CORBA_exception_init (&ev); - corba_value = Nautilus_Metafile_get (get_metafile (directory), file_name, key, non_null_default, &ev); + metafile = get_metafile (directory); + + if (metafile == CORBA_OBJECT_NIL) { + return g_strdup (default_metadata); + } + + corba_value = Nautilus_Metafile_get (metafile, file_name, key, non_null_default, &ev); if (ev._major != CORBA_NO_EXCEPTION) { g_warning ("Failed to get file metadata."); @@ -235,16 +247,23 @@ nautilus_directory_get_file_metadata_lis GList *result; Nautilus_MetadataList *corba_value; CORBA_unsigned_long buf_pos; + Nautilus_Metafile metafile; g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL); g_return_val_if_fail (!eel_str_is_empty (file_name), NULL); g_return_val_if_fail (!eel_str_is_empty (list_key), NULL); g_return_val_if_fail (!eel_str_is_empty (list_subkey), NULL); - CORBA_exception_init (&ev); + metafile = get_metafile (directory); - corba_value = Nautilus_Metafile_get_list (get_metafile (directory), file_name, list_key, list_subkey, &ev); + if (metafile == CORBA_OBJECT_NIL) { + return NULL; + } + CORBA_exception_init (&ev); + + corba_value = Nautilus_Metafile_get_list (metafile, file_name, list_key, list_subkey, &ev); + /* FIXME bugzilla.gnome.org 46664: examine ev for errors */ CORBA_exception_free (&ev); @@ -266,11 +285,18 @@ nautilus_directory_set_file_metadata (Na const char *metadata) { CORBA_Environment ev; + Nautilus_Metafile metafile; g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); g_return_if_fail (!eel_str_is_empty (file_name)); g_return_if_fail (!eel_str_is_empty (key)); + metafile = get_metafile (directory); + + if (metafile == CORBA_OBJECT_NIL) { + return; + } + /* We can't pass NULL as a CORBA_string - pass "" instead. */ if (default_metadata == NULL) { @@ -282,7 +308,7 @@ nautilus_directory_set_file_metadata (Na CORBA_exception_init (&ev); - Nautilus_Metafile_set (get_metafile (directory), file_name, key, default_metadata, metadata, &ev); + Nautilus_Metafile_set (metafile, file_name, key, default_metadata, metadata, &ev); /* FIXME bugzilla.gnome.org 46664: examine ev for errors */ CORBA_exception_free (&ev); @@ -296,7 +322,7 @@ nautilus_directory_set_file_metadata_lis GList *list) { CORBA_Environment ev; - + Nautilus_Metafile metafile; Nautilus_MetadataList *corba_list; int len; int buf_pos; @@ -306,7 +332,13 @@ nautilus_directory_set_file_metadata_lis g_return_if_fail (!eel_str_is_empty (file_name)); g_return_if_fail (!eel_str_is_empty (list_key)); g_return_if_fail (!eel_str_is_empty (list_subkey)); - + + metafile = get_metafile (directory); + + if (metafile == CORBA_OBJECT_NIL) { + return; + } + len = g_list_length (list); corba_list = Nautilus_MetadataList__alloc (); @@ -329,7 +361,7 @@ nautilus_directory_set_file_metadata_lis CORBA_exception_init (&ev); - Nautilus_Metafile_set_list (get_metafile (directory), file_name, list_key, list_subkey, corba_list, &ev); + Nautilus_Metafile_set_list (metafile, file_name, list_key, list_subkey, corba_list, &ev); /* FIXME bugzilla.gnome.org 46664: examine ev for errors */ CORBA_exception_free (&ev); @@ -438,17 +470,24 @@ nautilus_directory_copy_file_metadata (N { CORBA_Environment ev; char *destination_uri; + Nautilus_Metafile metafile; g_return_if_fail (NAUTILUS_IS_DIRECTORY (source_directory)); g_return_if_fail (source_file_name != NULL); g_return_if_fail (NAUTILUS_IS_DIRECTORY (destination_directory)); g_return_if_fail (destination_file_name != NULL); - + + metafile = get_metafile (source_directory); + + if (metafile == CORBA_OBJECT_NIL) { + return; + } + destination_uri = nautilus_directory_get_uri (destination_directory); CORBA_exception_init (&ev); - Nautilus_Metafile_copy (get_metafile (source_directory), source_file_name, + Nautilus_Metafile_copy (metafile, source_file_name, destination_uri, destination_file_name, &ev); /* FIXME bugzilla.gnome.org 46664: examine ev for errors */ @@ -462,13 +501,20 @@ nautilus_directory_remove_file_metadata const char *file_name) { CORBA_Environment ev; + Nautilus_Metafile metafile; g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); g_return_if_fail (file_name != NULL); - + + metafile = get_metafile (directory); + + if (metafile == CORBA_OBJECT_NIL) { + return; + } + CORBA_exception_init (&ev); - Nautilus_Metafile_remove (get_metafile (directory), file_name, &ev); + Nautilus_Metafile_remove (metafile, file_name, &ev); /* FIXME bugzilla.gnome.org 46664: examine ev for errors */ CORBA_exception_free (&ev); @@ -480,14 +526,21 @@ nautilus_directory_rename_file_metadata const char *new_file_name) { CORBA_Environment ev; + Nautilus_Metafile metafile; g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); g_return_if_fail (old_file_name != NULL); g_return_if_fail (new_file_name != NULL); - + + metafile = get_metafile (directory); + + if (metafile == CORBA_OBJECT_NIL) { + return; + } + CORBA_exception_init (&ev); - Nautilus_Metafile_rename (get_metafile (directory), old_file_name, new_file_name, &ev); + Nautilus_Metafile_rename (metafile, old_file_name, new_file_name, &ev); /* FIXME bugzilla.gnome.org 46664: examine ev for errors */ CORBA_exception_free (&ev); @@ -498,13 +551,20 @@ nautilus_directory_rename_directory_meta const char *new_directory_uri) { CORBA_Environment ev; + Nautilus_Metafile metafile; g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); g_return_if_fail (new_directory_uri != NULL); - + + metafile = get_metafile (directory); + + if (metafile == CORBA_OBJECT_NIL) { + return; + } + CORBA_exception_init (&ev); - Nautilus_Metafile_rename_directory (get_metafile (directory), new_directory_uri, &ev); + Nautilus_Metafile_rename_directory (metafile, new_directory_uri, &ev); /* FIXME bugzilla.gnome.org 46664: examine ev for errors */ CORBA_exception_free (&ev); @@ -514,6 +574,7 @@ void nautilus_directory_register_metadata_monitor (NautilusDirectory *directory) { CORBA_Environment ev; + Nautilus_Metafile metafile; g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); @@ -522,12 +583,18 @@ nautilus_directory_register_metadata_mon return; } + metafile = get_metafile (directory); + + if (metafile == CORBA_OBJECT_NIL) { + return; + } + directory->details->metafile_monitor = nautilus_metafile_monitor_new (directory); CORBA_exception_init (&ev); Nautilus_Metafile_register_monitor - (get_metafile (directory), + (metafile, BONOBO_OBJREF (directory->details->metafile_monitor), &ev); @@ -539,14 +606,21 @@ void nautilus_directory_unregister_metadata_monitor (NautilusDirectory *directory) { CORBA_Environment ev; + Nautilus_Metafile metafile; g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); g_return_if_fail (NAUTILUS_IS_METAFILE_MONITOR (directory->details->metafile_monitor)); + metafile = get_metafile (directory); + + if (metafile == CORBA_OBJECT_NIL) { + return; + } + CORBA_exception_init (&ev); Nautilus_Metafile_unregister_monitor - (get_metafile (directory), + (metafile, BONOBO_OBJREF (directory->details->metafile_monitor), &ev); diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-directory-private.h nautilus-2.12.2.joe/libnautilus-private/nautilus-directory-private.h --- nautilus-2.12.2/libnautilus-private/nautilus-directory-private.h 2004-11-22 16:24:36.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-directory-private.h 2006-04-14 23:02:12.170551588 +0200 @@ -192,7 +192,8 @@ void nautilus_directory_em void emit_change_signals_for_all_files (NautilusDirectory *directory); void nautilus_directory_emit_done_loading (NautilusDirectory *directory); void nautilus_directory_emit_load_error (NautilusDirectory *directory, - GnomeVFSResult error_result); + GnomeVFSResult error_result, + const char *error_message); NautilusDirectory *nautilus_directory_get_internal (const char *uri, gboolean create); char * nautilus_directory_get_name_for_self_as_new_file (NautilusDirectory *directory); diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-file.c nautilus-2.12.2.joe/libnautilus-private/nautilus-file.c --- nautilus-2.12.2/libnautilus-private/nautilus-file.c 2005-10-27 09:25:52.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-file.c 2006-04-14 23:02:12.198546722 +0200 @@ -40,6 +40,8 @@ #include "nautilus-link-desktop-file.h" #include "nautilus-metadata.h" #include "nautilus-module.h" +#include "nautilus-search-directory.h" +#include "nautilus-search-directory-file.h" #include "nautilus-thumbnails.h" #include "nautilus-trash-directory.h" #include "nautilus-trash-file.h" @@ -72,12 +74,11 @@ /* Time in seconds to cache getpwuid results */ #define GETPWUID_CACHE_TIME (5*60) + #undef NAUTILUS_FILE_DEBUG_REF #ifdef NAUTILUS_FILE_DEBUG_REF -extern void eazel_dump_stack_trace (const char *print_prefix, - int num_levels); -/* from libleakcheck.so */ +#include <valgrind/valgrind.h> #endif /* Files that start with these characters sort after files that don't. */ @@ -195,20 +196,27 @@ nautilus_file_new_from_relative_uri (Nau file = NULL; g_assert_not_reached (); } + } else if (NAUTILUS_IS_SEARCH_DIRECTORY (directory)) { + if (self_owned) { + file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_SEARCH_DIRECTORY_FILE, NULL)); + } else { + file = NULL; + g_assert_not_reached (); + } } else { file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_VFS_FILE, NULL)); } -#ifdef NAUTILUS_FILE_DEBUG_REF - printf("%10p ref'd\n", file); - eazel_dump_stack_trace ("\t", 10); -#endif - nautilus_directory_ref (directory); file->details->directory = directory; file->details->relative_uri = g_strdup (relative_uri); +#ifdef NAUTILUS_FILE_DEBUG_REF + if (strcmp (nautilus_file_get_uri (file), "file:///home/andersca/src/gnome/gtk%2B/gtk/gtkbutton.c") == 0) + VALGRIND_PRINTF_BACKTRACE("%10p ref'd", file); +#endif + return file; } @@ -307,15 +315,17 @@ nautilus_file_new_from_info (NautilusDir file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_VFS_FILE, NULL)); -#ifdef NAUTILUS_FILE_DEBUG_REF - printf("%10p ref'd\n", file); - eazel_dump_stack_trace ("\t", 10); -#endif - nautilus_directory_ref (directory); file->details->directory = directory; update_info_and_name (file, info, FALSE); + + +#ifdef NAUTILUS_FILE_DEBUG_REF + if (strcmp (nautilus_file_get_uri (file), "file:///home/andersca/src/gnome/gtk%2B/gtk/gtkbutton.c") == 0) + VALGRIND_PRINTF_BACKTRACE("%10p ref'd", file); +#endif + return file; } @@ -404,6 +414,13 @@ nautilus_file_get_internal (const char * relative_uri_tmp++; } relative_uri = strdup (relative_uri_tmp); + } else if (eel_uri_is_search (uri)) { + /* Special case search files as well. */ + relative_uri_tmp = uri + strlen (EEL_SEARCH_URI); + while (*relative_uri_tmp == '/') { + relative_uri_tmp++; + } + relative_uri = strdup (relative_uri_tmp); } } @@ -524,8 +541,8 @@ nautilus_file_ref (NautilusFile *file) g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL); #ifdef NAUTILUS_FILE_DEBUG_REF - printf("%10p ref'd\n", file); - eazel_dump_stack_trace ("\t", 10); + if (strcmp (nautilus_file_get_uri (file), "file:///home/andersca/src/gnome/gtk%2B/gtk/gtkbutton.c") == 0) + VALGRIND_PRINTF_BACKTRACE("%10p ref'd", file); #endif g_object_ref (file); @@ -542,8 +559,8 @@ nautilus_file_unref (NautilusFile *file) g_return_if_fail (NAUTILUS_IS_FILE (file)); #ifdef NAUTILUS_FILE_DEBUG_REF - printf("%10p unref'd\n", file); - eazel_dump_stack_trace ("\t", 10); + if (strcmp (nautilus_file_get_uri (file), "file:///home/andersca/src/gnome/gtk%2B/gtk/gtkbutton.c") == 0) + VALGRIND_PRINTF_BACKTRACE("%10p unref'd", file); #endif g_object_unref (file); diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-file-utilities.c nautilus-2.12.2.joe/libnautilus-private/nautilus-file-utilities.c --- nautilus-2.12.2/libnautilus-private/nautilus-file-utilities.c 2005-07-13 11:25:30.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-file-utilities.c 2006-04-14 23:02:12.208544984 +0200 @@ -30,6 +30,7 @@ #include "nautilus-metadata.h" #include "nautilus-metafile.h" #include "nautilus-file.h" +#include "nautilus-search-directory.h" #include <eel/eel-glib-extensions.h> #include <eel/eel-string.h> #include <eel/eel-vfs-extensions.h> @@ -56,10 +57,21 @@ nautilus_compute_title_for_uri (const ch GnomeVFSURI *uri; char *title, *displayname; const char *hostname; - + NautilusDirectory *directory; + NautilusQuery *query; hostname = NULL; if (text_uri) { + if (eel_uri_is_search (text_uri)) { + directory = nautilus_directory_get (text_uri); + + query = nautilus_search_directory_get_query (NAUTILUS_SEARCH_DIRECTORY (directory)); + title = nautilus_query_to_readable_string (query); + + nautilus_directory_unref (directory); + + return title; + } file = nautilus_file_get (text_uri); uri = gnome_vfs_uri_new (text_uri); if (uri && !gnome_vfs_uri_is_local (uri)) { @@ -237,6 +249,22 @@ nautilus_get_templates_directory_uri (vo return uri; } +char * +nautilus_get_searches_directory (void) +{ + char *user_dir; + char *searches_dir; + + user_dir = nautilus_get_user_directory (); + searches_dir = g_build_filename (user_dir, "searches", NULL); + g_free (user_dir); + + if (!g_file_test (searches_dir, G_FILE_TEST_EXISTS)) + mkdir (searches_dir, DEFAULT_NAUTILUS_DIRECTORY_MODE); + + return searches_dir; +} + /* These need to be reset to NULL when desktop_is_home_dir changes */ static char *escaped_desktop_dir = NULL; static char *escaped_desktop_dir_dirname = NULL; diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-file-utilities.h nautilus-2.12.2.joe/libnautilus-private/nautilus-file-utilities.h --- nautilus-2.12.2/libnautilus-private/nautilus-file-utilities.h 2005-06-23 10:27:27.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-file-utilities.h 2006-04-14 23:02:12.219543072 +0200 @@ -49,6 +49,8 @@ char * nautilus_get_templates_director char * nautilus_get_templates_directory_uri (void); void nautilus_create_templates_directory (void); +char * nautilus_get_searches_directory (void); + char * nautilus_compute_title_for_uri (const char *text_uri); /* This function returns something that needs to be freed with g_free, diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-icon-container.c nautilus-2.12.2.joe/libnautilus-private/nautilus-icon-container.c --- nautilus-2.12.2/libnautilus-private/nautilus-icon-container.c 2005-10-27 09:25:52.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-icon-container.c 2006-04-14 23:02:12.255536815 +0200 @@ -3572,6 +3572,7 @@ motion_notify_event (GtkWidget *widget, NautilusIconContainerDetails *details; double world_x, world_y; int canvas_x, canvas_y; + GdkDragAction actions; container = NAUTILUS_ICON_CONTAINER (widget); details = container->details; @@ -3602,13 +3603,16 @@ motion_notify_event (GtkWidget *widget, &canvas_x, &canvas_y); + actions = GDK_ACTION_COPY + | GDK_ACTION_LINK + | GDK_ACTION_ASK; + + if (container->details->drag_allow_moves) { + actions |= GDK_ACTION_MOVE; + } + nautilus_icon_dnd_begin_drag (container, - details->drag_state == DRAG_STATE_MOVE_OR_COPY - ? (GDK_ACTION_MOVE - | GDK_ACTION_COPY - | GDK_ACTION_LINK - | GDK_ACTION_ASK) - : GDK_ACTION_ASK, + actions, details->drag_button, event, canvas_x, @@ -6753,6 +6757,23 @@ nautilus_icon_container_get_icon_descrip } } +gboolean +nautilus_icon_container_get_allow_moves (NautilusIconContainer *container) +{ + g_return_val_if_fail (NAUTILUS_IS_ICON_CONTAINER (container), FALSE); + + return container->details->drag_allow_moves; +} + +void +nautilus_icon_container_set_allow_moves (NautilusIconContainer *container, + gboolean allow_moves) +{ + g_return_if_fail (NAUTILUS_IS_ICON_CONTAINER (container)); + + container->details->drag_allow_moves = allow_moves; +} + /* NautilusIconContainerAccessible */ static NautilusIconContainerAccessiblePrivate * diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-icon-container.h nautilus-2.12.2.joe/libnautilus-private/nautilus-icon-container.h --- nautilus-2.12.2/libnautilus-private/nautilus-icon-container.h 2005-10-27 09:25:52.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-icon-container.h 2006-04-14 23:02:12.264535251 +0200 @@ -286,5 +286,8 @@ void nautilus_icon_containe gboolean use_drop_shadows); char* nautilus_icon_container_get_icon_description (NautilusIconContainer *container, NautilusIconData *data); +gboolean nautilus_icon_container_get_allow_moves (NautilusIconContainer *container); +void nautilus_icon_container_set_allow_moves (NautilusIconContainer *container, + gboolean allow_moves); #endif /* NAUTILUS_ICON_CONTAINER_H */ diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-icon-factory.c nautilus-2.12.2.joe/libnautilus-private/nautilus-icon-factory.c --- nautilus-2.12.2/libnautilus-private/nautilus-icon-factory.c 2005-10-27 09:25:52.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-icon-factory.c 2006-04-14 23:02:12.276533165 +0200 @@ -829,6 +829,9 @@ get_special_icon_for_file (NautilusFile } else { ret = ICON_NAME_TRASH_FULL; } + } else if (eel_uri_is_search (uri)) { + /* FIXME: We really need a better icon than this */ + ret = "gnome-searchtool"; } g_free (uri); diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-icon-private.h nautilus-2.12.2.joe/libnautilus-private/nautilus-icon-private.h --- nautilus-2.12.2/libnautilus-private/nautilus-icon-private.h 2005-10-27 09:25:52.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-icon-private.h 2006-04-14 23:02:12.284531775 +0200 @@ -160,6 +160,7 @@ struct NautilusIconContainerDetails { DragState drag_state; gboolean drag_started; StretchState stretch_start; + gboolean drag_allow_moves; gboolean icon_selected_on_button_down; NautilusIcon *double_click_icon[2]; /* Both clicks in a double click need to be on the same icon */ diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-marshal.list nautilus-2.12.2.joe/libnautilus-private/nautilus-marshal.list --- nautilus-2.12.2/libnautilus-private/nautilus-marshal.list 2005-10-27 09:25:52.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-marshal.list 2006-04-14 23:02:12.291530559 +0200 @@ -14,3 +14,4 @@ VOID:POINTER,STRING,ENUM,INT,INT VOID:STRING,STRING VOID:POINTER,POINTER,POINTER,ENUM,INT,INT VOID:POINTER,ENUM +VOID:INT,STRING diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-metafile.c nautilus-2.12.2.joe/libnautilus-private/nautilus-metafile.c --- nautilus-2.12.2/libnautilus-private/nautilus-metafile.c 2005-10-27 09:25:52.000000000 +0200 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-metafile.c 2006-04-14 23:02:12.304528299 +0200 @@ -232,7 +232,12 @@ nautilus_metafile_get (const char *direc char *canonical_uri; g_return_val_if_fail (directory_uri != NULL, NULL); - + + /* We don't have metafiles for search uris */ + if (eel_uri_is_search (directory_uri)) { + return NULL; + } + if (metafiles == NULL) { metafiles = eel_g_hash_table_new_free_at_exit (g_str_hash, g_str_equal, __FILE__ ": metafiles"); diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-metafile-factory.c nautilus-2.12.2.joe/libnautilus-private/nautilus-metafile-factory.c --- nautilus-2.12.2/libnautilus-private/nautilus-metafile-factory.c 2002-03-07 15:02:18.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-metafile-factory.c 2006-04-14 23:02:12.313526735 +0200 @@ -54,6 +54,10 @@ corba_open (PortableServer_Servant serva metafile = nautilus_metafile_get (directory); + if (!metafile) { + return CORBA_OBJECT_NIL; + } + return CORBA_Object_duplicate (BONOBO_OBJREF (metafile), ev); } diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-query.c nautilus-2.12.2.joe/libnautilus-private/nautilus-query.c --- nautilus-2.12.2/libnautilus-private/nautilus-query.c 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-query.c 2006-04-14 23:02:12.327524302 +0200 @@ -0,0 +1,101 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * Copyright (C) 2005 Novell, Inc. + * + * Nautilus is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Nautilus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; see the file COPYING. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Anders Carlsson <andersca@imendio.com> + * + */ + +#include <config.h> +#include "nautilus-query.h" + +#include <eel/eel-gtk-macros.h> + +struct NautilusQueryDetails { + char *text; +}; + +static void nautilus_query_class_init (NautilusQueryClass *class); +static void nautilus_query_init (NautilusQuery *query); + +G_DEFINE_TYPE (NautilusQuery, + nautilus_query, + G_TYPE_OBJECT); + +static GObjectClass *parent_class = NULL; + +static void +finalize (GObject *object) +{ + NautilusQuery *query; + + query = NAUTILUS_QUERY (object); + + g_free (query->details->text); + g_free (query->details); + + EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); +} + +static void +nautilus_query_class_init (NautilusQueryClass *class) +{ + GObjectClass *gobject_class; + + parent_class = g_type_class_peek_parent (class); + + gobject_class = G_OBJECT_CLASS (class); + gobject_class->finalize = finalize; +} + +static void +nautilus_query_init (NautilusQuery *query) +{ + query->details = g_new0 (NautilusQueryDetails, 1); +} + +NautilusQuery * +nautilus_query_new (void) +{ + return g_object_new (NAUTILUS_TYPE_QUERY, NULL); +} + + +G_CONST_RETURN char * +nautilus_query_get_text (NautilusQuery *query) +{ + return query->details->text; +} + +void +nautilus_query_set_text (NautilusQuery *query, const char *text) +{ + g_free (query->details->text); + query->details->text = g_strdup (text); +} + +char * +nautilus_query_to_readable_string (NautilusQuery *query) +{ + if (!query || !query->details->text) { + return g_strdup ("Search"); + } + + return g_strdup_printf ("Search for \"%s\"", query->details->text); +} + diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-query.h nautilus-2.12.2.joe/libnautilus-private/nautilus-query.h --- nautilus-2.12.2/libnautilus-private/nautilus-query.h 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-query.h 2006-04-14 23:02:12.334523085 +0200 @@ -0,0 +1,58 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * Copyright (C) 2005 Novell, Inc. + * + * Nautilus is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Nautilus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; see the file COPYING. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Anders Carlsson <andersca@imendio.com> + * + */ + +#ifndef NAUTILUS_QUERY_H +#define NAUTILUS_QUERY_H + +#include <glib-object.h> +#include <libgnomevfs/gnome-vfs-result.h> + +#define NAUTILUS_TYPE_QUERY (nautilus_query_get_type ()) +#define NAUTILUS_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_QUERY, NautilusQuery)) +#define NAUTILUS_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_QUERY, NautilusQueryClass)) +#define NAUTILUS_IS_QUERY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_QUERY)) +#define NAUTILUS_IS_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_QUERY)) +#define NAUTILUS_QUERY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_QUERY, NautilusQueryClass)) + +typedef struct NautilusQueryDetails NautilusQueryDetails; + +typedef struct NautilusQuery { + GObject parent; + NautilusQueryDetails *details; +} NautilusQuery; + +typedef struct { + GObjectClass parent_class; +} NautilusQueryClass; + +GType nautilus_query_get_type (void); +gboolean nautilus_query_enabled (void); + +NautilusQuery* nautilus_query_new (void); + +G_CONST_RETURN char *nautilus_query_get_text (NautilusQuery *query); +void nautilus_query_set_text (NautilusQuery *query, const char *text); + +char *nautilus_query_to_readable_string (NautilusQuery *query); + +#endif /* NAUTILUS_QUERY_H */ diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-search-directory.c nautilus-2.12.2.joe/libnautilus-private/nautilus-search-directory.c --- nautilus-2.12.2/libnautilus-private/nautilus-search-directory.c 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-search-directory.c 2006-04-14 23:02:12.345521174 +0200 @@ -0,0 +1,893 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + Copyright (C) 2005 Novell, Inc + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Anders Carlsson <andersca@imendio.com> +*/ + +#include <config.h> +#include "nautilus-search-directory.h" + +#include "nautilus-directory-private.h" +#include "nautilus-file.h" +#include "nautilus-file-private.h" +#include "nautilus-file-utilities.h" +#include "nautilus-search-engine.h" +#include <eel/eel-glib-extensions.h> +#include <libgnomevfs/gnome-vfs-utils.h> +#include <gtk/gtksignal.h> +#include <libgnome/gnome-macros.h> +#include <string.h> +#include <sys/time.h> + +struct NautilusSearchDirectoryDetails { + NautilusQuery *query; + + NautilusSearchEngine *engine; + + gboolean search_finished; + + GList *files; + GHashTable *file_hash; + + GList *monitor_list; + GList *callback_list; + GList *pending_callback_list; +}; + +typedef struct { + gboolean monitor_hidden_files; + gboolean monitor_backup_files; + NautilusFileAttributes monitor_attributes; + + gconstpointer client; +} SearchMonitor; + +typedef struct { + NautilusSearchDirectory *search_directory; + + NautilusDirectoryCallback callback; + gpointer callback_data; + + NautilusFileAttributes wait_for_attributes; + gboolean wait_for_file_list; + GList *file_list; + GHashTable *non_ready_hash; +} SearchCallback; + +GNOME_CLASS_BOILERPLATE (NautilusSearchDirectory, nautilus_search_directory, + NautilusDirectory, NAUTILUS_TYPE_DIRECTORY) + + +static void search_engine_hits_added (NautilusSearchEngine *engine, GList *hits, NautilusSearchDirectory *search); +static void search_engine_hits_subtracted (NautilusSearchEngine *engine, GList *hits, NautilusSearchDirectory *search); +static void search_engine_finished (NautilusSearchEngine *engine, NautilusSearchDirectory *search); +static void search_engine_error (NautilusSearchEngine *engine, const char *error, NautilusSearchDirectory *search); +static void search_callback_file_ready_callback (NautilusFile *file, gpointer data); + + +static void +ensure_search_engine (NautilusSearchDirectory *search) +{ + if (!search->details->engine) { + search->details->engine = nautilus_search_engine_new (); + g_signal_connect (search->details->engine, "hits-added", + G_CALLBACK (search_engine_hits_added), + search); + g_signal_connect (search->details->engine, "hits-subtracted", + G_CALLBACK (search_engine_hits_subtracted), + search); + g_signal_connect (search->details->engine, "finished", + G_CALLBACK (search_engine_finished), + search); + g_signal_connect (search->details->engine, "error", + G_CALLBACK (search_engine_error), + search); + } +} + +static void +reset_file_list (NautilusSearchDirectory *search) +{ + nautilus_file_list_free (search->details->files); + search->details->files = NULL; +} + +static void +start_or_stop_search_engine (NautilusSearchDirectory *search, gboolean adding) +{ + if (adding && (search->details->monitor_list || + search->details->pending_callback_list) && + search->details->query) { + /* We need to start the search engine */ + ensure_search_engine (search); + nautilus_search_engine_set_query (search->details->engine, search->details->query); + + reset_file_list (search); + + nautilus_search_engine_start (search->details->engine); + } else if (!adding && !search->details->monitor_list && + !search->details->pending_callback_list && + search->details->engine) { + nautilus_search_engine_stop (search->details->engine); + + reset_file_list (search); + } + +} + +static void +file_changed (NautilusFile *file, NautilusSearchDirectory *search) +{ + GList list; + + list.data = file; + list.next = NULL; + + if (!g_object_get_data (G_OBJECT (file), "has-tag") || TRUE) + nautilus_directory_emit_files_changed (NAUTILUS_DIRECTORY (search), &list); + + g_object_set_data (G_OBJECT (file), "has-tag", GINT_TO_POINTER (1)); +} + +static void +search_monitor_add (NautilusDirectory *directory, + gconstpointer client, + gboolean monitor_hidden_files, + gboolean monitor_backup_files, + NautilusFileAttributes file_attributes, + NautilusDirectoryCallback callback, + gpointer callback_data) +{ + GList *list; + SearchMonitor *monitor; + NautilusSearchDirectory *search; + NautilusFile *file; + + search = NAUTILUS_SEARCH_DIRECTORY (directory); + + monitor = g_new0 (SearchMonitor, 1); + monitor->monitor_hidden_files = monitor_hidden_files; + monitor->monitor_backup_files = monitor_backup_files; + monitor->monitor_attributes = file_attributes; + monitor->client = client; + + search->details->monitor_list = g_list_prepend (search->details->monitor_list, monitor); + + if (callback != NULL) { + (* callback) (directory, search->details->files, callback_data); + } + + for (list = search->details->files; list != NULL; list = list->next) { + file = list->data; + + /* Add monitors */ + nautilus_file_monitor_add (file, monitor, file_attributes); + } + + start_or_stop_search_engine (search, TRUE); +} + +static void +search_monitor_remove_file_monitors (SearchMonitor *monitor, NautilusSearchDirectory *search) +{ + GList *list; + NautilusFile *file; + + for (list = search->details->files; list != NULL; list = list->next) { + file = list->data; + + nautilus_file_monitor_remove (file, monitor); + } + +} + +static void +search_monitor_destroy (SearchMonitor *monitor, NautilusSearchDirectory *search) +{ + search_monitor_remove_file_monitors (monitor, search); + + g_free (monitor); +} + +static void +search_monitor_remove (NautilusDirectory *directory, + gconstpointer client) +{ + NautilusSearchDirectory *search; + SearchMonitor *monitor; + GList *list; + + search = NAUTILUS_SEARCH_DIRECTORY (directory); + + for (list = search->details->monitor_list; list != NULL; list = list->next) { + monitor = list->data; + + if (monitor->client == client) { + search->details->monitor_list = g_list_delete_link (search->details->monitor_list, list); + + search_monitor_destroy (monitor, search); + + break; + } + } + + start_or_stop_search_engine (search, FALSE); +} + +static void +cancel_call_when_ready (gpointer key, gpointer value, gpointer user_data) +{ + SearchCallback *search_callback; + NautilusFile *file; + + file = key; + search_callback = user_data; + + nautilus_file_cancel_call_when_ready (file, search_callback_file_ready_callback, + search_callback); +} + +static void +search_callback_destroy (SearchCallback *search_callback) +{ + if (search_callback->non_ready_hash) { + g_hash_table_foreach (search_callback->non_ready_hash, cancel_call_when_ready, search_callback); + g_hash_table_destroy (search_callback->non_ready_hash); + } + + nautilus_file_list_free (search_callback->file_list); + + g_free (search_callback); +} + +static void +search_callback_invoke_and_destroy (SearchCallback *search_callback) +{ + search_callback->callback (NAUTILUS_DIRECTORY (search_callback->search_directory), + search_callback->file_list, + search_callback->callback_data); + + search_callback->search_directory->details->callback_list = + g_list_remove (search_callback->search_directory->details->callback_list, search_callback); + + search_callback_destroy (search_callback); +} + +static void +search_callback_file_ready_callback (NautilusFile *file, gpointer data) +{ + SearchCallback *search_callback = data; + + g_hash_table_remove (search_callback->non_ready_hash, file); + + if (g_hash_table_size (search_callback->non_ready_hash) == 0) { + search_callback_invoke_and_destroy (search_callback); + } +} + +static void +search_callback_add_file_callbacks (SearchCallback *callback) +{ + GList *file_list_copy, *list; + NautilusFile *file; + + file_list_copy = g_list_copy (callback->file_list); + + for (list = file_list_copy; list != NULL; list = list->next) { + file = list->data; + + nautilus_file_call_when_ready (file, + callback->wait_for_attributes, + search_callback_file_ready_callback, + callback); + } + g_list_free (file_list_copy); +} + +static SearchCallback * +search_callback_find (NautilusSearchDirectory *search, NautilusDirectoryCallback callback, gpointer callback_data) +{ + SearchCallback *search_callback; + GList *list; + + for (list = search->details->callback_list; list != NULL; list = list->next) { + search_callback = list->data; + + if (search_callback->callback == callback && + search_callback->callback_data == callback_data) { + return search_callback; + } + } + + return NULL; +} + +static SearchCallback * +search_callback_find_pending (NautilusSearchDirectory *search, NautilusDirectoryCallback callback, gpointer callback_data) +{ + SearchCallback *search_callback; + GList *list; + + for (list = search->details->pending_callback_list; list != NULL; list = list->next) { + search_callback = list->data; + + if (search_callback->callback == callback && + search_callback->callback_data == callback_data) { + return search_callback; + } + } + + return NULL; +} + +static GHashTable * +file_list_to_hash_table (GList *file_list) +{ + GList *list; + GHashTable *table; + + if (!file_list) + return NULL; + + table = g_hash_table_new (NULL, NULL); + + for (list = file_list; list != NULL; list = list->next) { + g_hash_table_insert (table, list->data, list->data); + } + + return table; +} + +static void +search_call_when_ready (NautilusDirectory *directory, + NautilusFileAttributes file_attributes, + gboolean wait_for_file_list, + NautilusDirectoryCallback callback, + gpointer callback_data) +{ + NautilusSearchDirectory *search; + SearchCallback *search_callback; + + search = NAUTILUS_SEARCH_DIRECTORY (directory); + + search_callback = search_callback_find (search, callback, callback_data); + + if (search_callback) { + g_warning ("tried to add a new callback while an old one was pending"); + return; + } + + search_callback = g_new0 (SearchCallback, 1); + search_callback->search_directory = search; + search_callback->callback = callback; + search_callback->callback_data = callback_data; + search_callback->wait_for_attributes = file_attributes; + search_callback->wait_for_file_list = wait_for_file_list; + + if (wait_for_file_list) { + /* Add it to the pending callback list, which will be + * processed when the directory has finished loading + */ + search->details->pending_callback_list = + g_list_prepend (search->details->pending_callback_list, search_callback); + + /* We might need to start the search engine */ + start_or_stop_search_engine (search, TRUE); + } else { + search_callback->file_list = nautilus_file_list_copy (search->details->files); + search_callback->non_ready_hash = file_list_to_hash_table (search->details->files); + + if (!search_callback->non_ready_hash) { + /* If there are no ready files, we invoke the callback + with an empty list. + */ + search_callback_invoke_and_destroy (search_callback); + } else { + search->details->callback_list = g_list_prepend (search->details->callback_list, search_callback); + search_callback_add_file_callbacks (search_callback); + } + } +} + +static void +search_cancel_callback (NautilusDirectory *directory, + NautilusDirectoryCallback callback, + gpointer callback_data) +{ + NautilusSearchDirectory *search; + SearchCallback *search_callback; + + search = NAUTILUS_SEARCH_DIRECTORY (directory); + search_callback = search_callback_find (search, callback, callback_data); + + if (search_callback) { + search->details->callback_list = g_list_remove (search->details->callback_list, search_callback); + + search_callback_destroy (search_callback); + + return; + } + + /* Check for a pending callback */ + search_callback = search_callback_find_pending (search, callback, callback_data); + + if (search_callback) { + search->details->pending_callback_list = g_list_remove (search->details->pending_callback_list, search_callback); + + search_callback_destroy (search_callback); + + /* We might need to stop the search engine now */ + start_or_stop_search_engine (search, FALSE); + } +} + + +static void +search_engine_hits_added (NautilusSearchEngine *engine, GList *hits, + NautilusSearchDirectory *search) +{ + GList *hit_list; + GList *file_list; + NautilusFile *file; + char *uri; + SearchMonitor *monitor; + GList *monitor_list; + + file_list = NULL; + + for (hit_list = hits; hit_list != NULL; hit_list = hit_list->next) { + uri = hit_list->data; + file = nautilus_file_get (uri); + + for (monitor_list = search->details->monitor_list; monitor_list; monitor_list = monitor_list->next) { + monitor = monitor_list->data; + + /* Add monitors */ + nautilus_file_monitor_add (file, monitor, monitor->monitor_attributes); + } + + g_signal_connect (file, "changed", G_CALLBACK (file_changed), search), + + file_list = g_list_prepend (file_list, file); + } + + search->details->files = g_list_concat (search->details->files, file_list); + + nautilus_directory_emit_files_added (NAUTILUS_DIRECTORY (search), file_list); + + file = nautilus_directory_get_corresponding_file (NAUTILUS_DIRECTORY (search)); + nautilus_file_emit_changed (file); + nautilus_file_unref (file); +} + +static void +search_engine_hits_subtracted (NautilusSearchEngine *engine, GList *hits, + NautilusSearchDirectory *search) +{ + GList *hit_list; + GList *monitor_list; + SearchMonitor *monitor; + GList *file_list; + char *uri; + NautilusFile *file; + + file_list = NULL; + + for (hit_list = hits; hit_list != NULL; hit_list = hit_list->next) { + uri = hit_list->data; + file = nautilus_file_get (uri); + + for (monitor_list = search->details->monitor_list; monitor_list; + monitor_list = monitor_list->next) { + monitor = monitor_list->data; + /* Remove monitors */ + nautilus_file_monitor_remove (file, monitor); + } + + g_signal_handlers_disconnect_by_func (file, file_changed, search); + + search->details->files = g_list_remove (search->details->files, file); + + file_list = g_list_prepend (file_list, file); + } + + nautilus_directory_emit_files_changed (NAUTILUS_DIRECTORY (search), file_list); + + nautilus_file_list_free (file_list); + + file = nautilus_directory_get_corresponding_file (NAUTILUS_DIRECTORY (search)); + nautilus_file_emit_changed (file); + nautilus_file_unref (file); +} + +static void +search_callback_add_pending_file_callbacks (SearchCallback *callback) +{ + callback->file_list = nautilus_file_list_copy (callback->search_directory->details->files); + callback->non_ready_hash = file_list_to_hash_table (callback->search_directory->details->files); + + search_callback_add_file_callbacks (callback); +} + +static void +search_remove_file_connections (NautilusSearchDirectory *search) +{ + GList *list; + NautilusFile *file; + + /* Remove file connections */ + for (list = search->details->files; list != NULL; list = list->next) { + file = list->data; + + g_signal_handlers_disconnect_by_func (file, file_changed, search); + } + +} + +static void +search_engine_error (NautilusSearchEngine *engine, const char *error_message, NautilusSearchDirectory *search) +{ + nautilus_directory_emit_load_error (NAUTILUS_DIRECTORY (search), + -1, error_message); +} + +static void +search_engine_finished (NautilusSearchEngine *engine, NautilusSearchDirectory *search) +{ + search->details->search_finished = TRUE; + + nautilus_directory_emit_done_loading (NAUTILUS_DIRECTORY (search)); + + /* Add all file callbacks */ + g_list_foreach (search->details->pending_callback_list, + (GFunc)search_callback_add_pending_file_callbacks, NULL); + search->details->callback_list = g_list_concat (search->details->callback_list, + search->details->pending_callback_list); + + g_list_free (search->details->pending_callback_list); + search->details->pending_callback_list = NULL; +} + +static void +search_force_reload (NautilusDirectory *directory) +{ + NautilusSearchDirectory *search; + + search = NAUTILUS_SEARCH_DIRECTORY (directory); + + if (!search->details->query) { + return; + } + + search->details->search_finished = FALSE; + + if (!search->details->engine) { + return; + } + + /* Remove file monitors */ + g_list_foreach (search->details->monitor_list, + (GFunc)search_monitor_remove_file_monitors, search); + + /* Remove file connections */ + search_remove_file_connections (search); + + reset_file_list (search); + + nautilus_search_engine_stop (search->details->engine); + nautilus_search_engine_set_query (search->details->engine, search->details->query); + nautilus_search_engine_start (search->details->engine); +} + +static gboolean +search_are_all_files_seen (NautilusDirectory *directory) +{ + NautilusSearchDirectory *search; + + search = NAUTILUS_SEARCH_DIRECTORY (directory); + + return (!search->details->query || + search->details->search_finished); +} + +static gboolean +search_contains_file (NautilusDirectory *directory, + NautilusFile *file) +{ + NautilusSearchDirectory *search; + + search = NAUTILUS_SEARCH_DIRECTORY (directory); + + /* FIXME: Maybe put the files in a hash */ + return (g_list_find (search->details->files, file) != NULL); +} + +static GList * +search_get_file_list (NautilusDirectory *directory) +{ + NautilusSearchDirectory *search; + + search = NAUTILUS_SEARCH_DIRECTORY (directory); + + return nautilus_file_list_copy (search->details->files); +} + + +static gboolean +search_is_editable (NautilusDirectory *directory) +{ + return FALSE; +} + +static void +search_dispose (GObject *object) +{ + NautilusSearchDirectory *search; + GList *list; + + search = NAUTILUS_SEARCH_DIRECTORY (object); + + /* Remove search monitors */ + if (search->details->monitor_list) { + for (list = search->details->monitor_list; list != NULL; list = list->next) { + search_monitor_destroy ((SearchMonitor *)list->data, search); + } + + g_list_free (search->details->monitor_list); + search->details->monitor_list = NULL; + } + + search_remove_file_connections (search); + reset_file_list (search); + + if (search->details->callback_list) { + /* Remove callbacks */ + g_list_foreach (search->details->callback_list, + (GFunc)search_callback_destroy, NULL); + g_list_free (search->details->callback_list); + search->details->callback_list = NULL; + } + + if (search->details->pending_callback_list) { + g_list_foreach (search->details->pending_callback_list, + (GFunc)search_callback_destroy, NULL); + g_list_free (search->details->pending_callback_list); + search->details->pending_callback_list = NULL; + } + + if (search->details->query) { + g_free (search->details->query); + search->details->query = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +search_finalize (GObject *object) +{ + NautilusSearchDirectory *search; + + search = NAUTILUS_SEARCH_DIRECTORY (object); + + g_free (search->details); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +nautilus_search_directory_instance_init (NautilusSearchDirectory *search) +{ + search->details = g_new0 (NautilusSearchDirectoryDetails, 1); +} + +static void +nautilus_search_directory_class_init (NautilusSearchDirectoryClass *class) +{ + NautilusDirectoryClass *directory_class; + + G_OBJECT_CLASS (class)->dispose = search_dispose; + G_OBJECT_CLASS (class)->finalize = search_finalize; + + directory_class = NAUTILUS_DIRECTORY_CLASS (class); + + directory_class->are_all_files_seen = search_are_all_files_seen; + directory_class->contains_file = search_contains_file; + directory_class->force_reload = search_force_reload; + directory_class->call_when_ready = search_call_when_ready; + directory_class->cancel_callback = search_cancel_callback; + + directory_class->file_monitor_add = search_monitor_add; + directory_class->file_monitor_remove = search_monitor_remove; + + directory_class->get_file_list = search_get_file_list; + directory_class->is_editable = search_is_editable; +} + +char * +nautilus_search_directory_generate_new_uri (void) +{ + static int counter = 0; + struct timeval tv; + char *uri; + + gettimeofday (&tv, NULL); + + uri = g_strdup_printf (EEL_SEARCH_URI"///%ld-%ld-%d/", tv.tv_sec, tv.tv_usec, counter++); + printf ("generated uri: %s\n", uri); + + return uri; +} + + +void +nautilus_search_directory_set_query (NautilusSearchDirectory *search, + NautilusQuery *query) +{ + g_object_ref (query); + + if (search->details->query) { + g_object_unref (search->details->query); + } + + search->details->query = query; +} + +NautilusQuery * +nautilus_search_directory_get_query (NautilusSearchDirectory *search) +{ + return search->details->query; +} + +/* Move past the "x-nautilus-search:///" portion of the URI */ +#define SEARCH_URI_OFFSET 21 + +void +nautilus_search_directory_save_search (NautilusSearchDirectory *search) +{ + char *search_uri; + char *search_dir, *search_file; + char *xml; + GError *err = NULL; + + if (search->details->query == NULL) + return; + + search_uri = nautilus_directory_get_uri (NAUTILUS_DIRECTORY (search)); + + search_dir = nautilus_get_searches_directory (); + search_file = g_build_path ("/", search_dir, search_uri + SEARCH_URI_OFFSET, NULL); + g_free (search_dir); + + xml = g_strdup_printf ("<query uri=\"%s\">\n" + " <text>%s</text>\n" + "</query>\n", + search_uri, + nautilus_query_get_text (search->details->query)); + + g_free (search_uri); + + g_file_set_contents (search_file, xml, strlen (xml), &err); +} + +typedef struct { + NautilusSearchDirectory *search; + gboolean in_text; +} ParserInfo; + +static void +start_element_cb (GMarkupParseContext *ctx, + const char *element_name, + const char **attribute_names, + const char **attribute_values, + gpointer user_data, + GError **err) +{ + ParserInfo *info; + + info = (ParserInfo *) user_data; + + if (strcmp (element_name, "text") == 0) + info->in_text = TRUE; +} + +static void +end_element_cb (GMarkupParseContext *ctx, + const char *element_name, + gpointer user_data, + GError **err) +{ + ParserInfo *info; + + info = (ParserInfo *) user_data; + + if (strcmp (element_name, "text") == 0) + info->in_text = FALSE; +} + +static void +text_cb (GMarkupParseContext *ctx, + const char *text, + gsize text_len, + gpointer user_data, + GError **err) +{ + ParserInfo *info; + char *t; + NautilusQuery *query; + + info = (ParserInfo *) user_data; + + if (!info->in_text) { + return; + } + + t = g_strndup (text, text_len); + + query = nautilus_query_new (); + nautilus_query_set_text (query, t); + g_free (t); + + nautilus_search_directory_set_query (info->search, query); + g_object_unref (query); +} + +static void +error_cb (GMarkupParseContext *ctx, + GError *err, + gpointer user_data) +{ +} + +static GMarkupParser parser = { + start_element_cb, + end_element_cb, + text_cb, + NULL, + error_cb +}; + +void +nautilus_search_directory_load_search (NautilusSearchDirectory *search) +{ + char *search_uri; + char *search_dir, *search_file; + ParserInfo info; + GMarkupParseContext *ctx; + char *xml; + gsize xml_len; + + search_uri = nautilus_directory_get_uri (NAUTILUS_DIRECTORY (search)); + + search_dir = nautilus_get_searches_directory (); + search_file = g_build_path ("/", search_dir, search_uri + SEARCH_URI_OFFSET, NULL); + g_free (search_dir); + + if (!g_file_test (search_file, G_FILE_TEST_EXISTS)) { + return; + } + + info.search = search; + info.in_text = FALSE; + + ctx = g_markup_parse_context_new (&parser, 0, &info, NULL); + g_file_get_contents (search_file, &xml, &xml_len, NULL); + + g_markup_parse_context_parse (ctx, xml, xml_len, NULL); +} diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-search-directory-file.c nautilus-2.12.2.joe/libnautilus-private/nautilus-search-directory-file.c --- nautilus-2.12.2/libnautilus-private/nautilus-search-directory-file.c 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-search-directory-file.c 2006-04-14 23:02:12.352519957 +0200 @@ -0,0 +1,153 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-search-directory-file.c: Subclass of NautilusFile to help implement the + searches + + Copyright (C) 2005 Novell, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Anders Carlsson <andersca@imendio.com> +*/ + +#include <config.h> +#include "nautilus-search-directory-file.h" + +#include "nautilus-directory-notify.h" +#include "nautilus-directory-private.h" +#include "nautilus-file-attributes.h" +#include "nautilus-file-private.h" +#include "nautilus-file-utilities.h" +#include <eel/eel-glib-extensions.h> +#include <eel/eel-gtk-macros.h> +#include "nautilus-search-directory.h" +#include <gtk/gtksignal.h> +#include <libgnome/gnome-i18n.h> +#include <string.h> + +static void nautilus_search_directory_file_init (gpointer object, + gpointer klass); +static void nautilus_search_directory_file_class_init (gpointer klass); + +EEL_CLASS_BOILERPLATE (NautilusSearchDirectoryFile, + nautilus_search_directory_file, + NAUTILUS_TYPE_FILE); + +struct NautilusSearchDirectoryFileDetails { + NautilusSearchDirectory *search_directory; +}; + +static void +search_directory_file_monitor_add (NautilusFile *file, + gconstpointer client, + NautilusFileAttributes attributes) +{ + nautilus_directory_monitor_add_internal (file->details->directory, + file, client, TRUE, TRUE, + attributes, NULL, NULL); +} + +static void +search_directory_file_monitor_remove (NautilusFile *file, + gconstpointer client) +{ + nautilus_directory_monitor_remove_internal (file->details->directory, + file, client); +} + +static void +search_directory_file_call_when_ready (NautilusFile *file, + NautilusFileAttributes file_attributes, + NautilusFileCallback callback, + gpointer callback_data) + +{ + nautilus_directory_call_when_ready_internal (file->details->directory, + file, file_attributes, + FALSE, NULL, + callback, callback_data); +} + +static void +search_directory_file_cancel_call_when_ready (NautilusFile *file, + NautilusFileCallback callback, + gpointer callback_data) +{ + /* Do nothing here, we don't have any pending calls */ +} + + +static gboolean +search_directory_file_check_if_ready (NautilusFile *file, + NautilusFileAttributes attributes) +{ + return nautilus_directory_check_if_ready_internal + (file->details->directory, + file, attributes); +} + +static GnomeVFSFileType +search_directory_file_get_file_type (NautilusFile *file) +{ + return GNOME_VFS_FILE_TYPE_DIRECTORY; +} + +static gboolean +search_directory_file_get_item_count (NautilusFile *file, + guint *count, + gboolean *count_unreadable) +{ + NautilusSearchDirectory *search_dir; + GList *file_list; + + if (count) { + search_dir = NAUTILUS_SEARCH_DIRECTORY (file->details->directory); + + file_list = nautilus_directory_get_file_list (file->details->directory); + + *count = g_list_length (file_list); + + nautilus_file_list_free (file_list); + } + + return TRUE; +} + +static void +nautilus_search_directory_file_init (gpointer object, gpointer klass) +{ + NautilusSearchDirectoryFile *search_file; + + search_file = NAUTILUS_SEARCH_DIRECTORY_FILE (object); +} + +static void +nautilus_search_directory_file_class_init (gpointer klass) +{ + GObjectClass *object_class; + NautilusFileClass *file_class; + + object_class = G_OBJECT_CLASS (klass); + file_class = NAUTILUS_FILE_CLASS (klass); + + file_class->monitor_add = search_directory_file_monitor_add; + file_class->monitor_remove = search_directory_file_monitor_remove; + file_class->call_when_ready = search_directory_file_call_when_ready; + file_class->cancel_call_when_ready = search_directory_file_cancel_call_when_ready; + file_class->get_file_type = search_directory_file_get_file_type; + file_class->check_if_ready = search_directory_file_check_if_ready; + file_class->get_item_count = search_directory_file_get_item_count; +} diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-search-directory-file.h nautilus-2.12.2.joe/libnautilus-private/nautilus-search-directory-file.h --- nautilus-2.12.2/libnautilus-private/nautilus-search-directory-file.h 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-search-directory-file.h 2006-04-14 23:02:12.360518567 +0200 @@ -0,0 +1,55 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-search-directory-file.h: Subclass of NautilusFile to implement the + the case of the search directory + + Copyright (C) 2003 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Alexander Larsson <alexl@redhat.com> +*/ + +#ifndef NAUTILUS_SEARCH_DIRECTORY_FILE_H +#define NAUTILUS_SEARCH_DIRECTORY_FILE_H + +#include <libnautilus-private/nautilus-file.h> + +#define NAUTILUS_TYPE_SEARCH_DIRECTORY_FILE \ + (nautilus_search_directory_file_get_type ()) +#define NAUTILUS_SEARCH_DIRECTORY_FILE(obj) \ + (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_SEARCH_DIRECTORY_FILE, NautilusSearchDirectoryFile)) +#define NAUTILUS_SEARCH_DIRECTORY_FILE_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_SEARCH_DIRECTORY_FILE, NautilusSearchDirectoryFileClass)) +#define NAUTILUS_IS_SEARCH_DIRECTORY_FILE(obj) \ + (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_SEARCH_DIRECTORY_FILE)) +#define NAUTILUS_IS_SEARCH_DIRECTORY_FILE_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_SEARCH_DIRECTORY_FILE)) + +typedef struct NautilusSearchDirectoryFileDetails NautilusSearchDirectoryFileDetails; + +typedef struct { + NautilusFile parent_slot; + NautilusSearchDirectoryFileDetails *details; +} NautilusSearchDirectoryFile; + +typedef struct { + NautilusFileClass parent_slot; +} NautilusSearchDirectoryFileClass; + +GType nautilus_search_directory_file_get_type (void); + +#endif /* NAUTILUS_SEARCH_DIRECTORY_FILE_H */ diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-search-directory.h nautilus-2.12.2.joe/libnautilus-private/nautilus-search-directory.h --- nautilus-2.12.2/libnautilus-private/nautilus-search-directory.h 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-search-directory.h 2006-04-14 23:02:12.368517176 +0200 @@ -0,0 +1,64 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-search-directory.h: Subclass of NautilusDirectory to implement + a virtual directory consisting of the search directory and the search + icons + + Copyright (C) 2005 Novell, Inc + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef NAUTILUS_SEARCH_DIRECTORY_H +#define NAUTILUS_SEARCH_DIRECTORY_H + +#include <libnautilus-private/nautilus-directory.h> +#include <libnautilus-private/nautilus-query.h> + +#define NAUTILUS_TYPE_SEARCH_DIRECTORY \ + (nautilus_search_directory_get_type ()) +#define NAUTILUS_SEARCH_DIRECTORY(obj) \ + (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_SEARCH_DIRECTORY, NautilusSearchDirectory)) +#define NAUTILUS_SEARCH_DIRECTORY_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_SEARCH_DIRECTORY, NautilusSearchDirectoryClass)) +#define NAUTILUS_IS_SEARCH_DIRECTORY(obj) \ + (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_SEARCH_DIRECTORY)) +#define NAUTILUS_IS_SEARCH_DIRECTORY_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_SEARCH_DIRECTORY)) + +typedef struct NautilusSearchDirectoryDetails NautilusSearchDirectoryDetails; + +typedef struct { + NautilusDirectory parent_slot; + NautilusSearchDirectoryDetails *details; +} NautilusSearchDirectory; + +typedef struct { + NautilusDirectoryClass parent_slot; +} NautilusSearchDirectoryClass; + +GType nautilus_search_directory_get_type (void); + +char *nautilus_search_directory_generate_new_uri (void); + +NautilusQuery *nautilus_search_directory_get_query (NautilusSearchDirectory *search); +void nautilus_search_directory_set_query (NautilusSearchDirectory *search, + NautilusQuery *query); + +void nautilus_search_directory_save_search (NautilusSearchDirectory *search); +void nautilus_search_directory_load_search (NautilusSearchDirectory *search); + +#endif /* NAUTILUS_SEARCH_DIRECTORY_H */ diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-search-engine-beagle.c nautilus-2.12.2.joe/libnautilus-private/nautilus-search-engine-beagle.c --- nautilus-2.12.2/libnautilus-private/nautilus-search-engine-beagle.c 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-search-engine-beagle.c 2006-04-14 23:02:12.376515786 +0200 @@ -0,0 +1,261 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * Copyright (C) 2005 Novell, Inc. + * + * Nautilus is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Nautilus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; see the file COPYING. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Anders Carlsson <andersca@imendio.com> + * + */ + +#include <config.h> +#include "nautilus-search-engine-beagle.h" +#include <beagle/beagle.h> + +#include <eel/eel-gtk-macros.h> + +struct NautilusSearchEngineBeagleDetails { + BeagleClient *client; + NautilusQuery *query; + + BeagleQuery *current_query; + gboolean query_finished; +}; + + +static void nautilus_search_engine_beagle_class_init (NautilusSearchEngineBeagleClass *class); +static void nautilus_search_engine_beagle_init (NautilusSearchEngineBeagle *engine); + +G_DEFINE_TYPE (NautilusSearchEngineBeagle, + nautilus_search_engine_beagle, + NAUTILUS_TYPE_SEARCH_ENGINE); + +static NautilusSearchEngineClass *parent_class = NULL; + +static void +finalize (GObject *object) +{ + NautilusSearchEngineBeagle *beagle; + + beagle = NAUTILUS_SEARCH_ENGINE_BEAGLE (object); + + if (beagle->details->current_query) { + g_object_unref (beagle->details->current_query); + } + + if (beagle->details->query) { + g_object_unref (beagle->details->query); + } + + if (beagle->details->client) { + g_object_unref (beagle->details->client); + } + + g_free (beagle->details); + + EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); +} + +static void +beagle_hits_added (BeagleQuery *query, + BeagleHitsAddedResponse *response, + NautilusSearchEngineBeagle *engine) +{ + GSList *hits, *list; + GList *hit_uris; + + hit_uris = NULL; + + hits = beagle_hits_added_response_get_hits (response); + + for (list = hits; list != NULL; list = list->next) { + BeagleHit *hit = BEAGLE_HIT (list->data); + + hit_uris = g_list_prepend (hit_uris, (char *)beagle_hit_get_uri (hit)); + } + + nautilus_search_engine_hits_added (NAUTILUS_SEARCH_ENGINE (engine), hit_uris); + g_list_free (hit_uris); +} + +static void +beagle_hits_subtracted (BeagleQuery *query, + BeagleHitsSubtractedResponse *response, + NautilusSearchEngineBeagle *engine) +{ + GSList *uris, *list; + GList *hit_uris; + + hit_uris = NULL; + + uris = beagle_hits_subtracted_response_get_uris (response); + + for (list = uris; list != NULL; list = list->next) { + hit_uris = g_list_prepend (hit_uris, (char *)list->data); + } + + nautilus_search_engine_hits_subtracted (NAUTILUS_SEARCH_ENGINE (engine), hit_uris); + g_list_free (hit_uris); +} + +static void +beagle_finished (BeagleQuery *query, + BeagleFinishedResponse *response, + NautilusSearchEngineBeagle *engine) +{ + /* For some reason we keep getting finished events, + * only emit finished once */ + if (engine->details->query_finished) { + return; + } + + engine->details->query_finished = TRUE; + nautilus_search_engine_finished (NAUTILUS_SEARCH_ENGINE (engine)); +} + +static void +beagle_error (BeagleQuery *query, + GError *error, + NautilusSearchEngineBeagle *engine) +{ + nautilus_search_engine_error (NAUTILUS_SEARCH_ENGINE (engine), error->message); +} + +static void +nautilus_search_engine_beagle_start (NautilusSearchEngine *engine) +{ + NautilusSearchEngineBeagle *beagle; + GError *error; + + error = NULL; + beagle = NAUTILUS_SEARCH_ENGINE_BEAGLE (engine); + + if (beagle->details->current_query) { + return; + } + + if (beagle->details->client == NULL) { + beagle->details->client = beagle_client_new (NULL); + + if (beagle->details->client == NULL) { + nautilus_search_engine_error (engine, + "Unable to connect to search service."); + return; + } + } + + beagle->details->query_finished = FALSE; + beagle->details->current_query = beagle_query_new (); + g_signal_connect (beagle->details->current_query, + "hits-added", G_CALLBACK (beagle_hits_added), engine); + g_signal_connect (beagle->details->current_query, + "hits-subtracted", G_CALLBACK (beagle_hits_subtracted), engine); + g_signal_connect (beagle->details->current_query, + "finished", G_CALLBACK (beagle_finished), engine); + g_signal_connect (beagle->details->current_query, + "error", G_CALLBACK (beagle_error), engine); + + beagle_query_add_text (beagle->details->current_query, + nautilus_query_get_text (beagle->details->query)); + /* We only want files */ + beagle_query_add_source (beagle->details->current_query, + "Files"); + beagle_query_set_max_hits (beagle->details->current_query, + 1000); + if (!beagle_client_send_request_async (beagle->details->client, + BEAGLE_REQUEST (beagle->details->current_query), &error)) { + nautilus_search_engine_error (engine, error->message); + g_error_free (error); + } +} + +static void +nautilus_search_engine_beagle_stop (NautilusSearchEngine *engine) +{ + NautilusSearchEngineBeagle *beagle; + + beagle = NAUTILUS_SEARCH_ENGINE_BEAGLE (engine); + + if (beagle->details->current_query) { + g_object_unref (beagle->details->current_query); + beagle->details->current_query = NULL; + } +} + +static void +nautilus_search_engine_beagle_set_query (NautilusSearchEngine *engine, NautilusQuery *query) +{ + NautilusSearchEngineBeagle *beagle; + + beagle = NAUTILUS_SEARCH_ENGINE_BEAGLE (engine); + + g_object_ref (query); + + if (beagle->details->query) { + g_object_unref (query); + } + + beagle->details->query = query; +} + +static void +nautilus_search_engine_beagle_class_init (NautilusSearchEngineBeagleClass *class) +{ + GObjectClass *gobject_class; + NautilusSearchEngineClass *engine_class; + + parent_class = g_type_class_peek_parent (class); + + gobject_class = G_OBJECT_CLASS (class); + gobject_class->finalize = finalize; + + engine_class = NAUTILUS_SEARCH_ENGINE_CLASS (class); + engine_class->set_query = nautilus_search_engine_beagle_set_query; + engine_class->start = nautilus_search_engine_beagle_start; + engine_class->stop = nautilus_search_engine_beagle_stop; +} + +static void +nautilus_search_engine_beagle_init (NautilusSearchEngineBeagle *engine) +{ + engine->details = g_new0 (NautilusSearchEngineBeagleDetails, 1); +} + + +NautilusSearchEngineBeagle * +nautilus_search_engine_beagle_new (void) +{ + NautilusSearchEngineBeagle *engine; + + engine = g_object_new (NAUTILUS_TYPE_SEARCH_ENGINE_BEAGLE, NULL); + + return engine; +} + +gboolean +nautilus_search_engine_beagle_available (void) +{ + BeagleClient *client; + + client = beagle_client_new (NULL); + + if (client == NULL) + return FALSE; + + g_object_unref (client); + + return TRUE; +} diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-search-engine-beagle.h nautilus-2.12.2.joe/libnautilus-private/nautilus-search-engine-beagle.h --- nautilus-2.12.2/libnautilus-private/nautilus-search-engine-beagle.h 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-search-engine-beagle.h 2006-04-14 23:02:12.383514569 +0200 @@ -0,0 +1,53 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * Copyright (C) 2005 Novell, Inc. + * + * Nautilus is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Nautilus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; see the file COPYING. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Anders Carlsson <andersca@imendio.com> + * + */ + +#ifndef NAUTILUS_SEARCH_ENGINE_BEAGLE_H +#define NAUTILUS_SEARCH_ENGINE_BEAGLE_H + +#include <libnautilus-private/nautilus-search-engine.h> + +#define NAUTILUS_TYPE_SEARCH_ENGINE_BEAGLE (nautilus_search_engine_beagle_get_type ()) +#define NAUTILUS_SEARCH_ENGINE_BEAGLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_SEARCH_ENGINE_BEAGLE, NautilusSearchEngineBeagle)) +#define NAUTILUS_SEARCH_ENGINE_BEAGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_SEARCH_ENGINE_BEAGLE, NautilusSearchEngineBeagleClass)) +#define NAUTILUS_IS_SEARCH_ENGINE_BEAGLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_SEARCH_ENGINE_BEAGLE)) +#define NAUTILUS_IS_SEARCH_ENGINE_BEAGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_SEARCH_ENGINE_BEAGLE)) +#define NAUTILUS_SEARCH_ENGINE_BEAGLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_SEARCH_ENGINE_BEAGLE, NautilusSearchEngineBeagleClass)) + +typedef struct NautilusSearchEngineBeagleDetails NautilusSearchEngineBeagleDetails; + +typedef struct NautilusSearchEngineBeagle { + NautilusSearchEngine parent; + NautilusSearchEngineBeagleDetails *details; +} NautilusSearchEngineBeagle; + +typedef struct { + NautilusSearchEngineClass parent_class; +} NautilusSearchEngineBeagleClass; + +GType nautilus_search_engine_beagle_get_type (void); + +NautilusSearchEngineBeagle* nautilus_search_engine_beagle_new (void); + +gboolean nautilus_search_engine_beagle_available (void); + +#endif /* NAUTILUS_SEARCH_ENGINE_BEAGLE_H */ diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-search-engine.c nautilus-2.12.2.joe/libnautilus-private/nautilus-search-engine.c --- nautilus-2.12.2/libnautilus-private/nautilus-search-engine.c 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-search-engine.c 2006-04-14 23:02:12.391513179 +0200 @@ -0,0 +1,205 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * Copyright (C) 2005 Novell, Inc. + * + * Nautilus is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Nautilus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; see the file COPYING. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Anders Carlsson <andersca@imendio.com> + * + */ + +#include <config.h> +#include "nautilus-search-engine.h" +#include "nautilus-search-engine-beagle.h" + +#include <eel/eel-gtk-macros.h> + +struct NautilusSearchEngineDetails { + char *text; + guint id; + gboolean emitted; + + int i; +}; + +enum { + HITS_ADDED, + HITS_SUBTRACTED, + FINISHED, + ERROR, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +static void nautilus_search_engine_class_init (NautilusSearchEngineClass *class); +static void nautilus_search_engine_init (NautilusSearchEngine *engine); + +G_DEFINE_ABSTRACT_TYPE (NautilusSearchEngine, + nautilus_search_engine, + G_TYPE_OBJECT); + +static GObjectClass *parent_class = NULL; + +static void +finalize (GObject *object) +{ + NautilusSearchEngine *engine; + + engine = NAUTILUS_SEARCH_ENGINE (object); + + g_free (engine->details->text); + g_free (engine->details); + + EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); +} + +static void +nautilus_search_engine_class_init (NautilusSearchEngineClass *class) +{ + GObjectClass *gobject_class; + + parent_class = g_type_class_peek_parent (class); + + gobject_class = G_OBJECT_CLASS (class); + gobject_class->finalize = finalize; + + signals[HITS_ADDED] = + g_signal_new ("hits-added", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NautilusSearchEngineClass, hits_added), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + + signals[HITS_SUBTRACTED] = + g_signal_new ("hits-subtracted", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NautilusSearchEngineClass, hits_subtracted), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + + signals[FINISHED] = + g_signal_new ("finished", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NautilusSearchEngineClass, finished), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[ERROR] = + g_signal_new ("error", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NautilusSearchEngineClass, error), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); + +} + +static void +nautilus_search_engine_init (NautilusSearchEngine *engine) +{ + engine->details = g_new0 (NautilusSearchEngineDetails, 1); +} + +gboolean +nautilus_search_engine_enabled (void) +{ +#ifdef HAVE_BEAGLE + return nautilus_search_engine_beagle_available (); +#endif + return FALSE; +} + +NautilusSearchEngine * +nautilus_search_engine_new (void) +{ +#ifdef HAVE_BEAGLE + return g_object_new (NAUTILUS_TYPE_SEARCH_ENGINE_BEAGLE, NULL); +#endif + return NULL; +} + +void +nautilus_search_engine_set_query (NautilusSearchEngine *engine, NautilusQuery *query) +{ + g_return_if_fail (NAUTILUS_IS_SEARCH_ENGINE (engine)); + g_return_if_fail (NAUTILUS_SEARCH_ENGINE_GET_CLASS (engine)->set_query != NULL); + + NAUTILUS_SEARCH_ENGINE_GET_CLASS (engine)->set_query (engine, query); +} + +void +nautilus_search_engine_start (NautilusSearchEngine *engine) +{ + g_return_if_fail (NAUTILUS_IS_SEARCH_ENGINE (engine)); + g_return_if_fail (NAUTILUS_SEARCH_ENGINE_GET_CLASS (engine)->start != NULL); + + NAUTILUS_SEARCH_ENGINE_GET_CLASS (engine)->start (engine); +} + + +void +nautilus_search_engine_stop (NautilusSearchEngine *engine) +{ + g_return_if_fail (NAUTILUS_IS_SEARCH_ENGINE (engine)); + g_return_if_fail (NAUTILUS_SEARCH_ENGINE_GET_CLASS (engine)->stop != NULL); + + NAUTILUS_SEARCH_ENGINE_GET_CLASS (engine)->stop (engine); +} + +void +nautilus_search_engine_hits_added (NautilusSearchEngine *engine, GList *hits) +{ + g_return_if_fail (NAUTILUS_IS_SEARCH_ENGINE (engine)); + + g_signal_emit (engine, signals[HITS_ADDED], 0, hits); +} + + +void +nautilus_search_engine_hits_subtracted (NautilusSearchEngine *engine, GList *hits) +{ + g_return_if_fail (NAUTILUS_IS_SEARCH_ENGINE (engine)); + + g_signal_emit (engine, signals[HITS_SUBTRACTED], 0, hits); +} + + +void +nautilus_search_engine_finished (NautilusSearchEngine *engine) +{ + g_return_if_fail (NAUTILUS_IS_SEARCH_ENGINE (engine)); + + g_signal_emit (engine, signals[FINISHED], 0); +} + +void +nautilus_search_engine_error (NautilusSearchEngine *engine, const char *error_message) +{ + g_return_if_fail (NAUTILUS_IS_SEARCH_ENGINE (engine)); + + g_signal_emit (engine, signals[ERROR], 0, error_message); +} diff -ruNp nautilus-2.12.2/libnautilus-private/nautilus-search-engine.h nautilus-2.12.2.joe/libnautilus-private/nautilus-search-engine.h --- nautilus-2.12.2/libnautilus-private/nautilus-search-engine.h 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/libnautilus-private/nautilus-search-engine.h 2006-04-14 23:02:12.398511962 +0200 @@ -0,0 +1,74 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * Copyright (C) 2005 Novell, Inc. + * + * Nautilus is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Nautilus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; see the file COPYING. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Anders Carlsson <andersca@imendio.com> + * + */ + +#ifndef NAUTILUS_SEARCH_ENGINE_H +#define NAUTILUS_SEARCH_ENGINE_H + +#include <glib-object.h> +#include <libgnomevfs/gnome-vfs-result.h> +#include <libnautilus-private/nautilus-query.h> + +#define NAUTILUS_TYPE_SEARCH_ENGINE (nautilus_search_engine_get_type ()) +#define NAUTILUS_SEARCH_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_SEARCH_ENGINE, NautilusSearchEngine)) +#define NAUTILUS_SEARCH_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_SEARCH_ENGINE, NautilusSearchEngineClass)) +#define NAUTILUS_IS_SEARCH_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_SEARCH_ENGINE)) +#define NAUTILUS_IS_SEARCH_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_SEARCH_ENGINE)) +#define NAUTILUS_SEARCH_ENGINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_SEARCH_ENGINE, NautilusSearchEngineClass)) + +typedef struct NautilusSearchEngineDetails NautilusSearchEngineDetails; + +typedef struct NautilusSearchEngine { + GObject parent; + NautilusSearchEngineDetails *details; +} NautilusSearchEngine; + +typedef struct { + GObjectClass parent_class; + + /* VTable */ + void (*set_query) (NautilusSearchEngine *engine, NautilusQuery *query); + void (*start) (NautilusSearchEngine *engine); + void (*stop) (NautilusSearchEngine *engine); + + /* Signals */ + void (*hits_added) (NautilusSearchEngine *engine, GList *hits); + void (*hits_subtracted) (NautilusSearchEngine *engine, GList *hits); + void (*finished) (NautilusSearchEngine *engine); + void (*error) (NautilusSearchEngine *engine, const char *error_message); +} NautilusSearchEngineClass; + +GType nautilus_search_engine_get_type (void); +gboolean nautilus_search_engine_enabled (void); + +NautilusSearchEngine* nautilus_search_engine_new (void); + +void nautilus_search_engine_set_query (NautilusSearchEngine *engine, NautilusQuery *query); +void nautilus_search_engine_start (NautilusSearchEngine *engine); +void nautilus_search_engine_stop (NautilusSearchEngine *engine); + +void nautilus_search_engine_hits_added (NautilusSearchEngine *engine, GList *hits); +void nautilus_search_engine_hits_subtracted (NautilusSearchEngine *engine, GList *hits); +void nautilus_search_engine_finished (NautilusSearchEngine *engine); +void nautilus_search_engine_error (NautilusSearchEngine *engine, const char *error_message); + +#endif /* NAUTILUS_SEARCH_ENGINE_H */ diff -ruNp nautilus-2.12.2/src/file-manager/fm-directory-view.c nautilus-2.12.2.joe/src/file-manager/fm-directory-view.c --- nautilus-2.12.2/src/file-manager/fm-directory-view.c 2005-11-28 10:03:35.000000000 +0100 +++ nautilus-2.12.2.joe/src/file-manager/fm-directory-view.c 2006-04-14 23:02:12.440504663 +0200 @@ -88,6 +88,7 @@ #include <libnautilus-private/nautilus-global-preferences.h> #include <libnautilus-private/nautilus-icon-factory.h> #include <libnautilus-private/nautilus-link.h> +#include <libnautilus-private/nautilus-marshal.h> #include <libnautilus-private/nautilus-metadata.h> #include <libnautilus-private/nautilus-mime-actions.h> #include <libnautilus-private/nautilus-module.h> @@ -253,6 +254,8 @@ struct FMDirectoryViewDetails guint open_with_merge_id; GList *subdirectory_list; + + gboolean allow_moves; }; typedef enum { @@ -2004,6 +2007,12 @@ fm_directory_view_send_selection_change view->details->send_selection_change_to_shell = FALSE; } +gboolean +fm_directory_view_get_allow_moves (FMDirectoryView *view) +{ + return view->details->allow_moves; +} + static void fm_directory_view_load_location (NautilusView *nautilus_view, const char *location) @@ -2013,6 +2022,12 @@ fm_directory_view_load_location (Nautilu directory_view = FM_DIRECTORY_VIEW (nautilus_view); + if (eel_uri_is_search (location)) { + directory_view->details->allow_moves = FALSE; + } else { + directory_view->details->allow_moves = TRUE; + } + directory = nautilus_directory_get (location); load_directory (directory_view, directory); nautilus_directory_unref (directory); @@ -2733,6 +2748,7 @@ done_loading_callback (NautilusDirectory static void load_error_callback (NautilusDirectory *directory, GnomeVFSResult load_error_code, + const char *load_error_message, gpointer callback_data) { FMDirectoryView *view; @@ -2748,11 +2764,11 @@ load_error_callback (NautilusDirectory * * occurred, so they can handle it in the UI. */ g_signal_emit (view, - signals[LOAD_ERROR], 0, load_error_code); + signals[LOAD_ERROR], 0, load_error_code, load_error_message); } static void -real_load_error (FMDirectoryView *view, GnomeVFSResult result) +real_load_error (FMDirectoryView *view, GnomeVFSResult result, const char *error_message) { g_assert (result != GNOME_VFS_OK); @@ -2765,7 +2781,7 @@ real_load_error (FMDirectoryView *view, if (!view->details->reported_load_error) { fm_report_error_loading_directory (fm_directory_view_get_directory_as_file (view), - result, + result, error_message, fm_directory_view_get_containing_window (view)); } view->details->reported_load_error = TRUE; @@ -8017,11 +8033,29 @@ fm_directory_view_is_empty (FMDirectoryV is_empty, (view)); } +gboolean +fm_directory_view_is_editable (FMDirectoryView *view) +{ + NautilusDirectory *directory; + + directory = fm_directory_view_get_model (view); + + if (directory != NULL) { + return nautilus_directory_is_editable (directory); + } + + return TRUE; +} + static gboolean real_is_read_only (FMDirectoryView *view) { NautilusFile *file; - + + if (!fm_directory_view_is_editable (view)) { + return TRUE; + } + file = fm_directory_view_get_directory_as_file (view); if (file != NULL) { return !nautilus_file_can_write (file); @@ -8076,7 +8110,7 @@ real_accepts_dragged_files (FMDirectoryV { g_return_val_if_fail (FM_IS_DIRECTORY_VIEW (view), FALSE); - return TRUE; + return !fm_directory_view_is_read_only (view); } gboolean @@ -8852,8 +8886,8 @@ fm_directory_view_class_init (FMDirector G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (FMDirectoryViewClass, load_error), NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); + nautilus_marshal_VOID__INT_STRING, + G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING); signals[REMOVE_FILE] = g_signal_new ("remove_file", G_TYPE_FROM_CLASS (klass), diff -ruNp nautilus-2.12.2/src/file-manager/fm-directory-view.h nautilus-2.12.2.joe/src/file-manager/fm-directory-view.h --- nautilus-2.12.2/src/file-manager/fm-directory-view.h 2005-11-14 15:46:57.000000000 +0100 +++ nautilus-2.12.2.joe/src/file-manager/fm-directory-view.h 2006-04-14 23:02:12.450502925 +0200 @@ -118,7 +118,8 @@ struct FMDirectoryViewClass { * load failures like ACCESS_DENIED. */ void (* load_error) (FMDirectoryView *view, - GnomeVFSResult result); + GnomeVFSResult result, + const char *error_message); /* Function pointers that don't have corresponding signals */ @@ -374,6 +375,7 @@ NautilusDirectory *fm_directory_view_ge GtkWindow *fm_directory_view_get_containing_window (FMDirectoryView *view); NautilusFile *fm_directory_view_get_directory_as_file (FMDirectoryView *view); EelBackground * fm_directory_view_get_background (FMDirectoryView *view); +gboolean fm_directory_view_get_allow_moves (FMDirectoryView *view); void fm_directory_view_pop_up_background_context_menu (FMDirectoryView *view, GdkEventButton *event); void fm_directory_view_pop_up_selection_context_menu (FMDirectoryView *view, @@ -412,4 +414,6 @@ void fm_directory_view_ad void fm_directory_view_remove_subdirectory (FMDirectoryView *view, NautilusDirectory*directory); +gboolean fm_directory_view_is_editable (FMDirectoryView *view); + #endif /* FM_DIRECTORY_VIEW_H */ diff -ruNp nautilus-2.12.2/src/file-manager/fm-error-reporting.c nautilus-2.12.2.joe/src/file-manager/fm-error-reporting.c --- nautilus-2.12.2/src/file-manager/fm-error-reporting.c 2003-12-11 11:38:16.000000000 +0100 +++ nautilus-2.12.2.joe/src/file-manager/fm-error-reporting.c 2006-04-14 23:02:12.459501361 +0200 @@ -41,31 +41,36 @@ static void cancel_rename (NautilusFile void fm_report_error_loading_directory (NautilusFile *file, GnomeVFSResult error, + const char *error_message, GtkWindow *parent_window) { char *file_name; char *message; - if (error == GNOME_VFS_OK) { + if (error_message == NULL && error == GNOME_VFS_OK) { return; } file_name = nautilus_file_get_display_name (file); - switch (error) { - case GNOME_VFS_ERROR_ACCESS_DENIED: - message = g_strdup_printf (_("You do not have the permissions necessary to view the contents of \"%s\"."), - file_name); - break; - case GNOME_VFS_ERROR_NOT_FOUND: - message = g_strdup_printf (_("\"%s\" couldn't be found. Perhaps it has recently been deleted."), - file_name); - break; - default: - /* We should invent decent error messages for every case we actually experience. */ - g_warning ("Hit unhandled case %d (%s) in fm_report_error_loading_directory", - error, gnome_vfs_result_to_string (error)); - message = g_strdup_printf (_("Sorry, couldn't display all the contents of \"%s\"."), file_name); + if (!error_message) { + switch (error) { + case GNOME_VFS_ERROR_ACCESS_DENIED: + message = g_strdup_printf (_("You do not have the permissions necessary to view the contents of \"%s\"."), + file_name); + break; + case GNOME_VFS_ERROR_NOT_FOUND: + message = g_strdup_printf (_("\"%s\" couldn't be found. Perhaps it has recently been deleted."), + file_name); + break; + default: + /* We should invent decent error messages for every case we actually experience. */ + g_warning ("Hit unhandled case %d (%s) in fm_report_error_loading_directory", + error, gnome_vfs_result_to_string (error)); + message = g_strdup_printf (_("Sorry, couldn't display all the contents of \"%s\"."), file_name); + } + } else { + message = g_strdup (error_message); } eel_show_error_dialog (_("The folder contents could not be displayed."), message, diff -ruNp nautilus-2.12.2/src/file-manager/fm-error-reporting.h nautilus-2.12.2.joe/src/file-manager/fm-error-reporting.h --- nautilus-2.12.2/src/file-manager/fm-error-reporting.h 2002-02-21 20:26:52.000000000 +0100 +++ nautilus-2.12.2.joe/src/file-manager/fm-error-reporting.h 2006-04-14 23:02:12.466500144 +0200 @@ -32,6 +32,7 @@ void fm_report_error_loading_directory (NautilusFile *file, GnomeVFSResult error_code, + const char *error_message, GtkWindow *parent_window); void fm_report_error_renaming_file (NautilusFile *file, const char *new_name, diff -ruNp nautilus-2.12.2/src/file-manager/fm-icon-view.c nautilus-2.12.2.joe/src/file-manager/fm-icon-view.c --- nautilus-2.12.2/src/file-manager/fm-icon-view.c 2005-11-14 15:46:57.000000000 +0100 +++ nautilus-2.12.2.joe/src/file-manager/fm-icon-view.c 2006-04-14 23:02:12.483497190 +0200 @@ -1055,6 +1055,9 @@ fm_icon_view_begin_loading (FMDirectoryV file = fm_directory_view_get_directory_as_file (view); icon_container = GTK_WIDGET (get_icon_container (icon_view)); + nautilus_icon_container_set_allow_moves (NAUTILUS_ICON_CONTAINER (icon_container), + fm_directory_view_get_allow_moves (view)); + /* kill any sound preview process that is ongoing */ preview_audio (icon_view, NULL, FALSE); @@ -1533,6 +1536,7 @@ fm_icon_view_update_menus (FMDirectoryVi int selection_count; GtkAction *action; NautilusIconContainer *icon_container; + gboolean editable; icon_view = FM_ICON_VIEW (view); @@ -1559,8 +1563,13 @@ fm_icon_view_update_menus (FMDirectoryVi gtk_action_set_sensitive (action, icon_container != NULL && nautilus_icon_container_is_stretched (icon_container)); - + nautilus_file_list_free (selection); + + editable = fm_directory_view_is_editable (view); + action = gtk_action_group_get_action (icon_view->details->icon_action_group, + FM_ACTION_MANUAL_LAYOUT); + gtk_action_set_sensitive (action, editable); } static void diff -ruNp nautilus-2.12.2/src/Makefile.am nautilus-2.12.2.joe/src/Makefile.am --- nautilus-2.12.2/src/Makefile.am 2005-07-08 13:25:50.000000000 +0200 +++ nautilus-2.12.2.joe/src/Makefile.am 2006-04-14 23:02:12.491495799 +0200 @@ -99,6 +99,8 @@ nautilus_SOURCES = \ nautilus-places-sidebar.h \ nautilus-property-browser.c \ nautilus-property-browser.h \ + nautilus-search-bar.c \ + nautilus-search-bar.h \ nautilus-self-check-functions.c \ nautilus-self-check-functions.h \ nautilus-shell.c \ diff -ruNp nautilus-2.12.2/src/nautilus-actions.h nautilus-2.12.2.joe/src/nautilus-actions.h --- nautilus-2.12.2/src/nautilus-actions.h 2005-07-11 10:52:21.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-actions.h 2006-04-14 23:02:12.497494757 +0200 @@ -42,5 +42,6 @@ #define NAUTILUS_ACTION_ZOOM_OUT "Zoom Out" #define NAUTILUS_ACTION_ZOOM_NORMAL "Zoom Normal" #define NAUTILUS_ACTION_CLOSE "Close" +#define NAUTILUS_ACTION_SEARCH "Search" #endif /* NAUTILUS_ACTIONS_H */ diff -ruNp nautilus-2.12.2/src/nautilus-bookmark-list.c nautilus-2.12.2.joe/src/nautilus-bookmark-list.c --- nautilus-2.12.2/src/nautilus-bookmark-list.c 2005-08-12 20:11:30.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-bookmark-list.c 2006-04-14 23:02:12.506493193 +0200 @@ -31,10 +31,12 @@ #include <eel/eel-glib-extensions.h> #include <eel/eel-gtk-macros.h> #include <eel/eel-string.h> +#include <eel/eel-vfs-extensions.h> #include <eel/eel-xml-extensions.h> #include <gtk/gtksignal.h> #include <libnautilus-private/nautilus-file-utilities.h> #include <libnautilus-private/nautilus-icon-factory.h> +#include <libnautilus-private/nautilus-search-directory.h> #include <libgnome/gnome-macros.h> #include <libgnome/gnome-util.h> #include <libgnomevfs/gnome-vfs-types.h> @@ -513,6 +515,21 @@ nautilus_bookmark_list_new (void) return list; } +static void +save_search_for_uri (const char *uri) +{ + NautilusDirectory *directory; + NautilusSearchDirectory *search; + + directory = nautilus_directory_get (uri); + + g_assert (NAUTILUS_IS_SEARCH_DIRECTORY (directory)); + + search = NAUTILUS_SEARCH_DIRECTORY (directory); + + nautilus_search_directory_save_search (search); +} + /** * nautilus_bookmark_list_save_file: * @@ -543,19 +560,20 @@ nautilus_bookmark_list_save_file (Nautil GList *l; for (l = bookmarks->list; l; l = l->next) { + char *uri; char *bookmark_string; bookmark = NAUTILUS_BOOKMARK (l->data); + + uri = nautilus_bookmark_get_uri (bookmark); /* make sure we save label if it has one for compatibility with GTK 2.7 and 2.8 */ if (nautilus_bookmark_get_has_custom_name (bookmark)) { - char *label, *uri; + char *label; label = nautilus_bookmark_get_name (bookmark); - uri = nautilus_bookmark_get_uri (bookmark); bookmark_string = g_strconcat (uri, " ", label, NULL); - g_free (uri); g_free (label); } else { - bookmark_string = nautilus_bookmark_get_uri (bookmark); + bookmark_string = g_strdup (uri); } if (fputs (bookmark_string, file) == EOF || fputs ("\n", file) == EOF) { saved_errno = errno; @@ -564,6 +582,15 @@ nautilus_bookmark_list_save_file (Nautil goto io_error; } g_free (bookmark_string); + + /* + * Rather gross hack to save out searches at the same + * time as the bookmarks. + */ + if (eel_uri_is_search (uri)) + save_search_for_uri (uri); + + g_free (uri); } if (fclose (file) == EOF) { diff -ruNp nautilus-2.12.2/src/nautilus-location-bar.c nautilus-2.12.2.joe/src/nautilus-location-bar.c --- nautilus-2.12.2/src/nautilus-location-bar.c 2005-08-03 13:28:58.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-location-bar.c 2006-04-14 23:02:12.515491628 +0200 @@ -497,12 +497,17 @@ nautilus_location_bar_set_location (Naut /* Note: This is called in reaction to external changes, and * thus should not emit the LOCATION_CHANGED signal. */ - - formatted_location = eel_format_uri_for_display (location); - nautilus_entry_set_text (NAUTILUS_ENTRY (bar->details->entry), - formatted_location); - set_position_and_selection_to_end (GTK_EDITABLE (bar->details->entry)); - g_free (formatted_location); + + if (eel_uri_is_search (location)) { + nautilus_location_entry_set_special_text (NAUTILUS_LOCATION_ENTRY (bar->details->entry), + ""); + } else { + formatted_location = eel_format_uri_for_display (location); + nautilus_entry_set_text (NAUTILUS_ENTRY (bar->details->entry), + formatted_location); + set_position_and_selection_to_end (GTK_EDITABLE (bar->details->entry)); + g_free (formatted_location); + } /* free up the cached file info from the previous location */ g_free (bar->details->current_directory); diff -ruNp nautilus-2.12.2/src/nautilus-location-entry.c nautilus-2.12.2.joe/src/nautilus-location-entry.c --- nautilus-2.12.2/src/nautilus-location-entry.c 2005-07-02 16:50:36.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-location-entry.c 2006-04-14 23:02:12.524490064 +0200 @@ -60,6 +60,10 @@ struct NautilusLocationEntryDetails { GList *file_info_list; guint idle_id; + + gboolean has_special_text; + gboolean setting_special_text; + gchar *special_text; }; static void nautilus_location_entry_class_init (NautilusLocationEntryClass *class); @@ -431,6 +435,7 @@ finalize (GObject *object) entry = NAUTILUS_LOCATION_ENTRY (object); + g_free (entry->details->special_text); g_free (entry->details); EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); @@ -461,11 +466,42 @@ destroy (GtkObject *object) } static void +nautilus_location_entry_text_changed (NautilusLocationEntry *entry, + GParamSpec *pspec) +{ + if (entry->details->setting_special_text) { + return; + } + + entry->details->has_special_text = FALSE; +} + +static gboolean +nautilus_location_entry_focus_in (GtkWidget *widget, + GdkEventFocus *event) +{ + NautilusLocationEntry *entry = NAUTILUS_LOCATION_ENTRY (widget); + + if (entry->details->has_special_text) { + entry->details->setting_special_text = TRUE; + gtk_entry_set_text (GTK_ENTRY (entry), ""); + entry->details->setting_special_text = FALSE; + } + + return EEL_CALL_PARENT_WITH_RETURN_VALUE (GTK_WIDGET_CLASS, focus_in_event, (widget, event)); +} + +static void nautilus_location_entry_class_init (NautilusLocationEntryClass *class) { + GtkWidgetClass *widget_class; GObjectClass *gobject_class; GtkObjectClass *object_class; + widget_class = GTK_WIDGET_CLASS (class); + + widget_class->focus_in_event = nautilus_location_entry_focus_in; + gobject_class = G_OBJECT_CLASS (class); gobject_class->finalize = finalize; @@ -483,6 +519,9 @@ nautilus_location_entry_init (NautilusLo g_signal_connect (entry, "event_after", G_CALLBACK (editable_event_after_callback), entry); + g_signal_connect (entry, "notify::text", + G_CALLBACK (nautilus_location_entry_text_changed), NULL); + } GtkWidget * @@ -494,3 +533,18 @@ nautilus_location_entry_new (void) return entry; } + +void +nautilus_location_entry_set_special_text (NautilusLocationEntry *entry, + const char *special_text) +{ + entry->details->has_special_text = TRUE; + + g_free (entry->details->special_text); + entry->details->special_text = g_strdup (special_text); + + entry->details->setting_special_text = TRUE; + gtk_entry_set_text (GTK_ENTRY (entry), special_text); + entry->details->setting_special_text = FALSE; +} + diff -ruNp nautilus-2.12.2/src/nautilus-location-entry.h nautilus-2.12.2.joe/src/nautilus-location-entry.h --- nautilus-2.12.2/src/nautilus-location-entry.h 2003-10-11 19:26:39.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-location-entry.h 2006-04-14 23:02:12.531488848 +0200 @@ -50,5 +50,7 @@ typedef struct { GType nautilus_location_entry_get_type (void); GtkWidget* nautilus_location_entry_new (void); +void nautilus_location_entry_set_special_text (NautilusLocationEntry *entry, + const char *special_text); #endif /* NAUTILUS_LOCATION_ENTRY_H */ diff -ruNp nautilus-2.12.2/src/nautilus-navigation-window.c nautilus-2.12.2.joe/src/nautilus-navigation-window.c --- nautilus-2.12.2/src/nautilus-navigation-window.c 2005-10-27 09:25:53.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-navigation-window.c 2006-04-14 23:05:04.407611458 +0200 @@ -38,6 +38,7 @@ #include "nautilus-signaller.h" #include "nautilus-location-bar.h" #include "nautilus-pathbar.h" +#include "nautilus-search-bar.h" #include "nautilus-window-manage-views.h" #include "nautilus-zoom-control.h" #include <eel/eel-accessibility.h> @@ -48,6 +49,7 @@ #include <eel/eel-gtk-macros.h> #include <eel/eel-stock-dialogs.h> #include <eel/eel-string.h> +#include <eel/eel-vfs-extensions.h> #include <gdk-pixbuf/gdk-pixbuf.h> #include <gdk/gdkx.h> #include <gtk/gtkmain.h> @@ -79,6 +81,7 @@ #include <libnautilus-private/nautilus-undo.h> #include <libnautilus-private/nautilus-module.h> #include <libnautilus-private/nautilus-sidebar-provider.h> +#include <libnautilus-private/nautilus-search-directory.h> #include <math.h> #include <sys/time.h> @@ -97,6 +100,12 @@ #define MENU_PATH_BOOKMARKS_PLACEHOLDER "/MenuBar/Other Menus/Bookmarks/Bookmarks Placeholder" +typedef enum { + NAUTILUS_BAR_PATH, + NAUTILUS_BAR_NAVIGATION, + NAUTILUS_BAR_SEARCH +} NautilusBarMode; + enum { ARG_0, ARG_APP_ID, @@ -114,11 +123,17 @@ static void navigation_bar_location_chan NautilusNavigationWindow *window); static void navigation_bar_cancel_callback (GtkWidget *widget, NautilusNavigationWindow *window); +static void search_bar_activate_callback (NautilusSearchBar *bar, + NautilusWindow *window); +static void search_bar_cancel_callback (GtkWidget *widget, + NautilusNavigationWindow *window); static void path_bar_location_changed_callback (GtkWidget *widget, const char *uri, NautilusNavigationWindow *window); static void always_use_location_entry_changed (gpointer callback_data); +static void nautilus_navigation_window_set_bar_mode (NautilusNavigationWindow *window, + NautilusBarMode mode); GNOME_CLASS_BOILERPLATE (NautilusNavigationWindow, nautilus_navigation_window, NautilusWindow, NAUTILUS_TYPE_WINDOW) @@ -205,6 +220,16 @@ nautilus_navigation_window_instance_init window->navigation_bar, TRUE, TRUE, 0); + window->search_bar = nautilus_search_bar_new (); + g_signal_connect_object (window->search_bar, "activate", + G_CALLBACK (search_bar_activate_callback), window, 0); + g_signal_connect_object (window->search_bar, "cancel", + G_CALLBACK (search_bar_cancel_callback), window, 0); + + gtk_box_pack_start (GTK_BOX (hbox), + window->search_bar, + TRUE, TRUE, 0); + /* Option menu for content view types; it's empty here, filled in when a uri is set. * Pack it into vbox so it doesn't grow vertically when location bar does. */ @@ -268,9 +293,9 @@ always_use_location_entry_changed (gpoin window = NAUTILUS_NAVIGATION_WINDOW (callback_data); if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY)) { - nautilus_navigation_window_hide_path_bar (window); + nautilus_navigation_window_set_bar_mode (window, NAUTILUS_BAR_NAVIGATION); } else { - nautilus_navigation_window_show_path_bar (window); + nautilus_navigation_window_set_bar_mode (window, NAUTILUS_BAR_PATH); } } @@ -329,11 +354,23 @@ hide_temporary_bars (NautilusNavigationW window->details->temporary_location_bar = FALSE; } if (window->details->temporary_navigation_bar) { - if (!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY)) { - nautilus_navigation_window_show_path_bar (window); + if (NAUTILUS_WINDOW (window)->details->search_mode) { + nautilus_navigation_window_set_bar_mode (window, NAUTILUS_BAR_SEARCH); + } else { + if (!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY)) { + nautilus_navigation_window_set_bar_mode (window, NAUTILUS_BAR_PATH); + } } window->details->temporary_navigation_bar = FALSE; } + if (window->details->temporary_search_bar) { + if (!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY)) { + nautilus_navigation_window_set_bar_mode (window, NAUTILUS_BAR_PATH); + } else { + nautilus_navigation_window_set_bar_mode (window, NAUTILUS_BAR_NAVIGATION); + } + window->details->temporary_search_bar = FALSE; + } } static void @@ -353,6 +390,42 @@ navigation_bar_cancel_callback (GtkWidge } static void +search_bar_activate_callback (NautilusSearchBar *bar, + NautilusWindow *window) +{ + char *uri; + NautilusDirectory *directory; + NautilusSearchDirectory *search_directory; + NautilusQuery *query; + + uri = nautilus_search_directory_generate_new_uri (); + nautilus_window_go_to (window, uri); + g_free (uri); + + directory = nautilus_directory_get_for_file (window->details->viewed_file); + + g_assert (NAUTILUS_IS_SEARCH_DIRECTORY (directory)); + + search_directory = NAUTILUS_SEARCH_DIRECTORY (directory); + query = nautilus_search_bar_get_query (bar); + + nautilus_search_directory_set_query (search_directory, query); + if (query) { + g_object_unref (query); + } + nautilus_window_reload (window); + + nautilus_directory_unref (directory); +} + +static void +search_bar_cancel_callback (GtkWidget *widget, + NautilusNavigationWindow *window) +{ + hide_temporary_bars (window); +} + +static void side_pane_close_requested_callback (GtkWidget *widget, gpointer user_data) { @@ -888,15 +961,20 @@ real_set_throbber_active (NautilusWindow } static void -nautilus_navigation_window_show_location_bar_temporarily (NautilusNavigationWindow *window, - gboolean in_search_mode) +nautilus_navigation_window_show_location_bar_temporarily (NautilusNavigationWindow *window) { if (!nautilus_navigation_window_location_bar_showing (window)) { nautilus_navigation_window_show_location_bar (window, FALSE); window->details->temporary_location_bar = TRUE; } - if (nautilus_navigation_window_path_bar_showing (window)) { - nautilus_navigation_window_hide_path_bar (window); +} + +static void +nautilus_navigation_window_show_navigation_bar_temporarily (NautilusNavigationWindow *window) +{ + if (nautilus_navigation_window_path_bar_showing (window) + || nautilus_navigation_window_search_bar_showing (window)) { + nautilus_navigation_window_set_bar_mode (window, NAUTILUS_BAR_NAVIGATION); window->details->temporary_navigation_bar = TRUE; } nautilus_navigation_bar_activate @@ -906,7 +984,33 @@ nautilus_navigation_window_show_location static void real_prompt_for_location (NautilusWindow *window) { - nautilus_navigation_window_show_location_bar_temporarily (NAUTILUS_NAVIGATION_WINDOW (window), FALSE); + nautilus_navigation_window_show_location_bar_temporarily (NAUTILUS_NAVIGATION_WINDOW (window)); + nautilus_navigation_window_show_navigation_bar_temporarily (NAUTILUS_NAVIGATION_WINDOW (window)); +} + +static void +real_set_search_mode (NautilusWindow *window, gboolean search_mode) +{ + NautilusNavigationWindow *nav_window; + + nav_window = NAUTILUS_NAVIGATION_WINDOW (window); + + if (!search_mode) { + nav_window->details->temporary_search_bar = TRUE; + hide_temporary_bars (nav_window); + return; + } + + nautilus_navigation_window_show_location_bar_temporarily (nav_window); + + if (nautilus_navigation_window_search_bar_showing (nav_window)) { + nav_window->details->temporary_search_bar = FALSE; + } else { + nav_window->details->temporary_search_bar = TRUE; + } + + nautilus_navigation_window_set_bar_mode (nav_window, NAUTILUS_BAR_SEARCH); + nautilus_search_bar_grab_focus (NAUTILUS_SEARCH_BAR (nav_window->search_bar)); } void @@ -1015,19 +1119,40 @@ nautilus_navigation_window_location_bar_ return TRUE; } -void -nautilus_navigation_window_hide_path_bar (NautilusNavigationWindow *window) +gboolean +nautilus_navigation_window_search_bar_showing (NautilusNavigationWindow *window) { - window->details->temporary_navigation_bar = FALSE; - gtk_widget_hide (window->path_bar); - gtk_widget_show (window->navigation_bar); + if (window->search_bar != NULL) { + return GTK_WIDGET_VISIBLE (window->search_bar); + } + /* If we're not visible yet we haven't changed visibility, so its TRUE */ + return TRUE; } -void -nautilus_navigation_window_show_path_bar (NautilusNavigationWindow *window) +static void +nautilus_navigation_window_set_bar_mode (NautilusNavigationWindow *window, + NautilusBarMode mode) { - gtk_widget_show (window->path_bar); - gtk_widget_hide (window->navigation_bar); + switch (mode) { + + case NAUTILUS_BAR_PATH: + gtk_widget_show (window->path_bar); + gtk_widget_hide (window->navigation_bar); + gtk_widget_hide (window->search_bar); + break; + + case NAUTILUS_BAR_NAVIGATION: + gtk_widget_show (window->navigation_bar); + gtk_widget_hide (window->path_bar); + gtk_widget_hide (window->search_bar); + break; + + case NAUTILUS_BAR_SEARCH: + gtk_widget_show (window->search_bar); + gtk_widget_hide (window->path_bar); + gtk_widget_hide (window->navigation_bar); + break; + } } gboolean @@ -1206,10 +1331,12 @@ nautilus_navigation_window_show (GtkWidg nautilus_navigation_window_hide_location_bar (window, FALSE); } - if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY)) { - nautilus_navigation_window_hide_path_bar (window); - } else { - nautilus_navigation_window_show_path_bar (window); + if (!nautilus_navigation_window_search_bar_showing (window)) { + if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY)) { + nautilus_navigation_window_set_bar_mode (window, NAUTILUS_BAR_NAVIGATION); + } else { + nautilus_navigation_window_set_bar_mode (window, NAUTILUS_BAR_PATH); + } } if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_START_WITH_SIDEBAR)) { @@ -1282,8 +1409,9 @@ nautilus_navigation_window_class_init (N NAUTILUS_WINDOW_CLASS (class)->set_content_view_widget = real_set_content_view_widget; NAUTILUS_WINDOW_CLASS (class)->set_throbber_active = real_set_throbber_active; NAUTILUS_WINDOW_CLASS (class)->prompt_for_location = real_prompt_for_location; + NAUTILUS_WINDOW_CLASS (class)->set_search_mode = real_set_search_mode; NAUTILUS_WINDOW_CLASS (class)->set_title = real_set_title; NAUTILUS_WINDOW_CLASS (class)->get_icon_name = real_get_icon_name; - NAUTILUS_WINDOW_CLASS(class)->get_default_size = real_get_default_size; + NAUTILUS_WINDOW_CLASS (class)->get_default_size = real_get_default_size; NAUTILUS_WINDOW_CLASS (class)->close = real_window_close; } diff -ruNp nautilus-2.12.2/src/nautilus-navigation-window.h nautilus-2.12.2.joe/src/nautilus-navigation-window.h --- nautilus-2.12.2/src/nautilus-navigation-window.h 2005-07-08 13:25:51.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-navigation-window.h 2006-04-14 23:02:12.552485198 +0200 @@ -60,6 +60,7 @@ struct _NautilusNavigationWindow { GtkWidget *view_as_option_menu; GtkWidget *navigation_bar; GtkWidget *path_bar; + GtkWidget *search_bar; /* Back/Forward chain, and history list. * The data in these lists are NautilusBookmark pointers. @@ -97,6 +98,8 @@ void nautilus_navigation_window_hide void nautilus_navigation_window_show_path_bar (NautilusNavigationWindow *window); gboolean nautilus_navigation_window_path_bar_showing (NautilusNavigationWindow *window); +gboolean nautilus_navigation_window_search_bar_showing (NautilusNavigationWindow *window); + gboolean nautilus_navigation_window_location_bar_showing (NautilusNavigationWindow *window); void nautilus_navigation_window_hide_toolbar (NautilusNavigationWindow *window); void nautilus_navigation_window_show_toolbar (NautilusNavigationWindow *window); diff -ruNp nautilus-2.12.2/src/nautilus-navigation-window-menus.c nautilus-2.12.2.joe/src/nautilus-navigation-window-menus.c --- nautilus-2.12.2/src/nautilus-navigation-window-menus.c 2005-10-27 09:25:53.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-navigation-window-menus.c 2006-04-14 23:02:12.562483460 +0200 @@ -60,6 +60,7 @@ #include <libnautilus-private/nautilus-ui-utilities.h> #include <libnautilus-private/nautilus-icon-factory.h> #include <libnautilus-private/nautilus-undo-manager.h> +#include <libnautilus-private/nautilus-search-engine.h> #define MENU_PATH_HISTORY_PLACEHOLDER "/MenuBar/Other Menus/Go/History Placeholder" @@ -231,6 +232,13 @@ nautilus_navigation_window_update_show_h NAUTILUS_ACTION_SHOW_HIDE_STATUSBAR); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), nautilus_navigation_window_status_bar_showing (window)); + + if (!nautilus_search_engine_enabled ()) { + action = gtk_action_group_get_action (window->details->navigation_action_group, + NAUTILUS_ACTION_SEARCH); + gtk_action_set_sensitive (action, FALSE); + gtk_action_set_visible (action, FALSE); + } } static void @@ -412,6 +420,17 @@ action_go_to_location_callback (GtkActio nautilus_window_prompt_for_location (window); } +static void +action_search_callback (GtkAction *action, + gpointer user_data) +{ + NautilusWindow *window; + + window = NAUTILUS_WINDOW (user_data); + + nautilus_window_set_search_mode (window, TRUE); +} + static const GtkActionEntry navigation_entries[] = { { "Go", NULL, N_("_Go") }, /* name, stock id, label */ { "Bookmarks", NULL, N_("_Bookmarks") }, /* name, stock id, label */ @@ -433,6 +452,10 @@ static const GtkActionEntry navigation_e { "Edit Bookmarks", NULL, N_("_Edit Bookmarks"), /* name, stock id, label */ "<control>b", N_("Display a window that allows editing the bookmarks in this menu"), G_CALLBACK (action_edit_bookmarks_callback) }, + { "Search", "gtk-find", N_("_Search"), /* name, stock id, label */ + "<control>F", N_("Search for files"), + G_CALLBACK (action_search_callback) }, + }; static const GtkToggleActionEntry navigation_toggle_entries[] = { diff -ruNp nautilus-2.12.2/src/nautilus-navigation-window-ui.xml nautilus-2.12.2.joe/src/nautilus-navigation-window-ui.xml --- nautilus-2.12.2/src/nautilus-navigation-window-ui.xml 2005-07-11 10:52:21.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-navigation-window-ui.xml 2006-04-14 23:02:12.571481896 +0200 @@ -31,6 +31,7 @@ <menuitem name="Go to Trash" action="Go to Trash"/> <menuitem name="Go to Burn CD" action="Go to Burn CD"/> <menuitem name="Go to Location" action="Go to Location"/> + <menuitem name="Search" action="Search"/> <separator/> <menuitem name="Clear History" action="Clear History"/> <separator/> @@ -54,7 +55,8 @@ <separator/> <toolitem name="Home" action="Home"/> <toolitem name="Computer" action="Go to Computer"/> - + <separator/> + <toolitem name="Search" action="Search"/> <placeholder name="Extra Buttons Placeholder"> <placeholder name="Extension Actions"/> </placeholder> diff -ruNp nautilus-2.12.2/src/nautilus-pathbar.c nautilus-2.12.2.joe/src/nautilus-pathbar.c --- nautilus-2.12.2/src/nautilus-pathbar.c 2005-07-26 01:43:25.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-pathbar.c 2006-04-14 23:02:12.584479637 +0200 @@ -24,6 +24,7 @@ #include <eel/eel-glib-extensions.h> #include <eel/eel-preferences.h> #include <eel/eel-string.h> +#include <eel/eel-vfs-extensions.h> #include <gtk/gtktogglebutton.h> #include <gtk/gtkalignment.h> #include <gtk/gtkarrow.h> @@ -50,7 +51,7 @@ typedef enum { ROOT_BUTTON, HOME_BUTTON, DESKTOP_BUTTON, - VOLUME_BUTTON + VOLUME_BUTTON, } ButtonType; #define BUTTON_DATA(x) ((ButtonData *)(x)) @@ -1293,7 +1294,7 @@ find_button_type (NautilusPathBar *path } if (is_file_path_mounted_volume (path, button_data)) { return VOLUME_BUTTON; - } + } return NORMAL_BUTTON; } diff -ruNp nautilus-2.12.2/src/nautilus-places-sidebar.c nautilus-2.12.2.joe/src/nautilus-places-sidebar.c --- nautilus-2.12.2/src/nautilus-places-sidebar.c 2005-10-27 09:25:53.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-places-sidebar.c 2006-04-14 23:02:12.594477899 +0200 @@ -28,6 +28,7 @@ #include <eel/eel-glib-extensions.h> #include <eel/eel-preferences.h> #include <eel/eel-string.h> +#include <eel/eel-vfs-extensions.h> #include <gtk/gtkalignment.h> #include <gtk/gtkbutton.h> #include <gtk/gtkvbox.h> @@ -45,11 +46,13 @@ #include <libnautilus-private/nautilus-sidebar-provider.h> #include <libnautilus-private/nautilus-module.h> #include <libnautilus-private/nautilus-file-utilities.h> +#include <libnautilus-private/nautilus-search-directory.h> #include <libgnomevfs/gnome-vfs-utils.h> #include <libgnomevfs/gnome-vfs-volume-monitor.h> #include "nautilus-bookmark-list.h" #include "nautilus-places-sidebar.h" +#include "nautilus-window.h" #define NAUTILUS_PLACES_SIDEBAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_PLACES_SIDEBAR, NautilusPlacesSidebarClass)) #define NAUTILUS_IS_PLACES_SIDEBAR(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_PLACES_SIDEBAR)) @@ -86,6 +89,7 @@ enum { }; typedef enum { + PLACES_SEARCH, PLACES_BUILT_IN, PLACES_MOUNTED_VOLUME, PLACES_BOOKMARK, @@ -142,6 +146,18 @@ update_places (NautilusPlacesSidebar *si gtk_list_store_clear (sidebar->store); location = nautilus_window_info_get_current_location (sidebar->window); + if (nautilus_search_engine_enabled ()) { + /* add search item */ + last_iter = add_place (sidebar->store, PLACES_SEARCH, + _("Search"), "gnome-searchtool", NULL); + /* add separator */ + + gtk_list_store_append (sidebar->store, &iter); + gtk_list_store_set (sidebar->store, &iter, + PLACES_SIDEBAR_COLUMN_ROW_TYPE, PLACES_SEPARATOR, + -1); + } + /* add built in bookmarks */ desktop_path = nautilus_get_desktop_directory (); @@ -276,6 +292,7 @@ row_activated_callback (GtkTreeView *tre NautilusPlacesSidebar *sidebar; GtkTreeModel *model; GtkTreeIter iter; + PlaceType place_type; char *uri; sidebar = NAUTILUS_PLACES_SIDEBAR (user_data); @@ -285,6 +302,14 @@ row_activated_callback (GtkTreeView *tre return; } + gtk_tree_model_get + (model, &iter, PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type, -1); + + if (place_type == PLACES_SEARCH) { + nautilus_window_set_search_mode (sidebar->window, TRUE); + return; + } + gtk_tree_model_get (model, &iter, PLACES_SIDEBAR_COLUMN_URI, &uri, -1); diff -ruNp nautilus-2.12.2/src/nautilus-search-bar.c nautilus-2.12.2.joe/src/nautilus-search-bar.c --- nautilus-2.12.2/src/nautilus-search-bar.c 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/src/nautilus-search-bar.c 2006-04-14 23:02:12.601476682 +0200 @@ -0,0 +1,258 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * Copyright (C) 2005 Novell, Inc. + * + * Nautilus is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Nautilus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; see the file COPYING. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Anders Carlsson <andersca@imendio.com> + * + */ + +#include <config.h> +#include "nautilus-search-bar.h" + +#include <glib/gi18n.h> +#include <eel/eel-gtk-macros.h> +#include <gdk/gdkkeysyms.h> +#include <gtk/gtkalignment.h> +#include <gtk/gtkbindings.h> +#include <gtk/gtkbutton.h> +#include <gtk/gtkentry.h> +#include <gtk/gtkframe.h> +#include <gtk/gtkhbox.h> +#include <gtk/gtklabel.h> + +struct NautilusSearchBarDetails { + GtkWidget *entry; + gboolean change_frozen; + guint typing_timeout_id; +}; + +enum { + ACTIVATE, + CANCEL, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +static void nautilus_search_bar_class_init (NautilusSearchBarClass *class); +static void nautilus_search_bar_init (NautilusSearchBar *bar); + +EEL_CLASS_BOILERPLATE (NautilusSearchBar, + nautilus_search_bar, + GTK_TYPE_EVENT_BOX) + +static void +finalize (GObject *object) +{ + NautilusSearchBar *bar; + + bar = NAUTILUS_SEARCH_BAR (object); + + g_free (bar->details); + + EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); +} + +static void +nautilus_search_bar_class_init (NautilusSearchBarClass *class) +{ + GObjectClass *gobject_class; + GtkBindingSet *binding_set; + + gobject_class = G_OBJECT_CLASS (class); + gobject_class->finalize = finalize; + + signals[ACTIVATE] = + g_signal_new ("activate", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NautilusSearchBarClass, activate), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[CANCEL] = + g_signal_new ("cancel", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | GTK_RUN_ACTION, + G_STRUCT_OFFSET (NautilusSearchBarClass, cancel), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + binding_set = gtk_binding_set_by_class (class); + gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0, "cancel", 0); +} + +static gboolean +query_is_valid (NautilusSearchBar *bar) +{ + const char *text; + + text = gtk_entry_get_text (GTK_ENTRY (bar->details->entry)); + + return text != NULL && text[0] != '\0'; +} + +static void +entry_activate_cb (GtkWidget *entry, NautilusSearchBar *bar) +{ + if (bar->details->typing_timeout_id) { + g_source_remove (bar->details->typing_timeout_id); + bar->details->typing_timeout_id = 0; + } + + if (query_is_valid (bar)) { + g_signal_emit (bar, signals[ACTIVATE], 0); + } +} + +static gboolean +typing_timeout_cb (gpointer user_data) +{ + NautilusSearchBar *bar; + + bar = NAUTILUS_SEARCH_BAR (user_data); + + if (query_is_valid (bar)) { + g_signal_emit (bar, signals[ACTIVATE], 0); + } + + bar->details->typing_timeout_id = 0; + + return FALSE; +} + +#define TYPING_TIMEOUT 750 + +static void +entry_changed_cb (GtkWidget *entry, NautilusSearchBar *bar) +{ + if (bar->details->change_frozen) { + return; + } + + if (bar->details->typing_timeout_id) { + g_source_remove (bar->details->typing_timeout_id); + } + + bar->details->typing_timeout_id = + g_timeout_add (TYPING_TIMEOUT, + typing_timeout_cb, + bar); +} + +static void +nautilus_search_bar_init (NautilusSearchBar *bar) +{ + GtkWidget *alignment; + GtkWidget *hbox; + GtkWidget *label; + + bar->details = g_new0 (NautilusSearchBarDetails, 1); + + alignment = gtk_alignment_new (0.5, 0.5, + 1.0, 1.0); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), + 0, 0, 6, 6); + gtk_widget_show (alignment); + gtk_container_add (GTK_CONTAINER (bar), alignment); + + hbox = gtk_hbox_new (FALSE, 6); + gtk_widget_show (hbox); + gtk_container_add (GTK_CONTAINER (alignment), hbox); + + label = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL (label), _("<b>Search:</b>")); + gtk_widget_show (label); + + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + + bar->details->entry = gtk_entry_new (); + gtk_box_pack_start (GTK_BOX (hbox), bar->details->entry, TRUE, TRUE, 0); + + g_signal_connect (bar->details->entry, "activate", + G_CALLBACK (entry_activate_cb), bar); + g_signal_connect (bar->details->entry, "changed", + G_CALLBACK (entry_changed_cb), bar); + + gtk_widget_show (bar->details->entry); +} + +void +nautilus_search_bar_grab_focus (NautilusSearchBar *bar) +{ + gtk_widget_grab_focus (bar->details->entry); +} + +NautilusQuery * +nautilus_search_bar_get_query (NautilusSearchBar *bar) +{ + const char *query_text; + NautilusQuery *query; + + query_text = gtk_entry_get_text (GTK_ENTRY (bar->details->entry)); + + /* Empty string is a NULL query */ + if (query_text && query_text[0] == '\0') { + return NULL; + } + + query = nautilus_query_new (); + nautilus_query_set_text (query, query_text); + + return query; +} + +void +nautilus_search_bar_clear_query (NautilusSearchBar *bar) +{ + bar->details->change_frozen = TRUE; + gtk_entry_set_text (GTK_ENTRY (bar->details->entry), ""); + bar->details->change_frozen = FALSE; +} + +GtkWidget * +nautilus_search_bar_new (void) +{ + GtkWidget *bar; + + bar = g_object_new (NAUTILUS_TYPE_SEARCH_BAR, NULL); + + return bar; +} + +void +nautilus_search_bar_set_query (NautilusSearchBar *bar, NautilusQuery *query) +{ + const char *text; + + if (!query) { + nautilus_search_bar_clear_query (bar); + return; + } + + text = nautilus_query_get_text (query); + if (!text) { + text = ""; + } + + bar->details->change_frozen = TRUE; + gtk_entry_set_text (GTK_ENTRY (bar->details->entry), text); + bar->details->change_frozen = FALSE; +} diff -ruNp nautilus-2.12.2/src/nautilus-search-bar.h nautilus-2.12.2.joe/src/nautilus-search-bar.h --- nautilus-2.12.2/src/nautilus-search-bar.h 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/src/nautilus-search-bar.h 2006-04-14 23:02:12.608475465 +0200 @@ -0,0 +1,61 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * Copyright (C) 2005 Novell, Inc. + * + * Nautilus is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Nautilus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; see the file COPYING. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Anders Carlsson <andersca@imendio.com> + * + */ + +#ifndef NAUTILUS_SEARCH_BAR_H +#define NAUTILUS_SEARCH_BAR_H + +#include <gtk/gtkeventbox.h> +#include <libnautilus-private/nautilus-query.h> + +#define NAUTILUS_TYPE_SEARCH_BAR (nautilus_search_bar_get_type ()) +#define NAUTILUS_SEARCH_BAR(obj) \ + GTK_CHECK_CAST (obj, NAUTILUS_TYPE_SEARCH_BAR, NautilusSearchBar) +#define NAUTILUS_SEARCH_BAR_CLASS(klass) \ + GTK_CHECK_CLASS_CAST (klass, NAUTILUS_TYPE_SEARCH_BAR, NautilusSearchBarClass) +#define NAUTILUS_IS_SEARCH_BAR(obj) \ + GTK_CHECK_TYPE (obj, NAUTILUS_TYPE_SEARCH_BAR) + +typedef struct NautilusSearchBarDetails NautilusSearchBarDetails; + +typedef struct NautilusSearchBar { + GtkEventBox parent; + NautilusSearchBarDetails *details; +} NautilusSearchBar; + +typedef struct { + GtkEventBoxClass parent_class; + + void (* activate) (NautilusSearchBar *bar); + void (* cancel) (NautilusSearchBar *bar); +} NautilusSearchBarClass; + +GType nautilus_search_bar_get_type (void); +GtkWidget* nautilus_search_bar_new (void); + +void nautilus_search_bar_grab_focus (NautilusSearchBar *bar); +void nautilus_search_bar_clear_query (NautilusSearchBar *bar); + +NautilusQuery *nautilus_search_bar_get_query (NautilusSearchBar *bar); +void nautilus_search_bar_set_query (NautilusSearchBar *bar, NautilusQuery *query); + +#endif /* NAUTILUS_SEARCH_BAR_H */ diff -ruNp nautilus-2.12.2/src/nautilus-spatial-window.c nautilus-2.12.2.joe/src/nautilus-spatial-window.c --- nautilus-2.12.2/src/nautilus-spatial-window.c 2005-10-27 09:25:53.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-spatial-window.c 2006-04-14 23:02:12.619473554 +0200 @@ -38,6 +38,7 @@ #include "nautilus-bookmarks-window.h" #include "nautilus-location-dialog.h" #include "nautilus-main.h" +#include "nautilus-search-bar.h" #include "nautilus-signaller.h" #include "nautilus-window-manage-views.h" #include "nautilus-zoom-control.h" @@ -77,6 +78,8 @@ #include <libnautilus-private/nautilus-program-choosing.h> #include <libnautilus-private/nautilus-clipboard.h> #include <libnautilus-private/nautilus-undo.h> +#include <libnautilus-private/nautilus-search-directory.h> +#include <libnautilus-private/nautilus-search-engine.h> #include <math.h> #include <sys/time.h> @@ -97,6 +100,7 @@ struct _NautilusSpatialWindowDetails { GtkWidget *location_button; GtkWidget *location_label; GtkWidget *location_icon; + GtkWidget *search_bar; GnomeVFSURI *location; }; @@ -288,6 +292,10 @@ nautilus_spatial_window_show (GtkWidget window = NAUTILUS_SPATIAL_WINDOW (widget); GTK_WIDGET_CLASS (parent_class)->show (widget); + + if (NAUTILUS_WINDOW (window)->details->search_mode) { + nautilus_search_bar_grab_focus (NAUTILUS_SEARCH_BAR (window->details->search_bar)); + } } static void @@ -313,6 +321,21 @@ real_prompt_for_location (NautilusWindow gtk_widget_show (dialog); } +static void +real_set_search_mode (NautilusWindow *window, gboolean search_mode) +{ + NautilusSpatialWindow *spatial_window; + + spatial_window = NAUTILUS_SPATIAL_WINDOW (window); + + if (search_mode) { + gtk_widget_show (spatial_window->details->search_bar); + } else { + gtk_widget_hide (spatial_window->details->search_bar); + } + nautilus_search_bar_grab_focus (NAUTILUS_SEARCH_BAR (spatial_window->details->search_bar)); +} + static char * real_get_icon_name (NautilusWindow *window) { @@ -575,6 +598,30 @@ location_button_clicked_callback (GtkWid gtk_object_sink (GTK_OBJECT (popup)); } +static void +search_bar_activate_callback (NautilusSearchBar *bar, + NautilusWindow *window) +{ + NautilusDirectory *directory; + NautilusSearchDirectory *search_directory; + NautilusQuery *query; + + directory = nautilus_directory_get_for_file (window->details->viewed_file); + + g_assert (NAUTILUS_IS_SEARCH_DIRECTORY (directory)); + + search_directory = NAUTILUS_SEARCH_DIRECTORY (directory); + query = nautilus_search_bar_get_query (bar); + + nautilus_search_directory_set_query (search_directory, query); + if (query) { + g_object_unref (query); + } + nautilus_window_reload (window); + + nautilus_directory_unref (directory); +} + static int get_dnd_icon_size (NautilusSpatialWindow *window) { @@ -724,6 +771,33 @@ action_edit_bookmarks_callback (GtkActio nautilus_window_edit_bookmarks (NAUTILUS_WINDOW (user_data)); } +static void +action_search_callback (GtkAction *action, + gpointer user_data) +{ + NautilusWindow *window; + NautilusSearchBar *bar; + NautilusQuery *query; + char *uri; + + window = NAUTILUS_WINDOW (user_data); + + if (window->details->search_mode) { + bar = NAUTILUS_SEARCH_BAR (NAUTILUS_SPATIAL_WINDOW (window)->details->search_bar); + + query = nautilus_search_bar_get_query (bar); + + if (query == NULL) { + nautilus_search_bar_grab_focus (bar); + return; + } + } + + uri = nautilus_search_directory_generate_new_uri (); + nautilus_window_go_to (window, uri); + g_free (uri); +} + static const GtkActionEntry spatial_entries[] = { { SPATIAL_ACTION_PLACES, NULL, N_("_Places") }, /* name, stock id, label */ { SPATIAL_ACTION_GO_TO_LOCATION, NULL, N_("Open _Location..."), /* name, stock id, label */ @@ -741,6 +815,9 @@ static const GtkActionEntry spatial_entr { "Edit Bookmarks", NULL, N_("_Edit Bookmarks"), /* name, stock id, label */ "<control>b", N_("Display a window that allows editing the bookmarks in this menu"), G_CALLBACK (action_edit_bookmarks_callback) }, + { "Search", "gtk-find", N_("_Search"), /* name, stock id, label */ + "<control>F", N_("Search for files"), + G_CALLBACK (action_search_callback) }, }; static void @@ -753,12 +830,13 @@ nautilus_spatial_window_instance_init (N GtkUIManager *ui_manager; GtkTargetList *targets; const char *ui; + GtkAction *action; window->details = g_new0 (NautilusSpatialWindowDetails, 1); window->affect_spatial_window_on_next_location_change = TRUE; window->details->content_box = - gtk_hbox_new (FALSE, 0); + gtk_vbox_new (FALSE, 0); gtk_table_attach (GTK_TABLE (NAUTILUS_WINDOW (window)->details->table), window->details->content_box, /* X direction */ /* Y direction */ @@ -767,6 +845,14 @@ nautilus_spatial_window_instance_init (N 0, 0); gtk_widget_show (window->details->content_box); + window->details->search_bar = nautilus_search_bar_new (); + g_signal_connect (window->details->search_bar, + "activate", + G_CALLBACK (search_bar_activate_callback), + window); + gtk_box_pack_start (GTK_BOX (window->details->content_box), + window->details->search_bar, FALSE, FALSE, 0); + window->details->location_button = gtk_button_new (); g_signal_connect (window->details->location_button, "button-press-event", @@ -839,8 +925,12 @@ nautilus_spatial_window_instance_init (N ui = nautilus_ui_string_get ("nautilus-spatial-window-ui.xml"); gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, NULL); - - return; + + if (!nautilus_search_engine_enabled ()) { + action = gtk_action_group_get_action (action_group, NAUTILUS_ACTION_SEARCH); + gtk_action_set_sensitive (action, FALSE); + gtk_action_set_visible (action, FALSE); + } } static void @@ -859,6 +949,8 @@ nautilus_spatial_window_class_init (Naut NAUTILUS_WINDOW_CLASS (class)->prompt_for_location = real_prompt_for_location; + NAUTILUS_WINDOW_CLASS (class)->set_search_mode = + real_set_search_mode; NAUTILUS_WINDOW_CLASS (class)->get_icon_name = real_get_icon_name; NAUTILUS_WINDOW_CLASS (class)->set_title = diff -ruNp nautilus-2.12.2/src/nautilus-spatial-window-ui.xml nautilus-2.12.2.joe/src/nautilus-spatial-window-ui.xml --- nautilus-2.12.2/src/nautilus-spatial-window-ui.xml 2005-06-23 16:16:58.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-spatial-window-ui.xml 2006-04-14 23:02:12.627472163 +0200 @@ -17,6 +17,7 @@ <menuitem name="Go to Templates" action="Go to Templates"/> <menuitem name="Go to Trash" action="Go to Trash"/> <menuitem name="Go to Burn CD" action="Go to Burn CD"/> + <menuitem name="Search" action="Search"/> <separator/> <placeholder name="Bookmarks Placeholder"/> <separator/> diff -ruNp nautilus-2.12.2/src/nautilus-window.c nautilus-2.12.2.joe/src/nautilus-window.c --- nautilus-2.12.2/src/nautilus-window.c 2005-10-27 09:25:53.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-window.c 2006-04-14 23:02:12.639470078 +0200 @@ -40,6 +40,7 @@ #include "nautilus-window-manage-views.h" #include "nautilus-window-bookmarks.h" #include "nautilus-zoom-control.h" +#include "nautilus-search-bar.h" #include <eel/eel-debug.h> #include <eel/eel-marshal.h> #include <eel/eel-gdk-extensions.h> @@ -77,6 +78,7 @@ #include <libnautilus-private/nautilus-view-factory.h> #include <libnautilus-private/nautilus-clipboard.h> #include <libnautilus-private/nautilus-undo.h> +#include <libnautilus-private/nautilus-search-directory.h> #include <math.h> #include <sys/time.h> @@ -142,7 +144,7 @@ nautilus_window_init (NautilusWindow *wi GtkWidget *table; GtkWidget *menu; GtkWidget *statusbar; - + window->details = g_new0 (NautilusWindowDetails, 1); window->details->show_hidden_files_mode = NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT; @@ -150,7 +152,7 @@ nautilus_window_init (NautilusWindow *wi /* Set initial window title */ gtk_window_set_title (GTK_WINDOW (window), _("Nautilus")); - table = gtk_table_new (1, 5, FALSE); + table = gtk_table_new (1, 6, FALSE); window->details->table = table; gtk_widget_show (table); gtk_container_add (GTK_CONTAINER (window), table); @@ -161,7 +163,7 @@ nautilus_window_init (NautilusWindow *wi gtk_table_attach (GTK_TABLE (table), statusbar, /* X direction */ /* Y direction */ - 0, 1, 4, 5, + 0, 1, 5, 6, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0, 0); window->details->help_message_cid = gtk_statusbar_get_context_id @@ -180,7 +182,6 @@ nautilus_window_init (NautilusWindow *wi GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0, 0); - /* Register IconFactory callback to update the window border icon * when the icon-theme is changed. */ @@ -395,6 +396,18 @@ nautilus_window_get_location (NautilusWi } void +nautilus_window_set_search_mode (NautilusWindow *window, gboolean search_mode) +{ + g_assert (NAUTILUS_IS_WINDOW (window)); + + window->details->search_mode = search_mode; + + EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window, + set_search_mode, (window, search_mode)); +} + + +void nautilus_window_zoom_in (NautilusWindow *window) { g_return_if_fail (NAUTILUS_IS_WINDOW (window)); @@ -1036,7 +1049,6 @@ nautilus_window_display_error (NautilusW gtk_widget_show (dialog); } - static char * real_get_title (NautilusWindow *window) { diff -ruNp nautilus-2.12.2/src/nautilus-window.h nautilus-2.12.2.joe/src/nautilus-window.h --- nautilus-2.12.2/src/nautilus-window.h 2005-10-27 09:25:53.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-window.h 2006-04-14 23:02:12.648468514 +0200 @@ -29,8 +29,8 @@ #ifndef NAUTILUS_WINDOW_H #define NAUTILUS_WINDOW_H -#include <bonobo/bonobo-window.h> #include <gtk/gtkuimanager.h> +#include <gtk/gtkwindow.h> #include <eel/eel-glib-extensions.h> #include <libnautilus-private/nautilus-bookmark.h> #include <libnautilus-private/nautilus-window-info.h> @@ -77,6 +77,7 @@ typedef struct { void (* set_allow_up) (NautilusWindow *window, gboolean allow); void (* reload) (NautilusWindow *window); void (* prompt_for_location) (NautilusWindow *window); + void (* set_search_mode) (NautilusWindow *window, gboolean search_mode); void (* get_default_size) (NautilusWindow *window, guint *default_width, guint *default_height); void (* show_window) (NautilusWindow *window); void (* close) (NautilusWindow *window); @@ -127,6 +128,8 @@ void nautilus_window_go_home void nautilus_window_go_up (NautilusWindow *window, gboolean close_behind); void nautilus_window_prompt_for_location (NautilusWindow *window); +void nautilus_window_set_search_mode (NautilusWindow *window, + gboolean search_mode); void nautilus_window_launch_cd_burner (NautilusWindow *window); void nautilus_window_update_title (NautilusWindow *window); void nautilus_window_display_error (NautilusWindow *window, diff -ruNp nautilus-2.12.2/src/nautilus-window-manage-views.c nautilus-2.12.2.joe/src/nautilus-window-manage-views.c --- nautilus-2.12.2/src/nautilus-window-manage-views.c 2005-10-27 09:25:53.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-window-manage-views.c 2006-04-14 23:02:12.663465907 +0200 @@ -31,6 +31,7 @@ #include "nautilus-actions.h" #include "nautilus-application.h" #include "nautilus-location-bar.h" +#include "nautilus-search-bar.h" #include "nautilus-pathbar.h" #include "nautilus-main.h" #include "nautilus-window-private.h" @@ -59,6 +60,7 @@ #include <libnautilus-private/nautilus-metadata.h> #include <libnautilus-private/nautilus-mime-actions.h> #include <libnautilus-private/nautilus-monitor.h> +#include <libnautilus-private/nautilus-search-directory.h> #include <libnautilus-private/nautilus-view-factory.h> #include <libnautilus-private/nautilus-window-info.h> @@ -1131,6 +1133,9 @@ update_for_new_location (NautilusWindow { char *new_location; NautilusFile *file; + gboolean uri_is_search; + NautilusDirectory *directory; + NautilusQuery *query; new_location = window->details->pending_location; window->details->pending_location = NULL; @@ -1168,6 +1173,9 @@ update_for_new_location (NautilusWindow /* Load menus from nautilus extensions for this location */ nautilus_window_load_extension_menus (window); + uri_is_search = eel_uri_is_search (window->details->location); + nautilus_window_set_search_mode (window, uri_is_search); + #if !NEW_UI_COMPLETE if (NAUTILUS_IS_NAVIGATION_WINDOW (window)) { /* Check if the back and forward buttons need enabling or disabling. */ @@ -1180,6 +1188,17 @@ update_for_new_location (NautilusWindow nautilus_path_bar_set_path (NAUTILUS_PATH_BAR (NAUTILUS_NAVIGATION_WINDOW (window)->path_bar), window->details->location); nautilus_navigation_window_load_extension_toolbar_items (NAUTILUS_NAVIGATION_WINDOW (window)); + + if (eel_uri_is_search (window->details->location)) { + directory = nautilus_directory_get (window->details->location); + + query = nautilus_search_directory_get_query (NAUTILUS_SEARCH_DIRECTORY (directory)); + + if (query != NULL) { + nautilus_search_bar_set_query (NAUTILUS_SEARCH_BAR (NAUTILUS_NAVIGATION_WINDOW (window)->search_bar), + query); + } + } } if (NAUTILUS_IS_SPATIAL_WINDOW (window)) { diff -ruNp nautilus-2.12.2/src/nautilus-window-menus.c nautilus-2.12.2.joe/src/nautilus-window-menus.c --- nautilus-2.12.2/src/nautilus-window-menus.c 2005-10-27 09:29:29.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-window-menus.c 2006-04-14 23:02:12.673464169 +0200 @@ -39,6 +39,7 @@ #include "nautilus-window-bookmarks.h" #include "nautilus-window-private.h" #include "nautilus-desktop-window.h" +#include "nautilus-search-bar.h" #include <eel/eel-debug.h> #include <eel/eel-glib-extensions.h> #include <eel/eel-gnome-extensions.h> @@ -64,6 +65,8 @@ #include <libnautilus-private/nautilus-icon-factory.h> #include <libnautilus-private/nautilus-module.h> #include <libnautilus-private/nautilus-undo-manager.h> +#include <libnautilus-private/nautilus-search-directory.h> +#include <libnautilus-private/nautilus-search-engine.h> #define MENU_PATH_EXTENSION_ACTIONS "/MenuBar/File/Extension Actions" #define POPUP_PATH_EXTENSION_ACTIONS "/background/Before Zoom Items/Extension Actions" diff -ruNp nautilus-2.12.2/src/nautilus-window-private.h nautilus-2.12.2.joe/src/nautilus-window-private.h --- nautilus-2.12.2/src/nautilus-window-private.h 2005-07-11 12:23:57.000000000 +0200 +++ nautilus-2.12.2.joe/src/nautilus-window-private.h 2006-04-14 23:02:12.681462778 +0200 @@ -94,6 +94,7 @@ struct NautilusWindowDetails guint location_change_at_idle_id; NautilusWindowShowHiddenFilesMode show_hidden_files_mode; + gboolean search_mode; }; struct _NautilusNavigationWindowDetails { @@ -103,6 +104,7 @@ struct _NautilusNavigationWindowDetails /* Location bar */ gboolean temporary_navigation_bar; gboolean temporary_location_bar; + gboolean temporary_search_bar; /* Side Pane */ int side_pane_width; diff -ruNp nautilus-2.12.2/test/Makefile.am nautilus-2.12.2.joe/test/Makefile.am --- nautilus-2.12.2/test/Makefile.am 2005-01-11 10:39:27.000000000 +0100 +++ nautilus-2.12.2.joe/test/Makefile.am 2006-04-14 23:02:12.689461388 +0200 @@ -14,10 +14,16 @@ LDADD =\ noinst_PROGRAMS =\ test-nautilus-wrap-table \ + test-nautilus-search-engine \ + test-nautilus-directory-async \ $(NULL) test_nautilus_wrap_table_SOURCES = test-nautilus-wrap-table.c test.c +test_nautilus_search_engine_SOURCES = test-nautilus-search-engine.c + +test_nautilus_directory_async_SOURCES = test-nautilus-directory-async.c + EXTRA_DIST = \ test.h \ $(NULL) diff -ruNp nautilus-2.12.2/test/test-nautilus-directory-async.c nautilus-2.12.2.joe/test/test-nautilus-directory-async.c --- nautilus-2.12.2/test/test-nautilus-directory-async.c 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/test/test-nautilus-directory-async.c 2006-04-14 23:02:12.694460519 +0200 @@ -0,0 +1,106 @@ +#include <gtk/gtk.h> +#include <libgnomevfs/gnome-vfs.h> +#include <libnautilus-private/nautilus-directory.h> +#include <libnautilus-private/nautilus-search-directory.h> +#include <libnautilus-private/nautilus-file.h> +#include <unistd.h> + +void *client1, *client2; + +#if 0 +static gboolean +quit_cb (gpointer data) +{ + gtk_main_quit (); + + return FALSE; +} +#endif + +static void +files_added (NautilusDirectory *directory, + GList *added_files) +{ +#if 0 + GList *list; + + for (list = added_files; list != NULL; list = list->next) { + NautilusFile *file = list->data; + + g_print (" - %s\n", nautilus_file_get_uri (file)); + } +#endif + + g_print ("files added: %d files\n", + g_list_length (added_files)); +} + +static void +files_changed (NautilusDirectory *directory, + GList *changed_files) +{ +#if 0 + GList *list; + + for (list = changed_files; list != NULL; list = list->next) { + NautilusFile *file = list->data; + + g_print (" - %s\n", nautilus_file_get_uri (file)); + } +#endif + g_print ("files changed: %d\n", + g_list_length (changed_files)); +} + +static gboolean +force_reload (NautilusDirectory *directory) +{ + g_print ("forcing reload!\n"); + + nautilus_directory_force_reload (directory); + + return FALSE; +} + +static void +done_loading (NautilusDirectory *directory) +{ + static int i = 0; + + g_print ("done loading\n"); + + if (i == 0) { + gtk_timeout_add (5000, (GSourceFunc)force_reload, directory); + i++; + } else { + } +} + +int +main (int argc, char **argv) +{ + NautilusDirectory *directory; + client1 = g_new0 (int, 1); + client2 = g_new0 (int, 1); + NautilusQuery *query; + + gnome_vfs_init (); + gtk_init (&argc, &argv); + + query = nautilus_query_new (); + nautilus_query_set_text (query, "richard hult"); + directory = nautilus_directory_get ("x-nautilus-search://0/"); + nautilus_search_directory_set_query (NAUTILUS_SEARCH_DIRECTORY (directory), query); + g_object_unref (query); + + g_signal_connect (directory, "files-added", G_CALLBACK (files_added), NULL); + g_signal_connect (directory, "files-changed", G_CALLBACK (files_changed), NULL); + g_signal_connect (directory, "done-loading", G_CALLBACK (done_loading), NULL); + nautilus_directory_file_monitor_add (directory, client1, TRUE, TRUE, + NAUTILUS_FILE_ATTRIBUTE_METADATA, + NULL, NULL); + + + gtk_main (); + return 0; +} diff -ruNp nautilus-2.12.2/test/test-nautilus-search-engine.c nautilus-2.12.2.joe/test/test-nautilus-search-engine.c --- nautilus-2.12.2/test/test-nautilus-search-engine.c 1970-01-01 01:00:00.000000000 +0100 +++ nautilus-2.12.2.joe/test/test-nautilus-search-engine.c 2006-04-14 23:02:12.701459302 +0200 @@ -0,0 +1,56 @@ +#include <libnautilus-private/nautilus-search-engine.h> +#include <gtk/gtk.h> + +static void +hits_added_cb (NautilusSearchEngine *engine, GSList *hits) +{ + g_print ("hits added\n"); + while (hits) { + g_print (" - %s\n", (char *)hits->data); + hits = hits->next; + } +} + +static void +hits_subtracted_cb (NautilusSearchEngine *engine, GSList *hits) +{ + g_print ("hits subtracted\n"); + while (hits) { + g_print (" - %s\n", (char *)hits->data); + hits = hits->next; + } +} + +static void +finished_cb (NautilusSearchEngine *engine) +{ + g_print ("finished!\n"); +// gtk_main_quit (); +} + +int +main (int argc, char* argv[]) +{ + NautilusSearchEngine *engine; + NautilusQuery *query; + + gtk_init (&argc, &argv); + + engine = nautilus_search_engine_new (); + g_signal_connect (engine, "hits-added", + G_CALLBACK (hits_added_cb), NULL); + g_signal_connect (engine, "hits-subtracted", + G_CALLBACK (hits_subtracted_cb), NULL); + g_signal_connect (engine, "finished", + G_CALLBACK (finished_cb), NULL); + + query = nautilus_query_new (); + nautilus_query_set_text (query, "richard hult"); + nautilus_search_engine_set_query (engine, query); + g_object_unref (query); + + nautilus_search_engine_start (engine); + + gtk_main (); + return 0; +} --- nautilus-2.12.2/po/POTFILES.in +++ nautilus-2.12.2/po/POTFILES.in @@ -76,6 +76,7 @@ src/nautilus-pathbar.c src/nautilus-places-sidebar.c src/nautilus-property-browser.c +src/nautilus-search-bar.c src/nautilus-shell-ui.xml src/nautilus-shell.c src/nautilus-side-pane.c
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor