[geany/geany-plugins] ca1912: Add file operations to Project Organizer.
Daniel Guerrero
git-noreply at xxxxx
Mon Apr 1 01:03:38 UTC 2019
Branch: refs/heads/master
Author: Daniel Guerrero <dgm at aquilessolutions.com>
Committer: Daniel Guerrero <dgm at aquilessolutions.com>
Date: Fri, 10 Aug 2018 15:07:25 UTC
Commit: ca1912d6c5ebf671af36851b63c2508da6b464e0
https://github.com/geany/geany-plugins/commit/ca1912d6c5ebf671af36851b63c2508da6b464e0
Log Message:
-----------
Add file operations to Project Organizer.
Add file and directory creation, renaming and removal operations to the Project Organizer sidebar.
Modified Paths:
--------------
projectorganizer/src/prjorg-project.c
projectorganizer/src/prjorg-project.h
projectorganizer/src/prjorg-sidebar.c
projectorganizer/src/prjorg-utils.c
projectorganizer/src/prjorg-utils.h
Modified: projectorganizer/src/prjorg-project.c
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -114,6 +114,7 @@ static GSList *get_file_list(const gchar *utf8_path, GSList *patterns,
if (!patterns_match(ignored_dirs_patterns, utf8_name))
{
+ list = g_slist_prepend(list, g_build_path(G_DIR_SEPARATOR_S, utf8_filename, PROJORG_SENTINEL_FILENAME, NULL));
lst = get_file_list(utf8_filename, patterns, ignored_dirs_patterns,
ignored_file_patterns, visited_paths);
if (lst)
Modified: projectorganizer/src/prjorg-project.h
2 lines changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -63,4 +63,6 @@ void prjorg_project_remove_single_tm_file(gchar *utf8_filename);
gboolean prjorg_project_is_in_project(const gchar *utf8_filename);
+#define PROJORG_SENTINEL_FILENAME "..."
+
#endif
Modified: projectorganizer/src/prjorg-sidebar.c
253 lines changed, 253 insertions(+), 0 deletions(-)
===================================================================
@@ -105,6 +105,11 @@ static struct
GtkWidget *find_tag;
GtkWidget *expand;
GtkWidget *remove_external_dir;
+
+ GtkWidget *create_file;
+ GtkWidget *create_dir;
+ GtkWidget *rename;
+ GtkWidget *delete;
} s_popup_menu;
@@ -350,6 +355,206 @@ static void on_remove_external_dir(G_GNUC_UNUSED GtkMenuItem *menuitem, G_GNUC_U
}
+// returned string must be freed
+static gchar* parent_dir_for_create()
+{
+ GtkTreeSelection *treesel;
+ GtkTreeModel *model;
+ GtkTreeIter iter, parent;
+ gchar *path = NULL;
+
+ treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(s_file_view));
+ if (gtk_tree_selection_get_selected(treesel, &model, &iter))
+ {
+ path = build_path(&iter);
+ if (!g_file_test(path, G_FILE_TEST_IS_DIR))
+ {
+ g_print("%s is not dir\n", path);
+ g_free(path);
+ path = NULL;
+ if (gtk_tree_model_iter_parent(model, &parent, &iter))
+ {
+ path = build_path(&parent);
+ }
+ }
+ }
+ return path;
+}
+
+
+static void on_create_file(G_GNUC_UNUSED GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer user_data)
+{
+ gchar *dir, *name, *path;
+
+ dir = parent_dir_for_create();
+ if (NULL == dir)
+ {
+ return;
+ }
+
+ g_print("Creating file in %s\n", dir);
+
+ name = dialogs_show_input(_("New File"), GTK_WINDOW(geany->main_widgets->window),
+ _("Name:"), _("newfile.txt"));
+
+ if (NULL != name)
+ {
+ path = g_build_path(G_DIR_SEPARATOR_S, dir, name, NULL);
+ g_free(name);
+ g_print("new file: %s", path);
+
+ if (create_file(path))
+ {
+ open_file(path);
+ prjorg_project_rescan();
+ prjorg_sidebar_update(TRUE);
+ project_write_config();
+ }
+ else
+ {
+ dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Cannot create new file %s"), path);
+ }
+ g_free(path);
+ }
+ g_free(dir);
+}
+
+
+static void on_create_dir(G_GNUC_UNUSED GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer user_data)
+{
+ gchar *dir, *name, *path;
+
+ dir = parent_dir_for_create();
+ if (NULL == dir)
+ {
+ return;
+ }
+
+ g_print("Creating dir in %s\n", dir);
+
+ name = dialogs_show_input(_("New Directory"), GTK_WINDOW(geany->main_widgets->window),
+ _("Name:"), _("newdir"));
+
+ if (NULL != name)
+ {
+ path = g_build_path(G_DIR_SEPARATOR_S, dir, name, NULL);
+ g_free(name);
+ g_print("new dir: %s", path);
+
+ if (create_dir(path))
+ {
+ prjorg_project_rescan();
+ prjorg_sidebar_update(TRUE);
+ project_write_config();
+ }
+ else
+ {
+ dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Cannot create directory %s"), path);
+ }
+ g_free(path);
+ }
+ g_free(dir);
+}
+
+
+static void on_rename(G_GNUC_UNUSED GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer user_data)
+{
+ GtkTreeSelection *treesel;
+ GtkTreeModel *model;
+ GtkTreeIter iter, parent;
+ gchar *name, *dir, *newname, *oldpath, *newpath;
+
+ g_print("Renaming");
+
+ treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(s_file_view));
+ if (!gtk_tree_selection_get_selected(treesel, &model, &iter))
+ {
+ return;
+ }
+ if (!gtk_tree_model_iter_parent(model, &parent, &iter))
+ {
+ return;
+ }
+ dir = build_path(&parent);
+ if (NULL == dir)
+ {
+ return;
+ }
+
+ gtk_tree_model_get(model, &iter, FILEVIEW_COLUMN_NAME, &name, -1);
+ if (NULL != name)
+ {
+ newname = dialogs_show_input(_("Rename"), GTK_WINDOW(geany->main_widgets->window),
+ _("New name:"), name);
+
+ if (NULL != newname)
+ {
+ oldpath = g_build_path(G_DIR_SEPARATOR_S, dir, name, NULL);
+ newpath = g_build_path(G_DIR_SEPARATOR_S, dir, newname, NULL);
+ if (rename_file_or_dir(oldpath, newpath))
+ {
+ prjorg_project_rescan();
+ prjorg_sidebar_update(TRUE);
+ project_write_config();
+ }
+ else
+ {
+ dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Cannot rename %s to %s"),
+ oldpath, newpath);
+ }
+ g_free(oldpath);
+ g_free(newpath);
+ g_free(newname);
+ }
+ g_free(name);
+ }
+ g_free(dir);
+}
+
+
+static void on_delete(G_GNUC_UNUSED GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer user_data)
+{
+ GtkTreeSelection *treesel;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *name;
+ gchar *path;
+
+ treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(s_file_view));
+ if (!gtk_tree_selection_get_selected(treesel, &model, &iter))
+ {
+ return;
+ }
+
+ gtk_tree_model_get(model, &iter, FILEVIEW_COLUMN_NAME, &name, -1);
+
+ if (dialogs_show_question(_("Do you really want to delete '%s'"), name))
+ {
+ path = build_path(&iter);
+ printf("deleting '%s'\n", path);
+
+ //TODO: recurse into directories
+
+ if (remove_file_or_dir(path))
+ {
+ close_file(path);
+ }
+ else
+ {
+ dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Cannot delete file %s"), path);
+ }
+
+ g_free(path);
+
+ prjorg_project_rescan();
+ prjorg_sidebar_update(TRUE);
+ project_write_config();
+ }
+
+ g_free(name);
+}
+
+
static void find_file_recursive(GtkTreeIter *iter, gboolean case_sensitive, gboolean full_path, GPatternSpec *pattern)
{
GtkTreeModel *model = GTK_TREE_MODEL(s_file_store);
@@ -900,6 +1105,10 @@ static void create_branch(gint level, GSList *leaf_list, GtkTreeIter *parent,
GtkTreeIter iter;
gchar **path_arr = elem->data;
GIcon *icon = NULL;
+
+ if (0 == g_strcmp0(PROJORG_SENTINEL_FILENAME, path_arr[level]))
+ continue;
+
gchar *content_type = g_content_type_guess(path_arr[level], NULL, 0, NULL);
if (content_type)
@@ -1468,6 +1677,50 @@ void prjorg_sidebar_init(void)
g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_remove_external_dir), NULL);
s_popup_menu.remove_external_dir = item;
+
+
+ item = gtk_separator_menu_item_new();
+ gtk_widget_show(item);
+ gtk_container_add(GTK_CONTAINER(s_popup_menu.widget), item);
+
+ image = gtk_image_new_from_stock(GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
+ gtk_widget_show(image);
+ item = gtk_image_menu_item_new_with_mnemonic(_("New File"));
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
+ gtk_widget_show(item);
+ gtk_container_add(GTK_CONTAINER(s_popup_menu.widget), item);
+ g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_create_file), NULL);
+ s_popup_menu.create_file = item;
+
+ image = gtk_image_new_from_stock(GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU);
+ gtk_widget_show(image);
+ item = gtk_image_menu_item_new_with_mnemonic(_("New Directory"));
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
+ gtk_widget_show(item);
+ gtk_container_add(GTK_CONTAINER(s_popup_menu.widget), item);
+ g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_create_dir), NULL);
+ s_popup_menu.create_dir = item;
+
+ image = gtk_image_new_from_stock(GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU);
+ gtk_widget_show(image);
+ item = gtk_image_menu_item_new_with_mnemonic(_("Rename"));
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
+ gtk_widget_show(item);
+ gtk_container_add(GTK_CONTAINER(s_popup_menu.widget), item);
+ g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_rename), NULL);
+ s_popup_menu.rename = item;
+
+ image = gtk_image_new_from_stock(GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
+ gtk_widget_show(image);
+ item = gtk_image_menu_item_new_with_mnemonic(_("Delete"));
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
+ gtk_widget_show(item);
+ gtk_container_add(GTK_CONTAINER(s_popup_menu.widget), item);
+ g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_delete), NULL);
+ s_popup_menu.delete = item;
+
+
+
item = gtk_separator_menu_item_new();
gtk_widget_show(item);
gtk_container_add(GTK_CONTAINER(s_popup_menu.widget), item);
Modified: projectorganizer/src/prjorg-utils.c
78 lines changed, 78 insertions(+), 0 deletions(-)
===================================================================
@@ -19,6 +19,11 @@
#include <string.h>
#include <glib.h>
+#include <glib/gstdio.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
#include <geanyplugin.h>
#include "prjorg-utils.h"
@@ -104,6 +109,79 @@ void open_file(gchar *utf8_name)
}
+void close_file(gchar *utf8_name)
+{
+ GeanyDocument *doc;
+
+ doc = document_find_by_filename(utf8_name);
+ if (doc)
+ {
+ document_set_text_changed(doc, FALSE);
+ document_close(doc);
+ }
+}
+
+
+gboolean create_file(gchar *utf8_name)
+{
+ int fd;
+ GError *err;
+
+ fd = g_open(utf8_name, O_CREAT|O_EXCL, 0660); // rw-rw----
+ if (-1 == fd) // not created?
+ {
+ return FALSE;
+ }
+ g_close(fd, &err);
+ return TRUE;
+}
+
+
+gboolean create_dir(char *utf8_name)
+{
+ return 0 == g_mkdir_with_parents(utf8_name, 0770); // rwxrwx---
+}
+
+
+gboolean remove_file_or_dir(char *utf8_name)
+{
+ return 0 == g_remove(utf8_name);
+}
+
+
+
+static gboolean document_rename(GeanyDocument *document, gchar *utf8_name)
+{
+ // IMHO: this is wrong. If save as fails Geany's state becomes inconsistent.
+ document_rename_file(document, utf8_name);
+ return document_save_file_as(document, utf8_name);
+}
+
+
+gboolean rename_file_or_dir(gchar *utf8_oldname, gchar *utf8_newname)
+{
+ GeanyDocument *doc;
+ gchar *oldname;
+ gchar *newname;
+ int res;
+
+ doc = document_find_by_filename(utf8_oldname);
+ if (doc)
+ {
+ return document_rename(doc, utf8_newname);
+ }
+ else
+ {
+ oldname = utils_get_locale_from_utf8(utf8_oldname);
+ newname = utils_get_locale_from_utf8(utf8_newname);
+ res = g_rename(oldname, newname);
+ g_free(oldname);
+ g_free(newname);
+ return 0 == res;
+ }
+}
+
+
gchar *get_selection(void)
{
GeanyDocument *doc = document_get_current();
Modified: projectorganizer/src/prjorg-utils.h
7 lines changed, 7 insertions(+), 0 deletions(-)
===================================================================
@@ -25,6 +25,13 @@ gboolean patterns_match(GSList *patterns, const gchar *str);
GSList *get_precompiled_patterns(gchar **patterns);
void open_file(gchar *utf8_name);
+void close_file(gchar *utf8_name);
+
+gboolean create_file(char *utf8_name);
+gboolean create_dir(char *utf8_name);
+gboolean remove_file_or_dir(char *utf8_name);
+gboolean rename_file_or_dir(gchar *utf8_oldname, gchar *utf8_newname);
+
gchar *get_selection(void);
gchar *get_project_base_path(void);
--------------
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