SF.net SVN: geany: [2085] trunk

eht16 at users.sourceforge.net eht16 at xxxxx
Sun Dec 2 10:52:20 UTC 2007


Revision: 2085
          http://geany.svn.sourceforge.net/geany/?rev=2085&view=rev
Author:   eht16
Date:     2007-12-02 02:52:19 -0800 (Sun, 02 Dec 2007)

Log Message:
-----------
Add search_show_find_in_files_dialog() to the plugin API.
Make path entry of filebrowser plugin editable.
Add "Open with" and "Find in Files" popup menu items to filebrowser  plugin and add configuration dialog.	    

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/plugins/filebrowser.c
    trunk/plugins/pluginmacros.h
    trunk/src/callbacks.c
    trunk/src/plugindata.h
    trunk/src/plugins.c
    trunk/src/search.c
    trunk/src/search.h
    trunk/src/utils.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-12-01 17:53:36 UTC (rev 2084)
+++ trunk/ChangeLog	2007-12-02 10:52:19 UTC (rev 2085)
@@ -1,3 +1,14 @@
+2007-12-02  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
+
+ * plugins/filebrowser.c, plugins/pluginmacros.h, src/callbacks.c,
+   src/plugins.c, src/plugindata.h, src/search.c, src/search.h,
+   src/utils.c:
+   Add search_show_find_in_files_dialog() to the plugin API.
+   Make path entry of filebrowser plugin editable.
+   Add "Open with" and "Find in Files" popup menu items to filebrowser
+   plugin and add configuration dialog.
+
+
 2007-12-01  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
 
  * src/templates.c:

Modified: trunk/plugins/filebrowser.c
===================================================================
--- trunk/plugins/filebrowser.c	2007-12-01 17:53:36 UTC (rev 2084)
+++ trunk/plugins/filebrowser.c	2007-12-02 10:52:19 UTC (rev 2085)
@@ -66,6 +66,8 @@
 
 static GtkWidget	*path_entry;
 static gchar		*current_dir = NULL;	// in locale-encoding
+static gchar		*open_cmd;				// in locale-encoding
+static gchar		*config_file;
 
 
 // Returns: whether name should be hidden.
@@ -154,6 +156,10 @@
 	gchar *utf8_dir;
 	GSList *list;
 
+	// don't clear when the new path doesn't exist
+	if (! g_file_test(current_dir, G_FILE_TEST_EXISTS))
+		return;
+
 	clear();
 
 	utf8_dir = utils->get_utf8_from_locale(current_dir);
@@ -184,7 +190,7 @@
 	if (project)
 		dir = project->base_path;
 	if (NZV(dir))
-		return g_strdup(dir);
+		return utils->get_locale_from_utf8(dir);
 
 	return g_get_current_dir();
 }
@@ -213,7 +219,7 @@
 }
 
 
-static void handle_selection(GList *list, GtkTreeSelection *treesel)
+static void handle_selection(GList *list, GtkTreeSelection *treesel, gboolean external)
 {
 	GList *item;
 	GtkTreeModel *model = GTK_TREE_MODEL(file_store);
@@ -252,14 +258,35 @@
 		gtk_tree_model_get_iter(model, &iter, treepath);
 		gtk_tree_model_get(model, &iter, FILEVIEW_COLUMN_NAME, &name, -1);
 
+		if (utils->str_equal(current_dir, G_DIR_SEPARATOR_S)) /// TODO test this on Windows
+			dir_sep = "";
 		setptr(name, utils->get_locale_from_utf8(name));
-		if (utils->str_equal(current_dir, G_DIR_SEPARATOR_S))
-			dir_sep = "";
 		fname = g_strconcat(current_dir, dir_sep, name, NULL);
 		g_free(name);
 
-		if (dir_found)
+		if (external)
 		{
+			gchar *cmd;
+			gchar *dir;
+			GString *cmd_str = g_string_new(open_cmd);
+
+			if (! dir_found)
+				dir = g_path_get_dirname(fname);
+			else
+				dir = g_strdup(fname);
+
+			utils->string_replace_all(cmd_str, "%f", fname);
+			utils->string_replace_all(cmd_str, "%d", dir);
+
+			cmd = g_string_free(cmd_str, FALSE);
+			setptr(cmd, utils->get_locale_from_utf8(cmd));
+			g_spawn_command_line_async(cmd, NULL);
+			g_free(cmd);
+			g_free(dir);
+			g_free(fname);
+		}
+		else if (dir_found)
+		{
 			setptr(current_dir, fname);
 			refresh();
 			return;
@@ -273,7 +300,7 @@
 }
 
 
-static void open_selected_files()
+static void open_selected_files(GtkMenuItem *menuitem, gpointer user_data)
 {
 	GtkTreeSelection *treesel;
 	GtkTreeModel *model;
@@ -282,13 +309,58 @@
 	treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(file_view));
 
 	list = gtk_tree_selection_get_selected_rows(treesel, &model);
-	handle_selection(list, treesel);
+	handle_selection(list, treesel, GPOINTER_TO_INT(user_data));
 
 	g_list_foreach(list, (GFunc) gtk_tree_path_free, NULL);
 	g_list_free(list);
 }
 
 
