I attach new patch with all commented issues fixed, the patch is also in
bugzilla[1].

[1] http://bugzilla.gnome.org/show_bug.cgi?id=328725

Comments about the patch:

Alexander Larsson wrote:
> Sometimes when i switch from icon to list view the "normal" typeahead
> seems to only match at the start of the name.

 Fixed, now the search_equal_func is set in the listview initialization.

> Comments on the code:
> 
> @@ -3861,8 +3864,7 @@ nautilus_icon_container_search_iter (Nau
>                       continue;
>               }
>               
> -             if (strncmp (case_normalized_key, case_normalized_name,
> -                          strlen (case_normalized_key)) == 0) {
> +             if (strcasestr (case_normalized_name, case_normalized_key)) {
>                       count++;
>               }
> 
> 
> This is already case insensitive due to the case normalization!
> strcasestr is a locale-specific function that is absolutely wrong to use
> here.

Now I use strstr after a g_utf8_normalize and g_utf8_casefold as this is
a sane way to do this, that is what original gtktreeview search_func
does, also pointed by this mail[1], for the listview I copied that
function and only changed it to strstr instead of strncmp.

[1]
http://mail.gnome.org/archives/gtk-app-devel-list/2003-March/msg00416.html

>  void
> +action_interactive_search_spatial_callback (GtkAction *action,
> +                                         gpointer   user_data)
> 
> You shouldn't special case views like this in the generic code. If you
> need to, add new view methods.

I reformatted the patch so now we only call
nautilus_view_start_interactive_search() from the spatial callback.

> +  { "Interactive Search", GTK_STOCK_FIND, N_("_Find in this folder"),
> +    "<control>G", N_("Find files in this folder"),
> +    G_CALLBACK (action_interactive_search_spatial_callback) },
> 
> control G is typically "find next". I'm not sure if its the best to use
> in this case.

  Now has CTRL-Z as seems is not used in nautilus.
Index: libnautilus-private/nautilus-icon-container.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-container.c,v
retrieving revision 1.406
diff -p -u -r1.406 nautilus-icon-container.c
--- libnautilus-private/nautilus-icon-container.c       12 Dec 2005 16:59:10 
-0000      1.406
+++ libnautilus-private/nautilus-icon-container.c       26 Jan 2006 01:01:33 
-0000
@@ -3861,8 +3861,7 @@ nautilus_icon_container_search_iter (Nau
                        continue;
                }
                
-               if (strncmp (case_normalized_key, case_normalized_name,
-                            strlen (case_normalized_key)) == 0) {
+               if (strstr (case_normalized_name, case_normalized_key)) {
                        count++;
                }
 
Index: libnautilus-private/nautilus-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-view.c,v
retrieving revision 1.3
diff -p -u -r1.3 nautilus-view.c
--- libnautilus-private/nautilus-view.c 17 May 2005 13:27:29 -0000      1.3
+++ libnautilus-private/nautilus-view.c 26 Jan 2006 01:01:34 -0000
@@ -260,3 +260,13 @@ nautilus_view_pop_up_location_context_me
                (* NAUTILUS_VIEW_GET_IFACE 
(view)->pop_up_location_context_menu) (view, event);
        }
 }
+
+void
+nautilus_view_start_interactive_search (NautilusView   *view)
+{
+       g_return_if_fail (NAUTILUS_IS_VIEW (view));
+
+       if (NAUTILUS_VIEW_GET_IFACE (view)->start_interactive_search != NULL) {
+               (* NAUTILUS_VIEW_GET_IFACE (view)->start_interactive_search) 
(view);
+       }
+}
Index: libnautilus-private/nautilus-view.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-view.h,v
retrieving revision 1.3
diff -p -u -r1.3 nautilus-view.h
--- libnautilus-private/nautilus-view.h 17 May 2005 13:27:29 -0000      1.3
+++ libnautilus-private/nautilus-view.h 26 Jan 2006 01:01:34 -0000
@@ -115,6 +115,9 @@ struct _NautilusViewIface 
        void           (* pop_up_location_context_menu) (NautilusView   *view,
                                                         GdkEventButton *event);
 
+       /* Request popup the interactive search dialog (aka typeahead) */
+       void           (* start_interactive_search) (NautilusView        *view);
+
        /* Padding for future expansion */
        void (*_reserved1) (void);
        void (*_reserved2) (void);
@@ -151,6 +154,7 @@ gboolean          nautilus_view_can_zoom
 NautilusZoomLevel nautilus_view_get_zoom_level             (NautilusView      
*view);
 void              nautilus_view_pop_up_location_context_menu (NautilusView    
*view,
                                                              GdkEventButton  
*event);
+void              nautilus_view_start_interactive_search   (NautilusView      
*view);
 
 G_END_DECLS
 
