Re: [Nautilus-list] [PATCH] location bar autocompletion



On Sat, 23 Feb 2002, David Emory Watson wrote:

> This patch works, but is almost certainly wrong.  I am still trying to
> figure out the correct way to connect the editable_key_press_callback
> ().  I guess I don't really understand the comment about needing a
> marshaled callback...

You need some more changes to handle the fact that all strings (even 
filenames) in Nautilus now are in UTF8. This means that all arguments to 
GtkEntry and GtkEditable that specify positions in the strings are 
measured in number of characters from the start (called position), not the 
number of bytes from the start (called index). 

static char *accumulate_name(char *full_name, char *candidate_name)

this function needs to be changed to compare characters instead of bytes 
when looking for the common part.

static int
get_editable_length (GtkEditable *editable)

this should use g_utf8_strlen, and possibly be renamed to 
get_editable_number_of_chars. This makes set_position_and_selection_to_end 
and position_and_selection_are_at_end work correctly.

 	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);
+		gtk_editable_insert_text (editable,
+					  expand_text + base_length,
+					  strlen (expand_text) - base_length,
+					  &user_location_length);
+
+		gtk_editable_select_region (editable,
+					    current_path_length - offset,
+					    current_path_length - offset + strlen (expand_text) - base_length);
 	}
 	g_free (expand_text);


Both gtk_editable_insert_text and gtk_editable_select_region take 
positions, not indexes, so this has to be changed.
 

-#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
-	
+	g_signal_connect_swapped (entry, "key_press_event",
+				  G_CALLBACK (editable_key_press_callback),
+				  bar);
+

You can't change this to a normal signal, since we need to peek on the 
return value from the entry to see if it handled the event, otherwise we 
shouldn't touch it. Our signahandler must also be connected "after" in 
order to run after the entry handler.

This has changed a bit since Gtk 1.2, now you have to use a GClosure in 
order to accomplish this. Here is some code (warning, untested) that 
should work:

  GClosure *closure;
  
  closure = g_closure_new_simple (sizeof (GCClosure), bar);
  ((GCClosure*) closure)->marshal = editable_key_press_callback;
  g_signal_connect_closure (GTK_OBJECT (entry), "key_press_event",
			    closure,  TRUE);


The signal handler/marshaller should then look like this:
static void
editable_key_press_callback (GClosure	  *closure,
			     GValue       *return_value,
			     guint         n_param_values,
			     const GValue *param_values,
			     gpointer      invocation_hint,
			     gpointer	   data)
{

This is slightly different from Gtk 1.2 too. In 1.2 the return value was 
stored in the args array, but now you get it in a separate argument.

You should be able to peek at the return value from the entry signal 
handler by doing  g_value_get_boolean (return_value), and the event should 
be in the param_value[0].

If you fix these things it should work. If you send me an updated patch 
I'll review it again.

/ Alex





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]