SF.net SVN: geany:[4148] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Thu Sep 3 12:04:27 UTC 2009


Revision: 4148
          http://geany.svn.sourceforge.net/geany/?rev=4148&view=rev
Author:   ntrel
Date:     2009-09-03 12:04:27 +0000 (Thu, 03 Sep 2009)

Log Message:
-----------
Enable type-ahead find for sidebar symbols and documents tabs
(patch by Thomas Martitz, thanks).

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/THANKS
    trunk/src/document.c
    trunk/src/document.h
    trunk/src/treeviews.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2009-09-03 04:32:05 UTC (rev 4147)
+++ trunk/ChangeLog	2009-09-03 12:04:27 UTC (rev 4148)
@@ -1,3 +1,10 @@
+2009-09-03  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/treeviews.c, src/document.c, src/document.h, THANKS:
+   Enable type-ahead find for sidebar symbols and documents tabs
+   (patch by Thomas Martitz, thanks).
+
+
 2009-09-03  Lex Trotman  <elextr(at)gmail(dot)com>
 
  * src/build.c, src/filetypes.h, src/filetypes.c

Modified: trunk/THANKS
===================================================================
--- trunk/THANKS	2009-09-03 04:32:05 UTC (rev 4147)
+++ trunk/THANKS	2009-09-03 12:04:27 UTC (rev 4148)
@@ -59,7 +59,7 @@
 Guillaume de Rorthais <ioguix(at)free(dot)fr> - Auto-close brackets/braces/quotes patch
 Tyler Mulligan <tyler(at)doknowevil(dot)net> - Close All toolbar icon
 Philipp Gildein <philipp(at)gildein(dot)com> - Ada filetype patch
-Thomas Martitz <thomas47(at)arcor(dot)de> - Multiple %cursor% wildcards in Snippets patch
+Thomas Martitz <thomas47(at)arcor(dot)de> - Multiple %cursor% in Snippets, typeahead sidebar patch
 David Gleich <dgleich(at)stanford(dot)edu> - Send Selection to Terminal patch
 Chris Macksey <cmacksey(at)users(dot)sourceforge(dot)net> - ActionScript filetype patch
 Simon Treny <simon(dot)treny(at)free(dot)fr> - Documents sidebar stock icons patch

Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c	2009-09-03 04:32:05 UTC (rev 4147)
+++ trunk/src/document.c	2009-09-03 12:04:27 UTC (rev 4148)
@@ -513,19 +513,40 @@
 }
 
 
+void document_try_focus(GeanyDocument *doc)
+{
+	/* doc might not be valid e.g. if user closed a tab whilst Geany is opening files */
+	if (DOC_VALID(doc))
+	{
+		GtkWidget *sci = GTK_WIDGET(doc->editor->sci);
+		GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window));
+
+		if (focusw == doc->priv->tag_tree)
+			gtk_widget_grab_focus(sci);
+	}
+}
+
+
+static gboolean on_idle_focus(gpointer doc)
+{
+	document_try_focus(doc);
+	return FALSE;
+}
+
+
 /* Creates a new document and editor, adding a tab in the notebook.
  * @return The created document */
 static GeanyDocument *document_create(const gchar *utf8_filename)
 {
-	GeanyDocument *this;
+	GeanyDocument *doc;
 	gint new_idx;
 	gint cur_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook));
 
 	if (cur_pages == 1)
 	{
-		GeanyDocument *doc = document_get_current();
+		GeanyDocument *cur = document_get_current();
 		/* remove the empty document and open a new one */
-		if (doc != NULL && doc->file_name == NULL && ! doc->changed)
+		if (cur != NULL && cur->file_name == NULL && ! cur->changed)
 			document_remove_page(0);
 	}
 
@@ -537,36 +558,35 @@
 		new_idx = documents_array->len;
 		g_ptr_array_add(documents_array, new_doc);
 	}
-	this = documents[new_idx];
-	init_doc_struct(this);	/* initialize default document settings */
-	this->index = new_idx;
+	doc = documents[new_idx];
+	init_doc_struct(doc);	/* initialize default document settings */
+	doc->index = new_idx;
 
-	this->file_name = g_strdup(utf8_filename);
+	doc->file_name = g_strdup(utf8_filename);
 
