[geany/geany-plugins] 839819: workbench: added "Create file here..."/"Create directory here..."

LarsDW223 git-noreply at xxxxx
Sun Jan 21 18:43:07 UTC 2018


Branch:      refs/heads/master
Author:      LarsDW223 <lars_paulsen at web.de>
Committer:   LarsDW223 <lars_paulsen at web.de>
Date:        Sun, 21 Jan 2018 18:43:07 UTC
Commit:      839819f8d7a57c2c0d97c6a69d87bf3808a22d51
             https://github.com/geany/geany-plugins/commit/839819f8d7a57c2c0d97c6a69d87bf3808a22d51

Log Message:
-----------
workbench: added "Create file here..."/"Create directory here..."

The user can now select from two new context menu items to either
create a new file or a new directory on the current selected position
in the file tree. See #660.


Modified Paths:
--------------
    workbench/README
    workbench/src/dialogs.c
    workbench/src/dialogs.h
    workbench/src/plugin_main.c
    workbench/src/popup_menu.c
    workbench/src/sidebar.c
    workbench/src/wb_project.c

Modified: workbench/README
8 lines changed, 8 insertions(+), 0 deletions(-)
===================================================================
@@ -133,6 +133,14 @@ These are the available items:
   Remove file from the Workbench or project bookmarks. It is only available
   if you right clicked on a bookmark.
 
+**Create file here...**
+  Select this item to create a new file at the current selected position
+  in the file tree. Available since version 1.02 of the workbench plugin.
+
+**Create directory here...**
+  Select this item to create a new directory at the current selected position
+  in the file tree. Available since version 1.02 of the workbench plugin.
+
 Known issues
 ============
 


Modified: workbench/src/dialogs.c
71 lines changed, 71 insertions(+), 0 deletions(-)
===================================================================
@@ -28,6 +28,77 @@
 
 extern GeanyPlugin *geany_plugin;
 
+
+/** Shows the dialog "Create new file".
+ *
+ * The dialog lets the user create a new file (filter *).
+ *
+ * @param path The current folder
+ * @return The filename
+ *
+ **/
+gchar *dialogs_create_new_file(const gchar *path)
+{
+	gchar *filename = NULL;
+	GtkWidget *dialog;
+
+	dialog = gtk_file_chooser_dialog_new(_("Create new file"),
+		GTK_WINDOW(wb_globals.geany_plugin->geany_data->main_widgets->window), GTK_FILE_CHOOSER_ACTION_SAVE,
+		_("_Cancel"), GTK_RESPONSE_CANCEL,
+		_("C_reate"), GTK_RESPONSE_ACCEPT, NULL);
+	gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
+
+	if (path != NULL)
+	{
+		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
+	}
+
+	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+	{
+		filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+	}
+
+	gtk_widget_destroy(dialog);
+
+	return filename;
+}
+
+
+/** Shows the dialog "Create new directory".
+ *
+ * The dialog lets the user create a new directory.
+ *
+ * @param path The current folder
+ * @return The filename
+ *
+ **/
+gchar *dialogs_create_new_directory(const gchar *path)
+{
+	gchar *filename = NULL;
+	GtkWidget *dialog;
+
+	dialog = gtk_file_chooser_dialog_new(_("Create new directory"),
+		GTK_WINDOW(wb_globals.geany_plugin->geany_data->main_widgets->window), GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER,
+		_("_Cancel"), GTK_RESPONSE_CANCEL,
+		_("C_reate"), GTK_RESPONSE_ACCEPT, NULL);
+	gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
+
+	if (path != NULL)
+	{
+		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
+	}
+
+	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+	{
+		filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+	}
+
+	gtk_widget_destroy(dialog);
+
+	return filename;
+}
+
+
 /** Shows the dialog "Create new workbench".
  *
  * The dialog lets the user create a new workbench file (filter *.geanywb).


Modified: workbench/src/dialogs.h
2 lines changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -19,6 +19,8 @@
 #ifndef __WB_DIALOGS_H__
 #define __WB_DIALOGS_H__
 
+gchar *dialogs_create_new_file(const gchar *path);
+gchar *dialogs_create_new_directory(const gchar *path);
 gchar *dialogs_create_new_workbench(void);
 gchar *dialogs_open_workbench(void);
 gchar *dialogs_add_project(void);


Modified: workbench/src/plugin_main.c
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -128,7 +128,7 @@ void geany_load_module(GeanyPlugin *plugin)
 	/* Set metadata */
 	plugin->info->name = _("Workbench");
 	plugin->info->description = _("Manage and customize multiple projects.");
-	plugin->info->version = "1.01";
+	plugin->info->version = "1.02";
 	plugin->info->author = "LarsGit223";
 
 	/* Set functions */