Index: src/nautilus-spatial-window-ui.xml
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-spatial-window-ui.xml,v
retrieving revision 1.17
diff -p -u -r1.17 nautilus-spatial-window-ui.xml
--- src/nautilus-spatial-window-ui.xml  15 Dec 2005 14:25:58 -0000      1.17
+++ src/nautilus-spatial-window-ui.xml  26 Jan 2006 01:01:34 -0000
@@ -10,6 +10,11 @@
                        <menuitem name="Close All Folders" action="Close All 
Folders"/>
                </placeholder>
        </menu>
+       <menu action="Edit">
+               <placeholder name="Select Items">
+                       <menuitem name="Find" action="Interactive Search"/>
+               </placeholder>
+       </menu>
         <placeholder name="Other Menus">
                <menu action="Places">
                      <menuitem name="Home" action="Home"/>
Index: src/nautilus-spatial-window.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-spatial-window.c,v
retrieving revision 1.456
diff -p -u -r1.456 nautilus-spatial-window.c
--- src/nautilus-spatial-window.c       16 Jan 2006 23:48:19 -0000      1.456
+++ src/nautilus-spatial-window.c       26 Jan 2006 01:01:35 -0000
@@ -319,6 +319,17 @@ action_close_all_folders_callback (GtkAc
        nautilus_application_close_all_spatial_windows ();
 }
 
+void
+action_interactive_search_spatial_callback (GtkAction *action,
+                                           gpointer   user_data)
+{      
+       NautilusWindow *window;
+       window = NAUTILUS_WINDOW (user_data);
+
+       nautilus_view_start_interactive_search (window->content_view);
+       
+}
+
 static void
 real_prompt_for_location (NautilusWindow *window,
                          const char     *initial)
@@ -849,6 +860,9 @@ static const GtkActionEntry spatial_entr
   { "Search", "gtk-find", N_("_Search"), /* name, stock id, label */
     "<control>F", N_("Search for files"),
     G_CALLBACK (action_search_callback) },
+  { "Interactive Search", GTK_STOCK_FIND, N_("_Find in this folder"),
+    "<control>Z", N_("Find files in this folder"),
+    G_CALLBACK (action_interactive_search_spatial_callback) },
 };
 
 static void
Index: src/nautilus-spatial-window.h
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-spatial-window.h,v
retrieving revision 1.113
diff -p -u -r1.113 nautilus-spatial-window.h
--- src/nautilus-spatial-window.h       11 Jul 2005 10:23:57 -0000      1.113
+++ src/nautilus-spatial-window.h       26 Jan 2006 01:01:35 -0000
@@ -63,6 +63,8 @@ void             nautilus_spatial_window
 void             nautilus_spatial_window_save_show_hidden_files_mode   
(NautilusSpatialWindow *window);
 void             nautilus_spatial_window_set_location_button           
(NautilusSpatialWindow *window,
                                                                         const 
char            *location);
+void             action_interactive_search_spatial_callback            
(GtkAction *action, 
+                                                                        
gpointer  user_data);
 
 
 #endif
Index: src/file-manager/fm-directory-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.c,v
retrieving revision 1.733
diff -p -u -r1.733 fm-directory-view.c
--- src/file-manager/fm-directory-view.c        16 Jan 2006 09:14:33 -0000      
1.733
+++ src/file-manager/fm-directory-view.c        26 Jan 2006 01:01:44 -0000
@@ -343,6 +343,7 @@ static void     load_directory          
                                                                
NautilusDirectory    *directory);
 static void     fm_directory_view_merge_menus                  
(FMDirectoryView      *view);
 static void     fm_directory_view_init_show_hidden_files       
(FMDirectoryView      *view);
+static void     fm_directory_view_start_interactive_search     
(FMDirectoryView      *view);
 static char *   file_name_from_uri                             (const char     
      *uri);
 static void     fm_directory_view_load_location                (NautilusView   
      *nautilus_view,
                                                                const char      
     *location);
@@ -444,6 +445,7 @@ EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_d
 EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_directory_view, set_selection)
 EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_directory_view, zoom_to_level)
 EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_directory_view, get_zoom_level)
+EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_directory_view, 
start_interactive_search)
 
 typedef struct {
        GnomeVFSMimeApplication *application;
@@ -1875,6 +1877,7 @@ fm_directory_view_init_view_iface (Nauti
        iface->get_zoom_level = (gpointer)fm_directory_view_get_zoom_level;
 
        iface->pop_up_location_context_menu = 
(gpointer)fm_directory_view_pop_up_location_context_menu;
+       iface->start_interactive_search = 
(gpointer)fm_directory_view_start_interactive_search;
 }
 
 static void
@@ -7559,6 +7562,23 @@ fm_directory_view_pop_up_location_contex
                                      event);
 }
 