-	this->editor = editor_create(this);
+	doc->editor = editor_create(doc);
 
-	editor_apply_update_prefs(this->editor);
+	editor_apply_update_prefs(doc->editor);
 
-	treeviews_openfiles_add(this);	/* sets this->iter */
+	treeviews_openfiles_add(doc);	/* sets doc->iter */
 
-	notebook_new_tab(this);
+	notebook_new_tab(doc);
 
 	/* select document in sidebar */
 	{
 		GtkTreeSelection *sel;
 
 		sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles));
-		gtk_tree_selection_select_iter(sel, &this->priv->iter);
+		gtk_tree_selection_select_iter(sel, &doc->priv->iter);
 	}
 
 	ui_document_buttons_update();
 
-	gtk_widget_grab_focus(GTK_WIDGET(this->editor->sci));
-
-	this->is_valid = TRUE;	/* do this last to prevent UI updating with NULL items. */
-	return this;
+	doc->is_valid = TRUE;	/* do this last to prevent UI updating with NULL items. */
+	return doc;
 }
 
+
 /**
  *  Close the given document.
  *
@@ -729,7 +749,9 @@
 	ui_document_show_hide(doc); /* update the document menu */
 
 	sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin, 0);
-	sci_goto_pos(doc->editor->sci, 0, TRUE);
+	/* bring it in front, jump to the start and grab the focus */
+	editor_goto_pos(doc->editor, 0, FALSE);
+	document_try_focus(doc);
 
 #if USE_GIO_FILEMON
 	monitor_file_setup(doc);
@@ -996,8 +1018,10 @@
 
 /* Sets the cursor position on opening a file. First it sets the line when cl_options.goto_line
  * is set, otherwise it sets the line when pos is greater than zero and finally it sets the column
- * if cl_options.goto_column is set. */
-static void set_cursor_position(GeanyEditor *editor, gint pos)
+ * if cl_options.goto_column is set.
+ *
+ * returns the new position which may have changed */
+static int set_cursor_position(GeanyEditor *editor, gint pos)
 {
 	if (cl_options.goto_line >= 0)
 	{	/* goto line which was specified on command line and then undefine the line */
@@ -1013,11 +1037,14 @@
 
 	if (cl_options.goto_column >= 0)
 	{	/* goto column which was specified on command line and then undefine the column */
-		gint cur_pos = sci_get_current_position(editor->sci);
-		sci_set_current_position(editor->sci, cur_pos + cl_options.goto_column, FALSE);
+
+		gint new_pos = sci_get_current_position(editor->sci) + cl_options.goto_column;
+		sci_set_current_position(editor->sci, new_pos, FALSE);
 		editor->scroll_percent = 0.5F;
 		cl_options.goto_column = -1;
+		return new_pos;
 	}
+	return sci_get_current_position(editor->sci);
 }
 
 
@@ -1204,14 +1231,10 @@
 		if (doc != NULL)
 		{
 			ui_add_recent_file(utf8_filename);	/* either add or reorder recent item */
-			gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook),
-					gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook),
-					(GtkWidget*) doc->editor->sci));
 			g_free(utf8_filename);
 			g_free(locale_filename);
 			document_check_disk_status(doc, TRUE);	/* force a file changed check */
-			set_cursor_position(doc->editor, pos);
-			return doc;
+			goto end;
 		}
 	}
 	display_filename = utils_str_middle_truncate(utf8_filename, 100);
@@ -1269,7 +1292,7 @@
 	sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin, 0);
 
 	/* set the cursor position according to pos, cl_options.goto_line and cl_options.goto_column */
-	set_cursor_position(doc->editor, pos);
+	pos = set_cursor_position(doc->editor, pos);
 
 	if (! reload)
 	{
@@ -1323,6 +1346,13 @@
 	 * based on a configurable interval */
 	/*g_timeout_add(10000, auto_update_tag_list, doc);*/
 
+end:
+	/* now bring the file in front */
+	editor_goto_pos(doc->editor, pos, FALSE);
+
+	/* finally, let the editor widget grab the focus so you can start coding
+	 * right away */
+	g_idle_add(on_idle_focus, doc);
 	return doc;
 }
 