+static void on_find_in_files(GtkMenuItem *menuitem, gpointer user_data)
+{
+	GtkTreeSelection *treesel;
+	GtkTreeModel *model;
+	GtkTreePath *treepath;
+	GtkTreeIter iter;
+	GList *list;
+	GList *item;
+	gchar *icon;
+	gchar *dir;
+	gchar *name;
+	gboolean is_dir = FALSE;
+
+	treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(file_view));
+	if (gtk_tree_selection_count_selected_rows(treesel) != 1)
+		return;
+
+	list = gtk_tree_selection_get_selected_rows(treesel, &model);
+	for (item = list; item != NULL; item = g_list_next(item))
+	{
+		treepath = (GtkTreePath*) item->data;
+		gtk_tree_model_get_iter(model, &iter, treepath);
+		gtk_tree_model_get(model, &iter,
+			FILEVIEW_COLUMN_ICON, &icon,
+			FILEVIEW_COLUMN_NAME, &name, -1);
+
+		if (utils->str_equal(icon, GTK_STOCK_DIRECTORY))
+			is_dir = TRUE;
+		g_free(icon);
+	}
+
+	g_list_foreach(list, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free(list);
+
+	if (is_dir)
+		dir = g_strconcat(current_dir, G_DIR_SEPARATOR_S, name, NULL);
+	else
+		dir = g_strdup(current_dir);
+
+	setptr(dir, utils->get_utf8_from_locale(dir));
+	search->show_find_in_files_dialog(dir);
+	g_free(dir);
+}
+
+
 static void on_hidden_files_clicked(GtkCheckMenuItem *item)
 {
 	show_hidden_files = gtk_check_menu_item_get_active(item);
@@ -298,7 +370,7 @@
 
 static GtkWidget *create_popup_menu()
 {
-	GtkWidget *item, *menu;
+	GtkWidget *item, *menu, *image;
 
 	menu = gtk_menu_new();
 
@@ -306,8 +378,26 @@
 	gtk_widget_show(item);
 	gtk_container_add(GTK_CONTAINER(menu), item);
 	g_signal_connect((gpointer) item, "activate",
-		G_CALLBACK(open_selected_files), NULL);
+		G_CALLBACK(open_selected_files), GINT_TO_POINTER(FALSE));
 
+
+	image = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
+	gtk_widget_show(image);
+	item = gtk_image_menu_item_new_with_mnemonic(_("Open _with ..."));
+	gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
+	gtk_widget_show(item);
+	gtk_container_add(GTK_CONTAINER(menu), item);
+	g_signal_connect((gpointer) item, "activate",
+		G_CALLBACK(open_selected_files), GINT_TO_POINTER(TRUE));
+
+	image = gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_MENU);
+	gtk_widget_show(image);
+	item = gtk_image_menu_item_new_with_mnemonic(_("_Find in Files"));
+	gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
+	gtk_widget_show(item);
+	gtk_container_add(GTK_CONTAINER(menu), item);
+	g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_find_in_files), NULL);
+
 	item = gtk_separator_menu_item_new();
 	gtk_widget_show(item);
 	gtk_container_add(GTK_CONTAINER(menu), item);
@@ -315,8 +405,7 @@
 	item = gtk_check_menu_item_new_with_mnemonic(_("Show _Hidden Files"));
 	gtk_widget_show(item);
 	gtk_container_add(GTK_CONTAINER(menu), item);
-	g_signal_connect((gpointer) item, "activate",
-		G_CALLBACK(on_hidden_files_clicked), NULL);
+	g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_hidden_files_clicked), NULL);
 
 	item = gtk_separator_menu_item_new();
 	gtk_widget_show(item);
