Re: [Patch] Interactive search (aka typeahead) enhancement patch
- From: Nelson Benítez <gnel cenobioracing com>
- To: Alexander Larsson <alexl redhat com>
- Cc: nautilus-list gnome org
- Subject: Re: [Patch] Interactive search (aka typeahead) enhancement patch
- Date: Thu, 26 Jan 2006 14:30:57 +0000
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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]