Modified: trunk/src/document.h
===================================================================
--- trunk/src/document.h	2009-09-03 04:32:05 UTC (rev 4147)
+++ trunk/src/document.h	2009-09-03 12:04:27 UTC (rev 4148)
@@ -184,6 +184,8 @@
 
 gboolean document_remove_page(guint page_num);
 
+void document_try_focus(GeanyDocument *doc);
+
 gboolean document_close(GeanyDocument *doc);
 
 gboolean document_account_for_unsaved(void);

Modified: trunk/src/treeviews.c
===================================================================
--- trunk/src/treeviews.c	2009-09-03 04:32:05 UTC (rev 4147)
+++ trunk/src/treeviews.c	2009-09-03 12:04:27 UTC (rev 4148)
@@ -42,10 +42,13 @@
 #include "project.h"
 #include "stash.h"
 #include "keyfile.h"
+#include "sciwrappers.h"
 
 #include <gdk/gdkkeysyms.h>
 
 SidebarTreeviews tv = {NULL, NULL, NULL};
+/* while typeahead searching, editor should not get focus */
+static gboolean may_steal_focus = FALSE;
 
 static struct
 {
@@ -85,17 +88,16 @@
 static GtkWidget *tag_window;	/* scrolled window that holds the symbol list GtkTreeView */
 
 /* callback prototypes */
-static void on_openfiles_tree_selection_changed(GtkTreeSelection *selection, gpointer data);
+static gboolean on_openfiles_tree_selection_changed(GtkTreeSelection *selection);
 static void on_openfiles_document_action(GtkMenuItem *menuitem, gpointer user_data);
 static gboolean on_taglist_tree_selection_changed(GtkTreeSelection *selection);
-static gboolean on_symbols_button_press_event(GtkWidget *widget, GdkEventButton *event,
+static gboolean treeviews_button_press_cb(GtkWidget *widget, GdkEventButton *event,
 		gpointer user_data);
-static gboolean on_documents_button_release_event(GtkWidget *widget, GdkEventButton *event,
+static gboolean treeviews_key_press_cb(GtkWidget *widget, GdkEventKey *event,
 		gpointer user_data);
-static gboolean on_treeviews_key_press_event(GtkWidget *widget, GdkEventKey *event,
-		gpointer user_data);
 static void on_list_document_activate(GtkCheckMenuItem *item, gpointer user_data);
 static void on_list_symbol_activate(GtkCheckMenuItem *item, gpointer user_data);
+static void documents_menu_update(GtkTreeSelection *selection);
 
 
 /* the prepare_* functions are document-related, but I think they fit better here than in document.c */
@@ -107,9 +109,9 @@
 
 	text_renderer = gtk_cell_renderer_text_new();
 	icon_renderer = gtk_cell_renderer_pixbuf_new();
-    column = gtk_tree_view_column_new();
+	column = gtk_tree_view_column_new();
 
-    gtk_tree_view_column_pack_start(column, icon_renderer, FALSE);
+	gtk_tree_view_column_pack_start(column, icon_renderer, FALSE);
   	gtk_tree_view_column_set_attributes(column, icon_renderer, "pixbuf", SYMBOLS_COLUMN_ICON, NULL);
   	g_object_set(icon_renderer, "xalign", 0.0, NULL);
 
@@ -127,12 +129,10 @@
 	g_object_unref(store);
 
 	g_signal_connect(tree, "button-press-event",
-		G_CALLBACK(on_symbols_button_press_event), NULL);
+		G_CALLBACK(treeviews_button_press_cb), NULL);
 	g_signal_connect(tree, "key-press-event",
-		G_CALLBACK(on_treeviews_key_press_event), GINT_TO_POINTER(TREEVIEW_SYMBOL));
+		G_CALLBACK(treeviews_key_press_cb), NULL);
 
-	gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tree), FALSE);
-
 	if (gtk_check_version(2, 12, 0) == NULL)
 	{
 		g_object_set(tree, "show-expanders", interface_prefs.show_symbol_list_expanders, NULL);
@@ -242,13 +242,12 @@
 	store_openfiles = gtk_tree_store_new(5, G_TYPE_STRING, G_TYPE_STRING,
 		G_TYPE_POINTER, GDK_TYPE_COLOR, G_TYPE_STRING);
 	gtk_tree_view_set_model(GTK_TREE_VIEW(tv.tree_openfiles), GTK_TREE_MODEL(store_openfiles));
-	g_object_unref(store_openfiles);
 
 	/* set policy settings for the scolledwindow around the treeview again, because glade
 	 * doesn't keep the settings */
 	gtk_scrolled_window_set_policy(
-			GTK_SCROLLED_WINDOW(ui_lookup_widget(main_widgets.window, "scrolledwindow7")),
-			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+		GTK_SCROLLED_WINDOW(ui_lookup_widget(main_widgets.window, "scrolledwindow7")),
+		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
 	icon_renderer = gtk_cell_renderer_pixbuf_new();
 	text_renderer = gtk_cell_renderer_text_new();
@@ -262,7 +261,8 @@
 	gtk_tree_view_append_column(GTK_TREE_VIEW(tv.tree_openfiles), column);
 	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tv.tree_openfiles), FALSE);
 