+/**
+ * fm_directory_view_start_interactive_search
+ *
+ * Pop up the interactive search box (aka typeahead).
+ * @view: FMDirectoryView of interest.
+ *
+ **/
+static void 
+fm_directory_view_start_interactive_search (FMDirectoryView *view)
+{
+       g_assert (FM_IS_DIRECTORY_VIEW (view));
+
+       EEL_CALL_METHOD
+       (FM_DIRECTORY_VIEW_CLASS, view,
+       start_interactive_search, (view));
+}
+
 static void
 schedule_update_menus (FMDirectoryView *view) 
 {
@@ -9736,7 +9756,8 @@ fm_directory_view_class_init (FMDirector
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, 
set_selection);
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, 
zoom_to_level);
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, 
get_zoom_level);
-
+       EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, 
start_interactive_search);
+       
        copied_files_atom = gdk_atom_intern ("x-special/gnome-copied-files", 
FALSE);
        utf8_string_atom = gdk_atom_intern ("UTF8_STRING", FALSE);
 
Index: src/file-manager/fm-directory-view.h
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.h,v
retrieving revision 1.143
diff -p -u -r1.143 fm-directory-view.h
--- src/file-manager/fm-directory-view.h        12 Dec 2005 16:59:11 -0000      
1.143
+++ src/file-manager/fm-directory-view.h        26 Jan 2006 01:01:44 -0000
@@ -195,6 +195,9 @@ struct FMDirectoryViewClass {
          */
         void     (* reveal_selection)          (FMDirectoryView *view);
 
+       /* Pops up the interactive_search_dialog (aka typeahead) */
+        void     (* start_interactive_search)  (FMDirectoryView *view);
+
         /* get_background is a function pointer that subclasses must
          * override to return the EelBackground for this view.
          */
Index: src/file-manager/fm-icon-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-icon-view.c,v
retrieving revision 1.318
diff -p -u -r1.318 fm-icon-view.c
--- src/file-manager/fm-icon-view.c     12 Dec 2005 16:59:11 -0000      1.318
+++ src/file-manager/fm-icon-view.c     26 Jan 2006 01:01:47 -0000
@@ -183,6 +183,7 @@ static void                 fm_icon_view
 static void                 fm_icon_view_set_directory_tighter_layout 
(FMIconView           *icon_view,
                                                                       
NautilusFile         *file,
                                                                       gboolean 
             tighter_layout);
+static void                 fm_icon_view_start_interactive_search     
(FMDirectoryView      *view);
 static const SortCriterion *get_sort_criterion_by_sort_type           
(NautilusFileSortType  sort_type);
 static void                 set_sort_criterion_by_sort_type           
(FMIconView           *icon_view,
                                                                       
NautilusFileSortType  sort_type);
@@ -2584,6 +2585,20 @@ icon_view_scroll_to_file (NautilusView *
        }
 }
 
+static void
+fm_icon_view_start_interactive_search (FMDirectoryView *view)
+{
+       NautilusIconContainer  *icon_container;
+       gboolean ret;
+
+       icon_container = NAUTILUS_ICON_CONTAINER (GTK_BIN (FM_ICON_VIEW 
(view))->child);
+       if (!GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (icon_container)))
+               gtk_widget_grab_focus (GTK_WIDGET (icon_container));
+
+       ret = EEL_CALL_METHOD_WITH_RETURN_VALUE
+       (NAUTILUS_ICON_CONTAINER_CLASS, icon_container,
+        start_interactive_search, (icon_container));
+}
 
 static void
 fm_icon_view_class_init (FMIconViewClass *klass)