@@ -338,7 +427,7 @@
 static gboolean on_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 {
 	if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
-		open_selected_files();
+		open_selected_files(NULL, NULL);
 	else
 	if (event->button == 3)
 	{
@@ -369,7 +458,7 @@
 		|| event->keyval == GDK_ISO_Enter
 		|| event->keyval == GDK_KP_Enter
 		|| event->keyval == GDK_space)
-		open_selected_files();
+		open_selected_files(NULL, NULL);
 
 	if ((event->keyval == GDK_Up ||
 		event->keyval == GDK_KP_Up) &&
@@ -379,6 +468,19 @@
 }
 
 
+static void on_path_entry_activate(GtkEntry *entry, gpointer user_data)
+{
+	gchar *new_dir = (gchar*) gtk_entry_get_text(entry);
+	if (NZV(new_dir))
+		new_dir = utils->get_locale_from_utf8(new_dir);
+	else
+		new_dir = g_strdup(g_get_home_dir());
+
+	setptr(current_dir, new_dir);
+	refresh();
+}
+
+
 static void prepare_file_view()
 {
 	GtkCellRenderer *text_renderer, *icon_renderer;
@@ -457,17 +559,29 @@
 }
 
 
+#define CHECK_READ_SETTING(var, error, tmp) \
+	if ((error) != NULL) \
+	{ \
+		g_error_free((error)); \
+		(error) = NULL; \
+	} \
+	else \
+		(var) = (tmp);
+
 void init(GeanyData *data)
 {
 	GtkWidget *scrollwin, *toolbar;
+	GKeyFile *config = g_key_file_new();
+	GError *error = NULL;
+	gboolean tmp;
 
 	file_view_vbox = gtk_vbox_new(FALSE, 0);
 	toolbar = make_toolbar();
 	gtk_box_pack_start(GTK_BOX(file_view_vbox), toolbar, FALSE, FALSE, 0);
 
 	path_entry = gtk_entry_new();
-	gtk_editable_set_editable(GTK_EDITABLE(path_entry), FALSE);
 	gtk_box_pack_start(GTK_BOX(file_view_vbox), path_entry, FALSE, FALSE, 2);
+	g_signal_connect(G_OBJECT(path_entry), "activate", G_CALLBACK(on_path_entry_activate), NULL);
 
 	file_view = gtk_tree_view_new();
 	prepare_file_view();
@@ -482,10 +596,114 @@
 	gtk_widget_show_all(file_view_vbox);
 	gtk_notebook_append_page(GTK_NOTEBOOK(app->treeview_notebook), file_view_vbox,
 		gtk_label_new(_("Files")));
+
+	config_file = g_strconcat(app->configdir, G_DIR_SEPARATOR_S, "plugins", G_DIR_SEPARATOR_S,
+		"filebrowser", G_DIR_SEPARATOR_S, "filebrowser.conf", NULL);
+	g_key_file_load_from_file(config, config_file, G_KEY_FILE_NONE, NULL);
+	open_cmd = g_key_file_get_string(config, "filebrowser", "open_command", &error);
+	if (error != NULL)
+	{
+		open_cmd = g_strdup("nautilus \"%d\"");
+		g_error_free(error);
+		error = NULL;
+	}
+	tmp = g_key_file_get_boolean(config, "filebrowser", "show_hidden_files", &error);
+	CHECK_READ_SETTING(show_hidden_files, error, tmp);
+	tmp = g_key_file_get_boolean(config, "filebrowser", "hide_object_files", &error);
+	CHECK_READ_SETTING(hide_object_files, error, tmp);
+
+	g_key_file_free(config);
 }
 
 
+void configure(GtkWidget *parent)
+{
+	GtkWidget *dialog, *label, *entry, *checkbox_of, *checkbox_hf, *vbox;
+	GtkTooltips *tooltips = gtk_tooltips_new();
+
+	dialog = gtk_dialog_new_with_buttons(_("File Browser"),
+		GTK_WINDOW(parent), GTK_DIALOG_DESTROY_WITH_PARENT,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
+	vbox = ui->dialog_vbox_new(GTK_DIALOG(dialog));
+	gtk_widget_set_name(dialog, "GeanyDialog");
+	gtk_box_set_spacing(GTK_BOX(vbox), 6);
+
+	label = gtk_label_new("External open command:");
+	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+	gtk_container_add(GTK_CONTAINER(vbox), label);
+
+	entry = gtk_entry_new();
+	gtk_widget_show(entry);
+	if (open_cmd != NULL)
+		gtk_entry_set_text(GTK_ENTRY(entry), open_cmd);
+	gtk_tooltips_set_tip(tooltips, entry,
+		_("The command to execute when using \"Open with\". You can use %f and %d wildcards.\n"
+		  "%f will be replaced with the filename including full path\n"
+		  "%d will be replaced with the path name of the selected file without the filename"),
+		  NULL);
+	gtk_container_add(GTK_CONTAINER(vbox), entry);
+
+	checkbox_hf = gtk_check_button_new_with_label(_("Show hidden files"));
+	gtk_button_set_focus_on_click(GTK_BUTTON(checkbox_hf), FALSE);
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox_hf), show_hidden_files);
+	gtk_box_pack_start(GTK_BOX(vbox), checkbox_hf, FALSE, FALSE, 5);
+
+	checkbox_of = gtk_check_button_new_with_label(_("Hide object files"));
+	gtk_button_set_focus_on_click(GTK_BUTTON(checkbox_of), FALSE);
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox_of), hide_object_files);
+	gtk_tooltips_set_tip(tooltips, checkbox_of,
+		_("Don't show generated object files in the file browser, this includes "
+		  "*.o, *.obj. *.so, *.dll, *.a, *.lib"),
+		  NULL);
+	gtk_box_pack_start(GTK_BOX(vbox), checkbox_of, FALSE, FALSE, 5);
+
+
+	gtk_widget_show_all(vbox);
+
+	// run the dialog and check for the response code
+	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+	{
+		GKeyFile *config = g_key_file_new();
+		gchar *data;
+		gchar *config_dir = g_path_get_dirname(config_file);
+
+		g_free(open_cmd);
+		open_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
+		show_hidden_files = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox_hf));
+		hide_object_files = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox_of));
+
+		g_key_file_load_from_file(config, config_file, G_KEY_FILE_NONE, NULL);
+
+		g_key_file_set_string(config, "filebrowser", "open_command", open_cmd);
+		g_key_file_set_boolean(config, "filebrowser", "show_hidden_files", show_hidden_files);
+		g_key_file_set_boolean(config, "filebrowser", "hide_object_files", hide_object_files);
+
+		if (! g_file_test(config_dir, G_FILE_TEST_IS_DIR) && utils->mkdir(config_dir, TRUE) != 0)
+		{
+			dialogs->show_msgbox(GTK_MESSAGE_ERROR,
+				_("Plugin configuration directory could not be created."));
+		}
+		else
+		{
+			// write config to file
+			data = g_key_file_to_data(config, NULL, NULL);
+			utils->write_file(config_file, data);
+			g_free(data);
+		}
+
+		// apply the changes
+		refresh();
+
+		g_free(config_dir);
+		g_key_file_free(config);
+	}
+	gtk_widget_destroy(dialog);
+}
+
+
 void cleanup()
 {
+	g_free(config_file);
+	g_free(open_cmd);
 	gtk_widget_destroy(file_view_vbox);
 }