Modified: workbench/src/popup_menu.c
114 lines changed, 114 insertions(+), 0 deletions(-)
===================================================================
@@ -19,9 +19,12 @@
 /*
  * Code for the popup menu.
  */
+#include <errno.h>
 #include <sys/time.h>
 #include <gdk/gdkkeysyms.h>
 #include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
 
 #ifdef HAVE_CONFIG_H
 	#include "config.h"
@@ -57,6 +60,8 @@ static struct
 	GtkWidget *add_wb_bookmark;
 	GtkWidget *add_prj_bookmark;
 	GtkWidget *remove_bookmark;
+	GtkWidget *new_file;
+	GtkWidget *new_directory;
 } s_popup_menu;
 
 
@@ -91,6 +96,8 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
 			gtk_widget_set_sensitive (s_popup_menu.remove_bookmark, FALSE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_open_all, FALSE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_close_all, FALSE);
+			gtk_widget_set_sensitive (s_popup_menu.new_file, FALSE);
+			gtk_widget_set_sensitive (s_popup_menu.new_directory, FALSE);
 		break;
 		case POPUP_CONTEXT_DIRECTORY:
 			gtk_widget_set_sensitive (s_popup_menu.add_project, TRUE);
@@ -110,6 +117,8 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
 			gtk_widget_set_sensitive (s_popup_menu.remove_bookmark, FALSE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_open_all, FALSE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_close_all, FALSE);
+			gtk_widget_set_sensitive (s_popup_menu.new_file, TRUE);
+			gtk_widget_set_sensitive (s_popup_menu.new_directory, TRUE);
 		break;
 		case POPUP_CONTEXT_SUB_DIRECTORY:
 			gtk_widget_set_sensitive (s_popup_menu.add_project, TRUE);
@@ -129,6 +138,8 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
 			gtk_widget_set_sensitive (s_popup_menu.remove_bookmark, FALSE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_open_all, TRUE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_close_all, TRUE);
+			gtk_widget_set_sensitive (s_popup_menu.new_file, TRUE);
+			gtk_widget_set_sensitive (s_popup_menu.new_directory, TRUE);
 		break;
 		case POPUP_CONTEXT_FILE:
 			gtk_widget_set_sensitive (s_popup_menu.add_project, TRUE);
@@ -148,6 +159,8 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
 			gtk_widget_set_sensitive (s_popup_menu.remove_bookmark, FALSE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_open_all, TRUE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_close_all, TRUE);
+			gtk_widget_set_sensitive (s_popup_menu.new_file, TRUE);
+			gtk_widget_set_sensitive (s_popup_menu.new_directory, TRUE);
 		break;
 		case POPUP_CONTEXT_BACKGROUND:
 			gtk_widget_set_sensitive (s_popup_menu.add_project, TRUE);
@@ -167,6 +180,8 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
 			gtk_widget_set_sensitive (s_popup_menu.remove_bookmark, FALSE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_open_all, FALSE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_close_all, FALSE);
+			gtk_widget_set_sensitive (s_popup_menu.new_file, FALSE);
+			gtk_widget_set_sensitive (s_popup_menu.new_directory, FALSE);
 		break;
 		case POPUP_CONTEXT_WB_BOOKMARK:
 			gtk_widget_set_sensitive (s_popup_menu.add_project, TRUE);
@@ -186,6 +201,8 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
 			gtk_widget_set_sensitive (s_popup_menu.remove_bookmark, TRUE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_open_all, FALSE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_close_all, FALSE);
+			gtk_widget_set_sensitive (s_popup_menu.new_file, FALSE);
+			gtk_widget_set_sensitive (s_popup_menu.new_directory, FALSE);
 		break;
 		case POPUP_CONTEXT_PRJ_BOOKMARK:
 			gtk_widget_set_sensitive (s_popup_menu.add_project, TRUE);
@@ -205,6 +222,8 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
 			gtk_widget_set_sensitive (s_popup_menu.remove_bookmark, TRUE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_open_all, FALSE);
 			gtk_widget_set_sensitive (s_popup_menu.subdir_close_all, FALSE);