@@ -2633,6 +2648,7 @@ fm_icon_view_class_init (FMIconViewClass
         fm_directory_view_class->text_attribute_names_changed = 
fm_icon_view_text_attribute_names_changed;
         fm_directory_view_class->update_menus = fm_icon_view_update_menus;
        fm_directory_view_class->using_manual_layout = 
fm_icon_view_using_manual_layout;
+       fm_directory_view_class->start_interactive_search = 
fm_icon_view_start_interactive_search;
 
        klass->clean_up = fm_icon_view_real_clean_up;
        klass->supports_auto_layout = real_supports_auto_layout;
Index: src/file-manager/fm-list-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-list-view.c,v
retrieving revision 1.263
diff -p -u -r1.263 fm-list-view.c
--- src/file-manager/fm-list-view.c     12 Dec 2005 16:59:11 -0000      1.263
+++ src/file-manager/fm-list-view.c     26 Jan 2006 01:01:49 -0000
@@ -135,6 +135,12 @@ static NautilusZoomLevel        default_
 static GList *                  default_visible_columns_auto_value;
 static GList *                  default_column_order_auto_value;
 
+static gboolean interactive_search_equal_func (GtkTreeModel  *model,
+                                               gint            column,
+                                               const gchar     *key,
+                                               GtkTreeIter     *iter,
+                                               gpointer        search_data);
+static void   fm_list_view_start_interactive_search       (FMDirectoryView   
*view);
 static GList *fm_list_view_get_selection                   (FMDirectoryView   
*view);
 static GList *fm_list_view_get_selection_for_file_transfer (FMDirectoryView   
*view);
 static void   fm_list_view_set_zoom_level                  (FMListView        
*view,
@@ -236,6 +242,80 @@ button_event_modifies_selection (GdkEven
        return (event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) != 0;
 }
 
+static gboolean
+interactive_search_equal_func (GtkTreeModel *model,
+                                gint          column,
+                                const gchar  *key,
+                                GtkTreeIter  *iter,
+                                gpointer      search_data)
+{
+  gboolean retval = TRUE;
+  const gchar *str;
+  gchar *normalized_string;
+  gchar *normalized_key;
+  gchar *case_normalized_string = NULL;
+  gchar *case_normalized_key = NULL;
+  GValue value = {0,};
+  GValue transformed = {0,};
+
+  gtk_tree_model_get_value (model, iter, column, &value);
+
+  g_value_init (&transformed, G_TYPE_STRING);
+
+  if (!g_value_transform (&value, &transformed))
+    {
+      g_value_unset (&value);
+      return TRUE;
+    }
+
+  g_value_unset (&value);
+
+  str = g_value_get_string (&transformed);
+  if (!str)
+    {
+      g_value_unset (&transformed);
+      return TRUE;
+    }
+
+  normalized_string = g_utf8_normalize (str, -1, G_NORMALIZE_ALL);
+  normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
+
+  if (normalized_string && normalized_key)
+    {
+      case_normalized_string = g_utf8_casefold (normalized_string, -1);
+      case_normalized_key = g_utf8_casefold (normalized_key, -1);
+
+      if (strstr (case_normalized_string, case_normalized_key) != NULL)
+         retval = FALSE;
+    }
+
+  g_value_unset (&transformed);
+  g_free (normalized_key);
+  g_free (normalized_string);
+  g_free (case_normalized_key);
+  g_free (case_normalized_string);
+
+  return retval;
+}
+
+static void
+fm_list_view_start_interactive_search (FMDirectoryView *view)
+{
+       GtkTreeView *tv;
+       gboolean ret;
+       FMListView *listview;
+
+       listview = FM_LIST_VIEW (view);
+       tv = listview->details->tree_view;
+       
+       if (!GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (tv)))
+               gtk_widget_grab_focus (GTK_WIDGET (tv));
+
+       ret = EEL_CALL_METHOD_WITH_RETURN_VALUE
+       (GTK_TREE_VIEW_CLASS, tv,
+       start_interactive_search, (tv));
+}
+
 static void
 fm_list_view_did_not_drag (FMListView *view,
                           GdkEventButton *event)
@@ -2498,6 +2578,7 @@ fm_list_view_class_init (FMListViewClass
         fm_directory_view_class->emblems_changed = 
fm_list_view_emblems_changed;
        fm_directory_view_class->end_file_changes = 
fm_list_view_end_file_changes;
        fm_directory_view_class->using_manual_layout = 
fm_list_view_using_manual_layout;
+       fm_directory_view_class->start_interactive_search = 
fm_list_view_start_interactive_search;
 
        eel_preferences_add_auto_enum (NAUTILUS_PREFERENCES_CLICK_POLICY,
                                       &click_policy_auto_value);
@@ -2538,6 +2619,10 @@ fm_list_view_init (FMListView *list_view
        list_view->details = g_new0 (FMListViewDetails, 1);
 
        create_and_set_up_tree_view (list_view);
+
+       gtk_tree_view_set_search_equal_func (list_view->details->tree_view,
+                                            interactive_search_equal_func,
+                                            NULL, NULL);
 
        eel_preferences_add_callback_while_alive 
(NAUTILUS_PREFERENCES_LIST_VIEW_DEFAULT_SORT_ORDER,
                                                  
default_sort_order_changed_callback,
Index: src/file-manager/fm-list-view.h
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-list-view.h,v
retrieving revision 1.12
diff -p -u -r1.12 fm-list-view.h
--- src/file-manager/fm-list-view.h     22 Nov 2004 15:24:38 -0000      1.12
+++ src/file-manager/fm-list-view.h     26 Jan 2006 01:01:49 -0000
@@ -46,6 +46,9 @@ typedef struct {
 
 typedef struct {
        FMDirectoryViewClass parent_class;
+
+       /* Pops up the interactive search dialog */
+        /* void    (* start_interactive_search)       (FMListView *view); */
 } FMListViewClass;
 
 GType fm_list_view_get_type (void);
-- 
nautilus-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/nautilus-list

Reply via email to