Modified: trunk/plugins/pluginmacros.h
===================================================================
--- trunk/plugins/pluginmacros.h	2007-12-01 17:53:36 UTC (rev 2084)
+++ trunk/plugins/pluginmacros.h	2007-12-02 10:52:19 UTC (rev 2085)
@@ -38,6 +38,7 @@
 #define keybindings	geany_data->keybindings
 #define msgwindow	geany_data->msgwindow
 #define scintilla	geany_data->sci
+#define search		geany_data->search
 #define support		geany_data->support
 #define templates	geany_data->templates
 #define tagmanager	geany_data->tm			// avoids conflict with "struct tm *t"

Modified: trunk/src/callbacks.c
===================================================================
--- trunk/src/callbacks.c	2007-12-01 17:53:36 UTC (rev 2084)
+++ trunk/src/callbacks.c	2007-12-02 10:52:19 UTC (rev 2085)
@@ -1187,7 +1187,7 @@
 on_find_in_files1_activate             (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	search_show_find_in_files_dialog();
+	search_show_find_in_files_dialog(NULL);
 }
 
 

Modified: trunk/src/plugindata.h
===================================================================
--- trunk/src/plugindata.h	2007-12-01 17:53:36 UTC (rev 2084)
+++ trunk/src/plugindata.h	2007-12-02 10:52:19 UTC (rev 2085)
@@ -93,7 +93,7 @@
 
 /* The API version should be incremented whenever any plugin data types below are
  * modified or appended to. */
