Skip to content

Commit

Permalink
workbench: remove files or directories.
Browse files Browse the repository at this point in the history
The user can now remove a selected file or directory. Closes #711.
The user has to confirm the action and is warned that it cannot be undone.

In case a directory is removed, then first all files will be removed.
The workbench plugin only removes that files in a directory which are
displayed in the sidebar. That means files that are not displayed because
they do not match the file patterns will not be removed. After removing
all files, all sub-directories and finally the selected directory will
be removed. This will fail if a directory is not really empty.

If removing of a file or directory fails, then a message is output.
  • Loading branch information
lpaulsen93 committed Feb 28, 2018
1 parent 7460d36 commit 4f7eb00
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 19 deletions.
165 changes: 159 additions & 6 deletions workbench/src/popup_menu.c
Expand Up @@ -62,6 +62,7 @@ static struct
GtkWidget *remove_bookmark;
GtkWidget *new_file;
GtkWidget *new_directory;
GtkWidget *remove_file_or_dir;
} s_popup_menu;


Expand Down Expand Up @@ -98,6 +99,7 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
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);
gtk_widget_set_sensitive (s_popup_menu.remove_file_or_dir, FALSE);
break;
case POPUP_CONTEXT_DIRECTORY:
gtk_widget_set_sensitive (s_popup_menu.add_project, TRUE);
Expand All @@ -119,6 +121,7 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
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);
gtk_widget_set_sensitive (s_popup_menu.remove_file_or_dir, TRUE);
break;
case POPUP_CONTEXT_SUB_DIRECTORY:
gtk_widget_set_sensitive (s_popup_menu.add_project, TRUE);
Expand All @@ -140,6 +143,7 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
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);
gtk_widget_set_sensitive (s_popup_menu.remove_file_or_dir, TRUE);
break;
case POPUP_CONTEXT_FILE:
gtk_widget_set_sensitive (s_popup_menu.add_project, TRUE);
Expand All @@ -161,6 +165,7 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
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);
gtk_widget_set_sensitive (s_popup_menu.remove_file_or_dir, TRUE);
break;
case POPUP_CONTEXT_BACKGROUND:
gtk_widget_set_sensitive (s_popup_menu.add_project, TRUE);
Expand All @@ -182,6 +187,7 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
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);
gtk_widget_set_sensitive (s_popup_menu.remove_file_or_dir, FALSE);
break;
case POPUP_CONTEXT_WB_BOOKMARK:
gtk_widget_set_sensitive (s_popup_menu.add_project, TRUE);
Expand All @@ -203,6 +209,7 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
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);
gtk_widget_set_sensitive (s_popup_menu.remove_file_or_dir, FALSE);
break;
case POPUP_CONTEXT_PRJ_BOOKMARK:
gtk_widget_set_sensitive (s_popup_menu.add_project, TRUE);
Expand All @@ -224,6 +231,7 @@ void popup_menu_show(POPUP_CONTEXT context, GdkEventButton *event)
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);
gtk_widget_set_sensitive (s_popup_menu.remove_file_or_dir, FALSE);
break;
}
gtk_menu_popup(GTK_MENU(s_popup_menu.widget), NULL, NULL, NULL, NULL,
Expand Down Expand Up @@ -321,7 +329,7 @@ static void popup_menu_on_project_open_all (G_GNUC_UNUSED GtkMenuItem *menuitem,
{
GPtrArray *list;

list = sidebar_get_selected_project_filelist();
list = sidebar_get_selected_project_filelist(FALSE);
if (list != NULL)
{
open_all_files_in_list(list);
Expand All @@ -335,7 +343,7 @@ static void popup_menu_on_project_close_all (G_GNUC_UNUSED GtkMenuItem *menuitem
{
GPtrArray *list;

list = sidebar_get_selected_project_filelist();
list = sidebar_get_selected_project_filelist(FALSE);
if (list != NULL)
{
close_all_files_in_list(list);
Expand Down Expand Up @@ -426,7 +434,7 @@ static void popup_menu_on_directory_open_all (G_GNUC_UNUSED GtkMenuItem *menuite
{
GPtrArray *list;

list = sidebar_get_selected_directory_filelist();
list = sidebar_get_selected_directory_filelist(FALSE);
if (list != NULL)
{
open_all_files_in_list(list);
Expand All @@ -440,7 +448,7 @@ static void popup_menu_on_directory_close_all (G_GNUC_UNUSED GtkMenuItem *menuit
{
GPtrArray *list;

list = sidebar_get_selected_directory_filelist();
list = sidebar_get_selected_directory_filelist(FALSE);
if (list != NULL)
{
close_all_files_in_list(list);
Expand Down Expand Up @@ -502,7 +510,7 @@ static void popup_menu_on_subdir_open_all (G_GNUC_UNUSED GtkMenuItem *menuitem,
{
GPtrArray *list;

list = sidebar_get_selected_subdir_filelist();
list = sidebar_get_selected_subdir_filelist(FALSE);
if (list != NULL)
{
open_all_files_in_list(list);
Expand All @@ -516,7 +524,7 @@ static void popup_menu_on_subdir_close_all (G_GNUC_UNUSED GtkMenuItem *menuitem,
{
GPtrArray *list;

list = sidebar_get_selected_subdir_filelist();
list = sidebar_get_selected_subdir_filelist(FALSE);
if (list != NULL)
{
close_all_files_in_list(list);
Expand Down Expand Up @@ -604,6 +612,145 @@ static void popup_menu_on_new_directory(G_GNUC_UNUSED GtkMenuItem *menuitem, G_G
}


/* Handle popup menu item "Remove..." */
static void popup_menu_on_remove_file_or_dir(G_GNUC_UNUSED GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer user_data)
{
gboolean remove_it, dir, removed_any = FALSE;
gchar *path = NULL, *abs_path = NULL;
SIDEBAR_CONTEXT context;
GPtrArray *files;

/* Check if a file, a sub-dir or a directory is selected. */
if (sidebar_file_view_get_selected_context(&context))
{
if (context.file != NULL)
{
abs_path = g_strdup(context.file);
dir = FALSE;
}
else if (context.subdir != NULL)
{
path = context.subdir;
abs_path = g_strdup(path);
files = sidebar_get_selected_subdir_filelist(TRUE);
dir = TRUE;
}
else if (context.directory != NULL)
{
path = wb_project_dir_get_base_dir(context.directory);
abs_path = get_combined_path(wb_project_get_filename(context.project), path);
files = sidebar_get_selected_directory_filelist(TRUE);
dir = TRUE;
}
}

if (abs_path == NULL)
{
return;
}

/* Warn the user. */
if (dir == FALSE)
{
remove_it = dialogs_show_question(_("Do you really want to remove file \"%s\"?\n\nThis cannot be undone!"),
abs_path);
}
else
{
remove_it = dialogs_show_question(_("Do you really want to remove directory \"%s\" and all files in it?\n\nThis cannot be undone!"),
abs_path);
}

/* Really remove it? */
if (remove_it)
{
if (dir == FALSE)
{
if (g_remove(abs_path) != 0)
{
/* Remove file failed. Report error. */
ui_set_statusbar(TRUE, _("Could not remove file \"%s\"."),
abs_path);
}
else
{
removed_any = TRUE;
}
}
else
{
if (files != NULL)
{
guint index;
gchar *filename;

/* First remove all files in the directories. */
for ( index = 0 ; index < files->len ; index++ )
{
filename = files->pdata[index];
if (g_file_test(filename, G_FILE_TEST_IS_REGULAR))
{
if (g_remove(filename) != 0)
{
/* Remove file failed. Report error. */
ui_set_statusbar(TRUE, _("Could not remove file \"%s\"."),
filename);
}
else
{
removed_any = TRUE;
}
}
}

/* Now try to remove the directories.
This will only succeed if they are empty. */
for ( index = 0 ; index < files->len ; index++ )
{
filename = files->pdata[index];
if (g_file_test(filename, G_FILE_TEST_IS_DIR))
{
if (g_rmdir(filename) != 0)
{
/* Remove file failed. Report error. */
ui_set_statusbar(TRUE, _("Could not remove directory \"%s\"."),
filename);
}
else
{
removed_any = TRUE;
}
}
}

/* At last try to remove the parent dir. */
if (g_rmdir(abs_path) != 0)
{
/* Remove file failed. Report error. */
ui_set_statusbar(TRUE, _("Could not remove directory \"%s\"."),
abs_path);
}
else
{
removed_any = TRUE;
}

g_ptr_array_free(files, TRUE);
}
}

/* If anything was removed update the filelist and sidebar. */
if (removed_any)
{
wb_project_dir_rescan(context.project, context.directory);
sidebar_update(SIDEBAR_CONTEXT_DIRECTORY_RESCANNED, &context);
}
}

g_free(abs_path);
}


/** Setup/Initialize the popup menu.
*
**/
Expand Down Expand Up @@ -764,4 +911,10 @@ 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_new_directory), NULL);
s_popup_menu.new_directory = item;

item = gtk_menu_item_new_with_mnemonic(_("_Remove..."));
gtk_widget_show(item);
gtk_container_add(GTK_CONTAINER(s_popup_menu.widget), item);
g_signal_connect(item, "activate", G_CALLBACK(popup_menu_on_remove_file_or_dir), NULL);
s_popup_menu.remove_file_or_dir = item;
}
25 changes: 15 additions & 10 deletions workbench/src/sidebar.c
Expand Up @@ -1012,7 +1012,7 @@ gboolean sidebar_file_view_get_selected_context(SIDEBAR_CONTEXT *context)
}

/* Collect all filenames recursively starting from iter and add them to list */
static void sidebar_get_filelist_for_iter(GPtrArray *list, GtkTreeIter iter)
static void sidebar_get_filelist_for_iter(GPtrArray *list, GtkTreeIter iter, gboolean dirnames)
{
GtkTreeModel *model;
GtkTreeIter childs;
Expand All @@ -1032,9 +1032,14 @@ static void sidebar_get_filelist_for_iter(GPtrArray *list, GtkTreeIter iter)
break;
case DATA_ID_DIRECTORY:
case DATA_ID_SUB_DIRECTORY:
if (dirnames == TRUE)
{
gtk_tree_model_get(model, &iter, FILEVIEW_COLUMN_ASSIGNED_DATA_POINTER, &filename, -1);
g_ptr_array_add(list, g_strdup(filename));
}
if (gtk_tree_model_iter_children(model, &childs, &iter) == TRUE)
{
sidebar_get_filelist_for_iter(list, childs);
sidebar_get_filelist_for_iter(list, childs, dirnames);
}
break;
}
Expand All @@ -1046,7 +1051,7 @@ static void sidebar_get_filelist_for_iter(GPtrArray *list, GtkTreeIter iter)

/* Get the lkist of files belonging to the current selection for
id (id = project, directory, sub-directory) */
static GPtrArray *sidebar_get_selected_filelist (guint id)
static GPtrArray *sidebar_get_selected_filelist (guint id, gboolean dirnames)
{
GtkTreeModel *model;
GPtrArray *list;
Expand All @@ -1058,7 +1063,7 @@ static GPtrArray *sidebar_get_selected_filelist (guint id)
model = gtk_tree_view_get_model(GTK_TREE_VIEW(sidebar.file_view));
if (gtk_tree_model_iter_children(model, &childs, &iter) == TRUE)
{
sidebar_get_filelist_for_iter(list, childs);
sidebar_get_filelist_for_iter(list, childs, dirnames);
}
return list;
}
Expand All @@ -1072,9 +1077,9 @@ static GPtrArray *sidebar_get_selected_filelist (guint id)
* @return GPtrArray containing file names or NULL.
*
**/
GPtrArray *sidebar_get_selected_project_filelist (void)
GPtrArray *sidebar_get_selected_project_filelist (gboolean dirnames)
{
return sidebar_get_selected_filelist(DATA_ID_PROJECT);
return sidebar_get_selected_filelist(DATA_ID_PROJECT, dirnames);
}


Expand All @@ -1083,9 +1088,9 @@ GPtrArray *sidebar_get_selected_project_filelist (void)
* @return GPtrArray containing file names or NULL.
*
**/
GPtrArray *sidebar_get_selected_directory_filelist (void)
GPtrArray *sidebar_get_selected_directory_filelist (gboolean dirnames)
{
return sidebar_get_selected_filelist(DATA_ID_DIRECTORY);
return sidebar_get_selected_filelist(DATA_ID_DIRECTORY, dirnames);
}


Expand All @@ -1094,9 +1099,9 @@ GPtrArray *sidebar_get_selected_directory_filelist (void)
* @return GPtrArray containing file names or NULL.
*
**/
GPtrArray *sidebar_get_selected_subdir_filelist (void)
GPtrArray *sidebar_get_selected_subdir_filelist (gboolean dirnames)
{
return sidebar_get_selected_filelist(DATA_ID_SUB_DIRECTORY);
return sidebar_get_selected_filelist(DATA_ID_SUB_DIRECTORY, dirnames);
}

/** Setup the sidebar.
Expand Down
6 changes: 3 additions & 3 deletions workbench/src/sidebar.h
Expand Up @@ -72,8 +72,8 @@ void sidebar_toggle_selected_project_dir_expansion (void);
WB_PROJECT *sidebar_file_view_get_selected_project(GtkTreePath **path);
gboolean sidebar_file_view_get_selected_context(SIDEBAR_CONTEXT *context);

GPtrArray *sidebar_get_selected_project_filelist (void);
GPtrArray *sidebar_get_selected_directory_filelist (void);
GPtrArray *sidebar_get_selected_subdir_filelist (void);
GPtrArray *sidebar_get_selected_project_filelist (gboolean dirnames);
GPtrArray *sidebar_get_selected_directory_filelist (gboolean dirnames);
GPtrArray *sidebar_get_selected_subdir_filelist (gboolean dirnames);

#endif

0 comments on commit 4f7eb00

Please sign in to comment.