[nautilus-actions] Do not delete a tree which contains a readonly item
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Do not delete a tree which contains a readonly item
- Date: Fri, 5 Mar 2010 21:05:59 +0000 (UTC)
commit 755f8b1872a0e77da0ec23a341fd4c29582388f3
Author: Pierre Wieser <pwieser trychlos org>
Date: Fri Mar 5 22:03:51 2010 +0100
Do not delete a tree which contains a readonly item
ChangeLog | 11 ++++
TODO | 2 +
src/api/na-core-utils.h | 1 +
src/core/na-core-utils.c | 22 +++++++
src/nact/nact-main-menubar.c | 126 ++++++++++++++++++++++++++++++++++++++---
5 files changed, 152 insertions(+), 10 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index e3672ab..b32e0d0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2009-03-05 Pierre Wieser <pwieser trychlos org>
+
+ * src/api/na-core-utils.h:
+ * src/core/na-core-utils.c
+ (na_core_utils_slist_join_at_end): New function.
+
+ * src/api/na-iio-provider.h: Fix typo in comment.
+
+ * src/nact/nact-main-menubar.c (on_delete_activated):
+ Do not delete a tree if at least one item is not writable.
+
2009-03-04 Pierre Wieser <pwieser trychlos org>
* src/core/na-object-action.c (instance_init):
diff --git a/TODO b/TODO
index ca871cd..9194726 100644
--- a/TODO
+++ b/TODO
@@ -170,3 +170,5 @@
- dnd to inside of a menu, by dropping while on the menu itself
if menu is at path 3, we get a dest of 3:0 which means first child of parent at path 3
if menu is new (never has been written), dnd says that parent is not writable ????
+
+- implement delete_rec in nact_main_menubar
diff --git a/src/api/na-core-utils.h b/src/api/na-core-utils.h
index f5f141c..50557b5 100644
--- a/src/api/na-core-utils.h
+++ b/src/api/na-core-utils.h
@@ -58,6 +58,7 @@ GSList *na_core_utils_slist_duplicate( GSList *list );
void na_core_utils_slist_dump( GSList *list );
GSList *na_core_utils_slist_from_split( const gchar *string, const gchar *separator );
GSList *na_core_utils_slist_from_array( const gchar **str_array );
+gchar *na_core_utils_slist_join_at_end( GSList *list, const gchar *link );
GSList *na_core_utils_slist_remove_ascii( GSList *list, const gchar *text );
GSList *na_core_utils_slist_remove_utf8( GSList *list, const gchar *string );
gchar *na_core_utils_slist_to_text( GSList *list );
diff --git a/src/core/na-core-utils.c b/src/core/na-core-utils.c
index 700e386..e3ca145 100644
--- a/src/core/na-core-utils.c
+++ b/src/core/na-core-utils.c
@@ -287,6 +287,28 @@ na_core_utils_slist_from_array( const gchar **str_array )
}
/**
+ * na_core_utils_slist_join_at_end:
+ * @slist: the string list to join.
+ * @link: the string used to join each element.
+ *
+ * Returns: a newly allocated string which should be g_free() by the caller.
+ */
+gchar *
+na_core_utils_slist_join_at_end( GSList *slist, const gchar *link )
+{
+ GSList *is;
+ GString *str;
+
+ str = g_string_new( "" );
+
+ for( is = slist ; is ; is = is->next ){
+ g_string_append_printf( str, "%s%s", ( const gchar * ) is->data, link );
+ }
+
+ return( g_string_free( str, FALSE ));
+}
+
+/**
* na_core_utils_slist_remove_ascii:
* @list: the GSList to be updated.
* @text: string to remove.
diff --git a/src/nact/nact-main-menubar.c b/src/nact/nact-main-menubar.c
index 1b55a35..15d7871 100644
--- a/src/nact/nact-main-menubar.c
+++ b/src/nact/nact-main-menubar.c
@@ -35,6 +35,7 @@
#include <glib/gi18n.h>
#include <api/na-object-api.h>
+#include <api/na-core-utils.h>
#include <core/na-factory-object.h>
#include <core/na-iprefs.h>
@@ -105,6 +106,9 @@ static void on_paste_into_activated( GtkAction *action, NactMainWindow *wind
static GList *prepare_for_paste( NactMainWindow *window );
static void on_duplicate_activated( GtkAction *action, NactMainWindow *window );
static void on_delete_activated( GtkAction *action, NactMainWindow *window );
+static GList *get_deletables( NAUpdater *updater, GList *tree, GSList **not_deletable );
+static GSList *get_deletables_rec( NAUpdater *updater, GList *tree );
+static gchar *add_non_deletable_msg( const NAObjectItem *item, gint reason );
static void update_clipboard_counters( NactMainWindow *window );
static void on_reload_activated( GtkAction *action, NactMainWindow *window );
static void on_preferences_activated( GtkAction *action, NactMainWindow *window );
@@ -779,7 +783,10 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
duplicate_enabled = cut_enabled;
nact_main_menubar_enable_item( window, "DuplicateItem", duplicate_enabled );
- /* delete is same that cut */
+ /* delete is same that cut
+ * but items themselves must be writable (because physically deleted)
+ * this will be checked on delete activated
+ */
delete_enabled = cut_enabled;
nact_main_menubar_enable_item( window, "DeleteItem", delete_enabled );
@@ -1235,29 +1242,128 @@ on_duplicate_activated( GtkAction *gtk_action, NactMainWindow *window )
* - (main) add selected items to main list of deleted,
* moving newref from list_from_tree to main_list_of_deleted
* - (tree) select next row (if any, or previous if any, or none)
+ *
+ * note that we get from selection a list of trees, but we don't have
+ * yet ensured that each element of this tree is actually deletable
+ * each branch of this list must be recursively deletable in order
+ * this branch itself be deleted
*/
static void
on_delete_activated( GtkAction *gtk_action, NactMainWindow *window )
{
static const gchar *thisfn = "nact_main_menubar_on_delete_activated";
+ NactApplication *application;
+ NAUpdater *updater;
GList *items;
- GList *it;
+ GList *to_delete;
+ GSList *non_deletables;
g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
g_return_if_fail( GTK_IS_ACTION( gtk_action ));
g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+ application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
+ updater = nact_application_get_updater( application );
items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
- for( it = items ; it ; it = it->next ){
- g_debug( "%s: item=%p (%s)", thisfn, ( void * ) it->data, G_OBJECT_TYPE_NAME( it->data ));
+
+ non_deletables = NULL;
+ to_delete = get_deletables( updater, items, &non_deletables );
+
+ if( non_deletables ){
+ gchar *second = na_core_utils_slist_join_at_end( non_deletables, "\n" );
+ base_window_error_dlg(
+ BASE_WINDOW( window ),
+ GTK_MESSAGE_INFO,
+ _( "Not all items have been deleted as following ones are not modifiable:" ),
+ second );
+ g_free( second );
+ na_core_utils_slist_free( non_deletables );
}
- nact_main_window_move_to_deleted( window, items );
- nact_iactions_list_bis_delete( NACT_IACTIONS_LIST( window ), items );
- /* do not unref selected items as the list has been concatenated
- * to main_deleted
- */
- /*g_list_free( items );*/
+ if( to_delete ){
+ nact_main_window_move_to_deleted( window, to_delete );
+ nact_iactions_list_bis_delete( NACT_IACTIONS_LIST( window ), to_delete );
+ }
+
+ na_object_unref_selected_items( items );
+}
+
+static GList *
+get_deletables( NAUpdater *updater, GList *selected, GSList **non_deletables )
+{
+ GList *to_delete;
+ GList *it;
+ GList *subitems;
+ GSList *sub_deletables;
+ gint reason;
+
+ to_delete = NULL;
+ for( it = selected ; it ; it = it->next ){
+
+ if( !na_updater_is_item_writable( updater, NA_OBJECT_ITEM( it->data ), &reason )){
+ *non_deletables = g_slist_prepend(
+ *non_deletables, add_non_deletable_msg( NA_OBJECT_ITEM( it->data ), reason ));
+ continue;
+ }
+
+ if( NA_IS_OBJECT_MENU( it->data )){
+ subitems = na_object_get_items( it->data );
+ sub_deletables = get_deletables_rec( updater, subitems );
+
+ if( sub_deletables ){
+ *non_deletables = g_slist_concat( *non_deletables, sub_deletables );
+ continue;
+ }
+ }
+
+ to_delete = g_list_prepend( to_delete, it->data );
+ }
+
+ return( to_delete );
+}
+
+static GSList *
+get_deletables_rec( NAUpdater *updater, GList *tree )
+{
+ GSList *msgs;
+ GList *it;
+ GList *subitems;
+ gint reason;
+
+ msgs = NULL;
+ for( it = tree ; it ; it = it->next ){
+
+ if( !na_updater_is_item_writable( updater, NA_OBJECT_ITEM( it->data ), &reason )){
+ msgs = g_slist_prepend(
+ msgs, add_non_deletable_msg( NA_OBJECT_ITEM( it->data ), reason ));
+ continue;
+ }
+
+ if( NA_IS_OBJECT_MENU( it->data )){
+ subitems = na_object_get_items( it->data );
+ msgs = g_slist_concat( msgs, get_deletables_rec( updater, subitems ));
+ }
+ }
+
+ return( msgs );
+}
+
+static gchar *
+add_non_deletable_msg( const NAObjectItem *item, gint reason )
+{
+ gchar *msg;
+ gchar *label;
+ gchar *reason_str;
+
+ label = na_object_get_label( item );
+ reason_str = na_io_provider_get_readonly_tooltip( reason );
+
+ msg = g_strdup_printf( "%s: %s", label, reason_str );
+
+ g_free( reason_str );
+ g_free( label );
+
+ return( msg );
}
/*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]