-static const gint api_version = 33;
+static const gint api_version = 34;
 
 /* The ABI version should be incremented whenever existing fields in the plugin
  * data types below have to be changed or reordered. It should stay the same if fields
@@ -195,6 +195,7 @@
 	struct EncodingFuncs	*encoding;
 	struct KeybindingFuncs	*keybindings;
 	struct TagManagerFuncs	*tm;
+	struct SearchFuncs		*search;
 }
 GeanyData;
 
@@ -337,6 +338,13 @@
 KeybindingFuncs;
 
 
+typedef struct SearchFuncs
+{
+	void		(*show_find_in_files_dialog) (const gchar *dir);
+}
+SearchFuncs;
+
+
 typedef struct TagManagerFuncs
 {
 	gchar*		(*get_real_path) (const gchar *file_name);

Modified: trunk/src/plugins.c
===================================================================
--- trunk/src/plugins.c	2007-12-01 17:53:36 UTC (rev 2084)
+++ trunk/src/plugins.c	2007-12-02 10:52:19 UTC (rev 2085)
@@ -49,6 +49,7 @@
 #include "geanyobject.h"
 #include "build.h"
 #include "encodings.h"
+#include "search.h"
 
 void keybindings_cmd(gint cmd_id);	// don't require keybindings.h enum in plugindata.h
 
@@ -182,7 +183,11 @@
 	&tm_get_real_path
 };
 
+static SearchFuncs search_funcs = {
+	&search_show_find_in_files_dialog
+};
 
+
 static GeanyData geany_data = {
 	NULL,
 	NULL,
@@ -203,6 +208,7 @@
 	&encoding_funcs,
 	&keybindings_funcs,
 	&tagmanager_funcs,
+	&search_funcs,
 };
 
 

Modified: trunk/src/search.c
===================================================================
--- trunk/src/search.c	2007-12-01 17:53:36 UTC (rev 2084)
+++ trunk/src/search.c	2007-12-02 10:52:19 UTC (rev 2085)
@@ -543,7 +543,9 @@
 }
 
 
-void search_show_find_in_files_dialog()
+/* dir is the directory to search in (UTF-8 encoding), maybe NULL to determine it the usual way
+ * by using the current file's path */
+void search_show_find_in_files_dialog(const gchar *dir)
 {
 	static GtkWidget *combo = NULL;
 	static GtkWidget *dir_combo;
@@ -552,7 +554,7 @@
 	gchar *sel = NULL;
 	gchar *cur_dir;
 
-	if (idx == -1 || ! doc_list[idx].is_valid) return;
+	if (! DOC_IDX_VALID(idx)) return;
 
 	if (widgets.find_in_files_dialog == NULL)
 	{
@@ -712,7 +714,10 @@
 	g_free(sel);
 
 	entry = GTK_BIN(dir_combo)->child;
-	cur_dir = utils_get_current_file_dir();
+	if (NZV(dir))
+		cur_dir = g_strdup(dir);
+	else
+		cur_dir = utils_get_current_file_dir();
 	if (cur_dir)
 	{
 		gtk_entry_set_text(GTK_ENTRY(entry), cur_dir);

Modified: trunk/src/search.h
===================================================================
--- trunk/src/search.h	2007-12-01 17:53:36 UTC (rev 2084)
+++ trunk/src/search.h	2007-12-02 10:52:19 UTC (rev 2085)
@@ -55,7 +55,7 @@
 
 void search_show_replace_dialog();
 
-void search_show_find_in_files_dialog();
+void search_show_find_in_files_dialog(const gchar *dir);
 
 void search_find_usage(const gchar *search_text, gint flags, gboolean in_session);
 

Modified: trunk/src/utils.c
===================================================================
--- trunk/src/utils.c	2007-12-01 17:53:36 UTC (rev 2084)
+++ trunk/src/utils.c	2007-12-02 10:52:19 UTC (rev 2085)
@@ -1039,12 +1039,12 @@
 
 /* Get directory from current file in the notebook.
  * Returns dir string that should be freed or NULL, depending on whether current file is valid.
- * (thanks to Nick Treleaven for this patch) */
+ * Returned string is in UTF-8 encoding */
 gchar *utils_get_current_file_dir()
 {
 	gint cur_idx = document_get_cur_idx();
 
-	if (cur_idx >= 0 && doc_list[cur_idx].is_valid) // if valid page found
+	if (DOC_IDX_VALID(cur_idx)) // if valid page found
 	{
 		// get current filename
 		const gchar *cur_fname = doc_list[cur_idx].file_name;


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