-	gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tv.tree_openfiles), FALSE);
+	gtk_tree_view_set_search_column(GTK_TREE_VIEW(tv.tree_openfiles),
+		DOCUMENTS_SHORTNAME);
 
 	/* sort opened filenames in the store_openfiles treeview */
 	sortable = GTK_TREE_SORTABLE(GTK_TREE_MODEL(store_openfiles));
@@ -274,13 +274,15 @@
 	if (gtk_check_version(2, 12, 0) == NULL)
 		g_object_set(tv.tree_openfiles, "has-tooltip", TRUE, "tooltip-column", DOCUMENTS_FILENAME, NULL);
 
-	g_signal_connect(tv.tree_openfiles, "button-release-event",
-		G_CALLBACK(on_documents_button_release_event), NULL);
-
 	/* selection handling */
 	select = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles));
 	gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
-	g_signal_connect(select, "changed", G_CALLBACK(on_openfiles_tree_selection_changed), NULL);
+	g_object_unref(store_openfiles);
+
+	g_signal_connect(GTK_TREE_VIEW(tv.tree_openfiles), "button-press-event",
+		G_CALLBACK(treeviews_button_press_cb), NULL);
+	g_signal_connect(GTK_TREE_VIEW(tv.tree_openfiles), "key-press-event",
+		G_CALLBACK(treeviews_key_press_cb), NULL);
 }
 
 
@@ -702,31 +704,16 @@
 }
 
 
-static gboolean change_focus_to_editor(GeanyDocument *doc, GtkWidget *focus_widget)
+static void change_focus_to_editor(GeanyDocument *doc)
 {
-	/* idx might not be valid e.g. if user closed a tab whilst Geany is opening files */
-	if (DOC_VALID(doc))
-	{
-		GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window));
-		GtkWidget *sci = GTK_WIDGET(doc->editor->sci);
-
-		if (focusw == focus_widget)
-			gtk_widget_grab_focus(sci);
-	}
-	return FALSE;
+	if (may_steal_focus)
+		document_try_focus(doc);
+	may_steal_focus = FALSE;
 }
 
 
-static gboolean change_focus_cb(gpointer data)
+static gboolean on_openfiles_tree_selection_changed(GtkTreeSelection *selection)
 {
-	change_focus_to_editor(data, tv.tree_openfiles);
-
-	return FALSE;
-}
-
-
-static void on_openfiles_tree_selection_changed(GtkTreeSelection *selection, gpointer data)
-{
 	GtkTreeIter iter;
 	GtkTreeModel *model;
 	GeanyDocument *doc = NULL;
@@ -734,14 +721,18 @@
 	/* use switch_notebook_page to ignore changing the notebook page because it is already done */
 	if (gtk_tree_selection_get_selected(selection, &model, &iter) && ! ignore_callback)
 	{
+		gint pos;
 		gtk_tree_model_get(model, &iter, DOCUMENTS_DOCUMENT, &doc, -1);
 		if (! doc)
-			return;	/* parent */
-		gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook),
-					gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook),
-					(GtkWidget*) doc->editor->sci));
-		g_idle_add((GSourceFunc) change_focus_cb, doc);
+			return FALSE;	/* parent */
+		pos = sci_get_current_position(doc->editor->sci);
+
+		/* we could just reload, but that would destroy the notification about
+		 * the file being modified if it was externally, so fill in all required fields */
+		document_open_file_full(NULL, doc->file_name, pos,
+			doc->readonly, doc->file_type, doc->encoding);
 	}
