Branch: refs/heads/master Author: LarsDW223 lars_paulsen@web.de Committer: LarsDW223 lars_paulsen@web.de Date: Sun, 21 Jan 2018 18:43:07 UTC Commit: 839819f8d7a57c2c0d97c6a69d87bf3808a22d51 https://github.com/geany/geany-plugins/commit/839819f8d7a57c2c0d97c6a69d87bf...
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).