+			gtk_widget_set_sensitive (s_popup_menu.new_file, FALSE);
+			gtk_widget_set_sensitive (s_popup_menu.new_directory, FALSE);
 		break;
 	}
 	gtk_menu_popup(GTK_MENU(s_popup_menu.widget), NULL, NULL, NULL, NULL,
@@ -506,6 +525,85 @@ static void popup_menu_on_subdir_close_all (G_GNUC_UNUSED GtkMenuItem *menuitem,
 }
 
 
+/* Handle popup menu item "Create new file here..." */
+static void popup_menu_on_new_file(G_GNUC_UNUSED GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer user_data)
+{
+	gchar *filename, *path = NULL, *abs_path = NULL;
+	SIDEBAR_CONTEXT context;
+
+	if (sidebar_file_view_get_selected_context(&context))
+	{
+		if (context.subdir != NULL)
+		{
+			path = context.subdir;
+			abs_path = g_strdup(path);
+		}
+		else
+		{
+			path = wb_project_dir_get_base_dir(context.directory);
+			abs_path = get_combined_path(wb_project_get_filename(context.project), path);
+		}
+	}
+
+	filename = dialogs_create_new_file(abs_path);
+	if (filename == NULL)
+	{
+		return;
+	}
+	else if (!g_file_test (filename, G_FILE_TEST_EXISTS))
+	{
+		FILE *new_file;
+		new_file = g_fopen (filename, "w");
+		if (new_file == NULL)
+		{
+			dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Could not create new file \"%s\":\n\n%s"), filename, strerror(errno));
+		}
+		else
+		{
+			fclose(new_file);
+			wb_project_dir_rescan(context.project, context.directory);
+			sidebar_update(SIDEBAR_CONTEXT_DIRECTORY_RESCANNED, &context);
+			document_open_file(filename, FALSE, NULL, NULL);
+		}
+	}
+
+	g_free(abs_path);
+	g_free(filename);
+}
+
+
+/* Handle popup menu item "Create new directory here..." */
+static void popup_menu_on_new_directory(G_GNUC_UNUSED GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer user_data)
+{
+	gchar *filename, *path = NULL, *abs_path = NULL;
+	SIDEBAR_CONTEXT context;
+
+	if (sidebar_file_view_get_selected_context(&context))
+	{
+		if (context.subdir != NULL)
+		{
+			path = context.subdir;
+			abs_path = g_strdup(path);
+		}
+		else
+		{
+			path = wb_project_dir_get_base_dir(context.directory);
+			abs_path = get_combined_path(wb_project_get_filename(context.project), path);
+		}
+	}
+
+	filename = dialogs_create_new_directory(abs_path);
+	if (filename != NULL)
+	{
+		wb_project_dir_rescan(context.project, context.directory);
+		sidebar_update(SIDEBAR_CONTEXT_DIRECTORY_RESCANNED, &context);
+	}
+
+	g_free(abs_path);
+	g_free(filename);
+}
+
+
 /** Setup/Initialize the popup menu.
  *
  **/
@@ -650,4 +748,20 @@ void popup_menu_init(void)
 	gtk_container_add(GTK_CONTAINER(s_popup_menu.widget), item);
 	g_signal_connect(item, "activate", G_CALLBACK(popup_menu_on_remove_from_bookmarks), NULL);
 	s_popup_menu.remove_bookmark = item;
+
+	item = gtk_separator_menu_item_new();
+	gtk_widget_show(item);
+	gtk_container_add(GTK_CONTAINER(s_popup_menu.widget), item);
+
+	item = gtk_menu_item_new_with_mnemonic(_("_Create file here..."));
+	gtk_widget_show(item);
+	gtk_container_add(GTK_CONTAINER(s_popup_menu.widget), item);
+	g_signal_connect(item, "activate", G_CALLBACK(popup_menu_on_new_file), NULL);
+	s_popup_menu.new_file = item;
+
+	item = gtk_menu_item_new_with_mnemonic(_("_Create directory here..."));
+	gtk_widget_show(item);
+	gtk_container_add(GTK_CONTAINER(s_popup_menu.widget), item);
+	g_signal_connect(item, "activate", G_CALLBACK(popup_menu_on_new_directory), NULL);
+	s_popup_menu.new_directory = item;
 }