+	return FALSE;
 }
 
 
@@ -767,7 +758,7 @@
 			if (doc != NULL)
 			{
 				navqueue_goto_line(doc, doc, line);
-				change_focus_to_editor(doc, doc->priv->tag_tree);
+				change_focus_to_editor(doc);
 			}
 		}
 	}
@@ -775,29 +766,35 @@
 }
 
 
-static gboolean on_treeviews_key_press_event(GtkWidget *widget, GdkEventKey *event,
+static gboolean treeviews_key_press_cb(GtkWidget *widget, GdkEventKey *event,
 											 gpointer user_data)
 {
+	may_steal_focus = FALSE;
 	if (event->keyval == GDK_Return ||
 		event->keyval == GDK_ISO_Enter ||
 		event->keyval == GDK_KP_Enter ||
 		event->keyval == GDK_space)
 	{
+		may_steal_focus = TRUE;
 		GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
 		/* delay the query of selection state because this callback is executed before GTK
 		 * changes the selection (g_signal_connect_after would be better but it doesn't work) */
-		g_idle_add((GSourceFunc) on_taglist_tree_selection_changed, select);
+		if (widget ==  tv.tree_openfiles) /* tag and doc list have separate handlers */
+			g_idle_add((GSourceFunc) on_openfiles_tree_selection_changed, select);
+		else
+			g_idle_add((GSourceFunc) on_taglist_tree_selection_changed, select);
 	}
 	return FALSE;
 }
 
 
-static gboolean on_symbols_button_press_event(GtkWidget *widget, GdkEventButton *event,
+static gboolean treeviews_button_press_cb(GtkWidget *widget, GdkEventButton *event,
 		G_GNUC_UNUSED gpointer user_data)
 {
 	GtkTreeSelection *selection;
 
 	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
+	may_steal_focus = TRUE;
 
 	if (event->type == GDK_2BUTTON_PRESS)
 	{	/* double click on parent node(section) expands/collapses it */
@@ -824,18 +821,31 @@
 	{	/* allow reclicking of taglist treeview item */
 		/* delay the query of selection state because this callback is executed before GTK
 		 * changes the selection (g_signal_connect_after would be better but it doesn't work) */
-		g_idle_add((GSourceFunc) on_taglist_tree_selection_changed, selection);
+		if (widget == tv.tree_openfiles)
+			g_idle_add((GSourceFunc) on_openfiles_tree_selection_changed, selection);
+		else
+			g_idle_add((GSourceFunc) on_taglist_tree_selection_changed, selection);
 	}
 	else if (event->button == 3)
 	{
-		gtk_menu_popup(GTK_MENU(tv.popup_taglist), NULL, NULL, NULL, NULL,
-															event->button, event->time);
-		return TRUE;	/* prevent selection changed signal for symbol tags */
+		documents_menu_update(selection);
+		if (widget == tv.tree_openfiles)
+		{
+			if (!openfiles_popup_menu)
+				create_openfiles_popup_menu();
+
+			gtk_menu_popup(GTK_MENU(openfiles_popup_menu), NULL, NULL, NULL, NULL,
+					event->button, event->time);
+		}
+		else
+		{
+			gtk_menu_popup(GTK_MENU(tv.popup_taglist), NULL, NULL, NULL, NULL,
+					event->button, event->time);
+		}
 	}
 	return FALSE;
 }
 
-
 static void documents_menu_update(GtkTreeSelection *selection)
 {
 	GtkTreeModel *model;
@@ -866,26 +876,6 @@
 }
 
 
-static gboolean on_documents_button_release_event(GtkWidget *widget, GdkEventButton *event,
-												gpointer user_data)
-{
-	GtkTreeSelection *selection;
-
-	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
-
-	if (event->button == 3)
-	{
-		if (!openfiles_popup_menu)
-			create_openfiles_popup_menu();
-
-		documents_menu_update(selection);
-		gtk_menu_popup(GTK_MENU(openfiles_popup_menu), NULL, NULL, NULL, NULL,
-			event->button, event->time);
-	}
-	return FALSE;
-}
-
-
 GeanyPrefGroup *stash_group = NULL;
 
 static void on_load_settings(void)


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list