Re: [Nautilus-list] [PATCH] location bar autocompletion
- From: David Emory Watson <dwatson cs ucr edu>
- To: Darin Adler <darin bentspoon com>
- Cc: Nautilus <nautilus-list lists eazel com>, Alex Larsson <alexl redhat com>
- Subject: Re: [Nautilus-list] [PATCH] location bar autocompletion
- Date: Mon, 25 Feb 2002 18:22:36 -0800
Dang it! 2nd try...
On Mon, 2002-02-25 at 08:32, Darin Adler wrote:
> Owen suggested changing this to use two signal handlers:
> http://lists.gnome.org/archives/gtk-app-devel-list/2002-January/msg00243.htm
> l
>
> - connect_after to catch return_value = FALSE returns
> - connect to ::event-after to catch all key presses afterwards
Index: ./src/nautilus-location-bar.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-location-bar.c,v
retrieving revision 1.81
diff -p -u -r1.81 nautilus-location-bar.c
--- ./src/nautilus-location-bar.c 2002/02/19 22:53:43 1.81
+++ ./src/nautilus-location-bar.c 2002/02/26 01:41:43
@@ -1,4 +1,3 @@
-
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
@@ -98,18 +97,17 @@ static GtkTargetEntry drop_types [] = {
static char *nautilus_location_bar_get_location (NautilusNavigationBar *navigation_bar);
static void nautilus_location_bar_set_location (NautilusNavigationBar *navigation_bar,
const char *location);
-static void nautilus_location_bar_class_init (NautilusLocationBarClass *class);
-static void nautilus_location_bar_init (NautilusLocationBar *bar);
+static void nautilus_location_bar_class_init (NautilusLocationBarClass *class);
+static void nautilus_location_bar_init (NautilusLocationBar *bar);
static void nautilus_location_bar_update_label (NautilusLocationBar *bar);
EEL_CLASS_BOILERPLATE (NautilusLocationBar,
- nautilus_location_bar,
- NAUTILUS_TYPE_NAVIGATION_BAR)
+ nautilus_location_bar,
+ NAUTILUS_TYPE_NAVIGATION_BAR)
static NautilusWindow *
nautilus_location_bar_get_window (GtkWidget *bar)
{
-
return NAUTILUS_WINDOW (gtk_widget_get_ancestor (bar, NAUTILUS_TYPE_WINDOW));
}
@@ -239,13 +237,11 @@ style_set_handler (GtkWidget *widget, Gt
#endif
}
-#if GNOME2_CONVERSION_COMPLETE
-
/* utility routine to determine the string to expand to. If we don't have anything yet, accept
the whole string, otherwise accept the largest part common to both */
static char *
-accumulate_name(char *full_name, char *candidate_name)
+accumulate_name (char *full_name, char *candidate_name)
{
char *result_name, *str1, *str2;
@@ -256,11 +252,15 @@ accumulate_name(char *full_name, char *c
if (!eel_str_has_prefix (full_name, candidate_name)) {
str1 = full_name;
str2 = candidate_name;
- while ((*str1++ == *str2++)) { }
- *--str1 = '\0';
+
+ while ((g_utf8_get_char (str1) == g_utf8_get_char (str2))) {
+ str1 = g_utf8_next_char (str1);
+ str2 = g_utf8_next_char (str2);
+ }
+ *str1 = '\0';
}
}
-
+
return result_name;
}
@@ -275,7 +275,7 @@ get_file_info_list (NautilusLocationBar
gnome_vfs_file_info_list_free (bar->details->file_info_list);
bar->details->file_info_list = NULL;
}
-
+
bar->details->current_directory = g_strdup (dir_name);
result = gnome_vfs_directory_list_load (&bar->details->file_info_list, dir_name,
GNOME_VFS_FILE_INFO_DEFAULT);
@@ -289,8 +289,8 @@ get_file_info_list (NautilusLocationBar
}
/* routine that performs the tab expansion using gnome-vfs. Extract the directory name and
- incomplete basename, then iterate through the directory trying to complete it. If we
- find something, add it to the entry */
+ incomplete basename, then iterate through the directory trying to complete it. If we
+ find something, add it to the entry */
static gboolean
try_to_expand_path (gpointer callback_data)
@@ -301,10 +301,7 @@ try_to_expand_path (gpointer callback_da
GList *element;
GnomeVFSURI *uri;
GtkEditable *editable;
-
- uint base_length;
- int current_path_length;
- int offset;
+
char *base_name_uri_escaped;
char *base_name;
char *user_location;
@@ -313,33 +310,39 @@ try_to_expand_path (gpointer callback_da
char *expand_text;
char *expand_name;
- bar = NAUTILUS_LOCATION_BAR (callback_data);
+ uint base_name_length;
+ uint user_location_length;
+ uint current_path_length;
+ uint expand_text_length;
+ uint offset;
+ bar = NAUTILUS_LOCATION_BAR (callback_data);
editable = GTK_EDITABLE (bar->details->entry);
user_location = gtk_editable_get_chars (editable, 0, -1);
bar->details->idle_id = 0;
-
+
/* if it's just '~' or '~/', don't expand because slash shouldn't be appended */
if (eel_strcmp (user_location, "~") == 0
|| eel_strcmp (user_location, "~/") == 0) {
g_free (user_location);
return FALSE;
}
- current_path = eel_make_uri_from_input (user_location);
+ current_path = eel_make_uri_from_input (user_location);
if (!eel_istr_has_prefix (current_path, "file://")) {
g_free (user_location);
g_free (current_path);
return FALSE;
}
- current_path_length = strlen (current_path);
- offset = current_path_length - strlen (user_location);
+ current_path_length = strlen (current_path);
+ user_location_length = g_utf8_strlen (user_location, -1);
+ offset = current_path_length - user_location_length;
g_free (user_location);
uri = gnome_vfs_uri_new (current_path);
-
+
base_name_uri_escaped = gnome_vfs_uri_extract_short_name (uri);
if (base_name_uri_escaped == NULL) {
base_name = NULL;
@@ -351,14 +354,15 @@ try_to_expand_path (gpointer callback_da
if (base_name == NULL) {
gnome_vfs_uri_unref (uri);
g_free (current_path);
- return FALSE;
+ return FALSE;
}
- base_length = strlen (base_name);
+ base_name_length = strlen (base_name);
+
dir_name = gnome_vfs_uri_extract_dirname (uri);
/* get file info for the directory, if it hasn't changed since last time */
- get_file_info_list (bar, dir_name);
+ get_file_info_list (bar, dir_name);
if (bar->details->file_info_list == NULL) {
g_free (dir_name);
g_free (base_name);
@@ -369,7 +373,6 @@ try_to_expand_path (gpointer callback_da
/* iterate through the directory, keeping the intersection of all the names that
have the current basename as a prefix. */
-
expand_text = NULL;
for (element = bar->details->file_info_list; element != NULL; element = element->next) {
current_file_info = element->data;
@@ -383,15 +386,21 @@ try_to_expand_path (gpointer callback_da
g_free (expand_name);
}
}
-
- /* if we've got something, add it to the entry */
- if (expand_text != NULL
- && !eel_str_has_suffix (current_path, expand_text)
- && base_length < strlen (expand_text)) {
- gtk_entry_append_text (GTK_ENTRY (editable), expand_text + base_length);
- gtk_entry_select_region (GTK_ENTRY (editable),
- current_path_length - offset,
- current_path_length - offset + strlen (expand_text) - base_length);
+
+ /* if we've got something, add it to the entry */
+ if (expand_text != NULL) {
+ expand_text_length = g_utf8_strlen (expand_text, -1);
+ if (!eel_str_has_suffix (current_path, expand_text)
+ && base_name_length < expand_text_length) {
+ gtk_editable_insert_text (editable,
+ g_utf8_offset_to_pointer (expand_text, base_name_length),
+ expand_text_length - base_name_length,
+ &user_location_length);
+
+ gtk_editable_select_region (editable,
+ current_path_length - offset,
+ current_path_length - offset + expand_text_length - base_name_length);
+ }
}
g_free (expand_text);
@@ -435,13 +444,13 @@ entry_would_have_inserted_characters (co
}
static int
-get_editable_length (GtkEditable *editable)
+get_editable_number_of_chars (GtkEditable *editable)
{
char *text;
int length;
text = gtk_editable_get_chars (editable, 0, -1);
- length = strlen (text);
+ length = g_utf8_strlen (text, -1);
g_free (text);
return length;
}
@@ -453,8 +462,8 @@ has_exactly_one_slash (GtkEditable *edit
gboolean exactly_one;
text = gtk_editable_get_chars (editable, 0, -1);
- slash = strchr (text, '/');
- exactly_one = slash != NULL && strchr (slash + 1, '/') == NULL;
+ slash = g_utf8_strchr (text, -1, '/');
+ exactly_one = slash != NULL && g_utf8_strchr (g_utf8_next_char (slash), -1, '/') == NULL;
g_free (text);
return exactly_one;
@@ -465,7 +474,7 @@ set_position_and_selection_to_end (GtkEd
{
int end;
- end = get_editable_length (editable);
+ end = get_editable_number_of_chars (editable);
gtk_editable_select_region (editable, end, end);
gtk_editable_set_position (editable, end);
}
@@ -476,7 +485,7 @@ position_and_selection_are_at_end (GtkEd
int end;
int start_sel, end_sel;
- end = get_editable_length (editable);
+ end = get_editable_number_of_chars (editable);
if (gtk_editable_get_selection_bounds (editable, &start_sel, &end_sel)) {
if (start_sel != end || end_sel != end) {
return FALSE;
@@ -485,30 +494,24 @@ position_and_selection_are_at_end (GtkEd
return gtk_editable_get_position (editable) == end;
}
-/* Handle changes in the location entry. This is a marshal-style
- * callback so that we don't mess up the return value.
- */
static void
-editable_key_press_callback (GtkObject *object,
- gpointer data,
- guint n_args,
- GtkArg *args)
+editable_event_after_callback (GtkEntry *entry,
+ GdkEvent *event,
+ gpointer user_data)
{
GtkEditable *editable;
- GdkEventKey *event;
- gboolean *return_value_location;
+ GdkEventKey *keyevent;
NautilusLocationBar *bar;
const char *unexpanded_text;
char *expanded_text;
-
- g_assert (n_args == 1);
- g_assert (args != NULL);
- bar = NAUTILUS_LOCATION_BAR (data);
+ if (event->type != GDK_KEY_PRESS) {
+ return;
+ }
- editable = GTK_EDITABLE (object);
- event = GTK_VALUE_POINTER (args[0]);
- return_value_location = GTK_RETLOC_BOOL (args[1]);
+ editable = GTK_EDITABLE (entry);
+ keyevent = (GdkEventKey *)event;
+ bar = NAUTILUS_LOCATION_BAR (user_data);
/* After typing the right arrow key we move the selection to
* the end.
@@ -519,7 +522,7 @@ editable_key_press_callback (GtkObject *
* you can't move through the text a character at a
* time. Seems like a bad idea.
*/
- if ((event->keyval == GDK_Right || event->keyval == GDK_End)
+ if ((keyevent->keyval == GDK_Right || keyevent->keyval == GDK_End)
&& gtk_editable_get_selection_bounds (editable, NULL, NULL)) {
set_position_and_selection_to_end (editable);
}
@@ -530,9 +533,8 @@ editable_key_press_callback (GtkObject *
* when we type a key that would have inserted characters.
*/
if (position_and_selection_are_at_end (editable)) {
- if (*return_value_location
- && entry_would_have_inserted_characters (event)) {
- if (event->keyval == GDK_slash
+ if (entry_would_have_inserted_characters (keyevent)) {
+ if (keyevent->keyval == GDK_slash
&& has_exactly_one_slash (editable)) {
/* It's OK for us to call
* gtk_entry_set_text here, even
@@ -564,7 +566,6 @@ editable_key_press_callback (GtkObject *
nautilus_location_bar_update_label (bar);
}
-#endif
static void
real_activate (NautilusNavigationBar *navigation_bar)
@@ -659,10 +660,10 @@ nautilus_location_bar_init (NautilusLoca
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
g_signal_connect (label, "style_set",
- G_CALLBACK (style_set_handler), NULL);
+ G_CALLBACK (style_set_handler), NULL);
- gtk_box_pack_start (GTK_BOX (hbox), event_box, FALSE, TRUE,
- GNOME_PAD_SMALL);
+ gtk_box_pack_start (GTK_BOX (hbox), event_box, FALSE, TRUE,
+ GNOME_PAD_SMALL);
entry = nautilus_entry_new ();
@@ -671,39 +672,31 @@ nautilus_location_bar_init (NautilusLoca
g_signal_connect_swapped (entry, "activate",
G_CALLBACK (nautilus_navigation_bar_location_changed),
bar);
+ g_signal_connect (GTK_OBJECT (entry), "event_after",
+ G_CALLBACK (editable_event_after_callback),
+ bar);
-#if GNOME2_CONVERSION_COMPLETE
- /* The callback uses the marshal interface directly
- * so it can both read and write the return value.
- */
- gtk_signal_connect_full (GTK_OBJECT (entry), "key_press_event",
- NULL, editable_key_press_callback,
- bar, NULL,
- FALSE, TRUE);
-#endif
-
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (bar), hbox);
-
/* Drag source */
gtk_drag_source_set (GTK_WIDGET (event_box),
GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
drag_types, G_N_ELEMENTS (drag_types),
GDK_ACTION_LINK);
- g_signal_connect (event_box, "drag_data_get",
- G_CALLBACK (drag_data_get_callback),
- bar);
+ g_signal_connect (event_box, "drag_data_get",
+ G_CALLBACK (drag_data_get_callback),
+ bar);
/* Drag dest. */
- gtk_drag_dest_set (GTK_WIDGET (bar),
- GTK_DEST_DEFAULT_ALL,
- drop_types, G_N_ELEMENTS (drop_types),
- GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
+ gtk_drag_dest_set (GTK_WIDGET (bar),
+ GTK_DEST_DEFAULT_ALL,
+ drop_types, G_N_ELEMENTS (drop_types),
+ GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
g_signal_connect (bar, "drag_data_received",
- G_CALLBACK (drag_data_received_callback),
- NULL);
+ G_CALLBACK (drag_data_received_callback),
+ NULL);
gtk_widget_show_all (hbox);
@@ -711,7 +704,6 @@ nautilus_location_bar_init (NautilusLoca
bar->details->entry = NAUTILUS_ENTRY (entry);
}
-
GtkWidget *
nautilus_location_bar_new (NautilusWindow *window)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]