Modified: workbench/src/sidebar.c
44 lines changed, 38 insertions(+), 6 deletions(-)
===================================================================
@@ -96,7 +96,7 @@ static void sidebar_create_branch(gint level, const gchar *abs_base_dir, GSList
 	GSList *dir_list = NULL;
 	GSList *file_list = NULL;
 	GSList *elem = NULL;
-	gchar **path_arr;
+	gchar **path_arr, *part, *full, *dirpath;
 
 	foreach_slist (elem, leaf_list)
 	{
@@ -105,21 +105,35 @@ static void sidebar_create_branch(gint level, const gchar *abs_base_dir, GSList
 			continue;
 		}
 		path_arr = elem->data;
+		if (path_arr[level] == NULL)
+		{
+			continue;
+		}
 
 		if (path_arr[level+1] != NULL)
 		{
 			dir_list = g_slist_prepend(dir_list, path_arr);
 		}
 		else
 		{
-			file_list = g_slist_prepend(file_list, path_arr);
+			// Extra check for empty directories
+			part = g_build_filenamev(path_arr);
+			dirpath = g_build_filename(abs_base_dir, part, NULL);
+			if (dirpath != NULL && g_file_test (dirpath, G_FILE_TEST_IS_DIR))
+			{
+				dir_list = g_slist_prepend(dir_list, path_arr);
+				g_free(dirpath);
+			}
+			else
+			{
+				file_list = g_slist_prepend(file_list, path_arr);
+			}
 		}
 	}
 
 	foreach_slist (elem, file_list)
 	{
 		GtkTreeIter iter;
-		gchar *part, *full;
 		GIcon *icon = NULL;
 
 		path_arr = elem->data;
@@ -177,6 +191,10 @@ static void sidebar_create_branch(gint level, const gchar *abs_base_dir, GSList
 		{
 			gboolean dir_changed;
 
+			part = g_build_filenamev(path_arr);
+			full = g_build_filename(abs_base_dir, part, NULL);
+			g_free(part);
+
 			path_arr = (gchar **) elem->data;
 			dir_changed = g_strcmp0(last_dir_name, path_arr[level]) != 0;
 
@@ -186,6 +204,7 @@ static void sidebar_create_branch(gint level, const gchar *abs_base_dir, GSList
 					FILEVIEW_COLUMN_ICON, icon_dir,
 					FILEVIEW_COLUMN_NAME, last_dir_name,
 					FILEVIEW_COLUMN_DATA_ID, DATA_ID_SUB_DIRECTORY,
+					FILEVIEW_COLUMN_ASSIGNED_DATA_POINTER, g_strdup(full),
 					-1);
 
 				sidebar_create_branch(level+1, abs_base_dir, tmp_list, &iter);
@@ -194,15 +213,22 @@ static void sidebar_create_branch(gint level, const gchar *abs_base_dir, GSList
 				tmp_list = NULL;
 				last_dir_name = path_arr[level];
 			}
+			g_free(full);
 
 			tmp_list = g_slist_prepend(tmp_list, path_arr);
 		}
 
+		part = g_build_filenamev(path_arr);
+		full = g_build_filename(abs_base_dir, part, NULL);
+		g_free(part);
+
 		gtk_tree_store_insert_with_values(sidebar.file_store, &iter, parent, 0,
 			FILEVIEW_COLUMN_ICON, icon_dir,
 			FILEVIEW_COLUMN_NAME, last_dir_name,
 			FILEVIEW_COLUMN_DATA_ID, DATA_ID_SUB_DIRECTORY,
+			FILEVIEW_COLUMN_ASSIGNED_DATA_POINTER, g_strdup(full),
 			-1);
+			g_free(full);
 
 		sidebar_create_branch(level+1, abs_base_dir, tmp_list, &iter);
 
@@ -221,7 +247,7 @@ static void sidebar_create_branch(gint level, const gchar *abs_base_dir, GSList
 /* Reverse strcmp */
 static int rev_strcmp(const char *str1, const char *str2)
 {
-	return strcmp(str2, str1);
+	return g_strcmp0(str2, str1);
 }
 
 
@@ -241,7 +267,10 @@ static void sidebar_insert_project_directory(WB_PROJECT *prj, WB_PROJECT_DIR *di
 	while (g_hash_table_iter_next(&iter, &key, &value))
 	{
 		gchar *path = get_relative_path(abs_base_dir, key);
-		lst = g_slist_prepend(lst, path);
+		if (path != NULL)
+		{
+			lst = g_slist_prepend(lst, path);
+		}
 	}
 	/* sort in reverse order so we can prepend nodes to the tree store -
 	 * the store behaves as a linked list and prepending is faster */
@@ -961,7 +990,10 @@ gboolean sidebar_file_view_get_selected_context(SIDEBAR_CONTEXT *context)
 						/* Has not got any data. */
 					break;
 					case DATA_ID_SUB_DIRECTORY:
-						context->subdir = data;
+						if (context->subdir == NULL)
+						{
+							context->subdir = data;
+						}
 					break;
 					case DATA_ID_FILE:
 						context->file = data;


Modified: workbench/src/wb_project.c
5 lines changed, 3 insertions(+), 2 deletions(-)
===================================================================
@@ -528,8 +528,9 @@ static guint wb_project_dir_rescan_int(WB_PROJECT *prj, WB_PROJECT_DIR *root)
 	searchdir = get_combined_path(prj->filename, root->base_dir);
 	root->file_count = 0;
 	root->subdir_count = 0;
-	lst = gp_filelist_scan_directory(&(root->file_count), &(root->subdir_count),
-		searchdir, file_patterns, root->ignored_dirs_patterns, root->ignored_file_patterns);
+	lst = gp_filelist_scan_directory_full(&(root->file_count), &(root->subdir_count),
+		searchdir, file_patterns, root->ignored_dirs_patterns, root->ignored_file_patterns,
+		FILELIST_FLAG_ADD_DIRS);
 	g_free(searchdir);
 
 	foreach_slist(elem, lst)



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Plugins-Commits mailing list