[nautilus-actions] Improve delete process in case of an item cannot be deleted
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Improve delete process in case of an item cannot be deleted
- Date: Tue, 14 Dec 2010 20:29:53 +0000 (UTC)
commit a1bcc7cff820bfbc3036946761d9a039e452f888
Author: Pierre Wieser <pwieser trychlos org>
Date: Tue Dec 14 21:28:40 2010 +0100
Improve delete process in case of an item cannot be deleted
ChangeLog | 13 +++++++
src/core/na-pivot.c | 5 +++
src/nact/nact-main-menubar-file.c | 50 +++++++++++++++++++++++++---
src/nact/nact-main-window.c | 65 ++++++++++++++++++++++++++++--------
src/nact/nact-main-window.h | 2 +-
src/nact/nact-window.c | 40 ++++++++++------------
src/nact/nact-window.h | 4 +-
7 files changed, 133 insertions(+), 46 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 8413c61..086ce68 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2010-12-14 Pierre Wieser <pwieser trychlos org>
+
+ * src/core/na-pivot.c (na_pivot_write_level_zero): Improve comment.
+
+ * src/nact/nact-main-menubar-file.c (nact_main_menubar_file_save_items):
+ Improve delete process, restoring items which cannot have been deleted.
+
+ * src/nact/nact-main-window.c:
+ * src/nact/nact-main-window.h (nact_main_window_remove_deleted):
+ * src/nact/nact-window.c:
+ * src/nact/nact-window.h (nact_window_delete_item):
+ Improve delete process, returning a status and an error message.
+
2010-12-13 Pierre Wieser <pwieser trychlos org>
* src/nact/nact-main-menubar-file.c (nact_main_menubar_file_save_items):
diff --git a/src/core/na-pivot.c b/src/core/na-pivot.c
index fb1cef2..49ebf60 100644
--- a/src/core/na-pivot.c
+++ b/src/core/na-pivot.c
@@ -693,6 +693,11 @@ time_val_diff( const GTimeVal *recent, const GTimeVal *old )
*
* Returns: %TRUE if successfully written (i.e. writable, not locked,
* and so on), %FALSE else.
+ *
+ * @messages #GSList is only filled up in case of an error has occured.
+ * If there is no error (na_pivot_write_level_zero() returns %TRUE), then
+ * the caller may safely assume that @messages is returned in the same
+ * state that it has been provided.
*/
gboolean
na_pivot_write_level_zero( const NAPivot *pivot, GList *items, GSList **messages )
diff --git a/src/nact/nact-main-menubar-file.c b/src/nact/nact-main-menubar-file.c
index 5acbe91..0baabdd 100644
--- a/src/nact/nact-main-menubar-file.c
+++ b/src/nact/nact-main-menubar-file.c
@@ -49,6 +49,7 @@ static guint st_event_autosave = 0;
static gchar *st_save_error = N_( "Save error" );
static gchar *st_save_warning = N_( "Some items may not have been saved" );
static gchar *st_level_zero_write = N_( "Unable to rewrite the level-zero items list" );
+static gchar *st_delete_error = N_( "Some items cannot have been deleted" );
static gboolean save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item, GSList **messages );
static gboolean autosave_callback( NactMainWindow *window );
@@ -233,7 +234,7 @@ nact_main_menubar_file_on_new_profile( GtkAction *gtk_action, NactMainWindow *wi
* Saving is not only saving modified items, but also saving hierarchy
* (and order if alpha order is not set).
*
- * This is the same function that #nact_main_menubar_file_save_items(), just with
+ * This is the same function that nact_main_menubar_file_save_items(), just with
* different arguments.
*/
void
@@ -254,8 +255,29 @@ nact_main_menubar_file_on_save( GtkAction *gtk_action, NactMainWindow *window )
* @window: the #NactMainWindow main window.
*
* Save items.
- * This is the same function that #nact_main_menubar_file_on_save(), just with
- * different arguments.
+ * This is the same function that nact_main_menubar_file_on_save(), just
+ * with different arguments.
+ *
+ * Synopsis:
+ * - rewrite the level-zero items list
+ * - delete the items which are marked to be deleted
+ * - rewrite (i.e. delete/write) updated items
+ *
+ * The difficulty here is that some sort of pseudo-transactionnal process
+ * must be setup:
+ *
+ * - if the level-zero items list cannot be updated, then an error message
+ * is displayed, and we abort the whole processus
+ *
+ * - if some items cannot be actually deleted, then an error message is
+ * displayed, and the whole processus is aborted;
+ * plus:
+ * a/ items which have not been deleted must be restored (maybe marked
+ * as deleted ?) -> so these items are modified
+ * b/ the level-zero list must be updated with these restored items
+ * and reset modified
+ *
+ * - idem if some items cannot be actually rewritten...
*/
void
nact_main_menubar_file_save_items( NactMainWindow *window )
@@ -288,7 +310,6 @@ nact_main_menubar_file_save_items( NactMainWindow *window )
messages = NULL;
if( !na_pivot_write_level_zero( NA_PIVOT( updater ), items, &messages )){
-
if( g_slist_length( messages )){
msg = na_core_utils_slist_join_at_end( messages, "\n" );
} else {
@@ -306,7 +327,17 @@ nact_main_menubar_file_save_items( NactMainWindow *window )
/* remove deleted items
* so that new actions with same id do not risk to be deleted later
*/
- nact_main_window_remove_deleted( window );
+ if( !nact_main_window_remove_deleted( window, &messages )){
+ if( g_slist_length( messages )){
+ msg = na_core_utils_slist_join_at_end( messages, "\n" );
+ } else {
+ msg = g_strdup( st_delete_error );
+ }
+ base_window_error_dlg( BASE_WINDOW( window ), GTK_MESSAGE_ERROR, st_save_error, msg );
+ g_free( msg );
+ na_core_utils_slist_free( messages );
+ return;
+ }
/* recursively save the modified items
* check is useless here if item was not modified, but not very costly;
@@ -384,6 +415,7 @@ save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item, GSLis
NAIOProvider *provider_before;
NAIOProvider *provider_after;
GList *subitems, *it;
+ gchar *msg;
g_return_val_if_fail( NACT_IS_MAIN_WINDOW( window ), FALSE );
g_return_val_if_fail( NA_IS_UPDATER( updater ), FALSE );
@@ -394,8 +426,9 @@ save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item, GSLis
if( na_object_is_modified( item )){
ret = FALSE;
+ msg = NULL;
- if( nact_window_save_item( NACT_WINDOW( window ), item )){
+ if( nact_window_save_item( NACT_WINDOW( window ), item, &msg )){
if( NA_IS_OBJECT_ACTION( item )){
na_object_reset_last_allocated( item );
@@ -407,6 +440,11 @@ save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item, GSLis
if( provider_after != provider_before ){
g_signal_emit_by_name( window, TAB_UPDATABLE_SIGNAL_PROVIDER_CHANGED, item );
}
+
+ } else {
+ /* TODO:
+ * add the error message to the GSList
+ */
}
}
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index d8e7d8d..2fbaae9 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -161,7 +161,7 @@ static void instance_set_property( GObject *object, guint property_id, const
static void instance_dispose( GObject *application );
static void instance_finalize( GObject *application );
-static void actually_delete_item( NactMainWindow *window, NAObject *item, NAUpdater *updater );
+static gboolean actually_delete_item( NactMainWindow *window, NAObject *item, NAUpdater *updater, GList **not_deleted, GSList **messages );
static gchar *base_get_toplevel_name( const BaseWindow *window );
static gchar *base_get_iprefs_window_id( const BaseWindow *window );
@@ -978,34 +978,57 @@ nact_main_window_reload( NactMainWindow *window )
/**
* nact_main_window_remove_deleted:
* @window: this #NactMainWindow instance.
+ * @messages: a pointer to a #GSList of error messages.
*
* Removes the deleted items from the underlying I/O storage subsystem.
+ *
+ * Each item of <structfield>NactMainWindow::private::deleted</structfield>
+ * #GList may actually itself be a tree (e.g. a #NAObjectMenu). The embedded
+ * items will be recursivelly removed, starting from the root.
+ *
+ * Returns: %TRUE if all candidate items have been successfully deleted,
+ * %FALSE else.
+ *
+ * @messages #GSList is only filled up in case of an error has occured.
+ * If there is no error (nact_main_window_remove_deleted() returns %TRUE),
+ * then the caller may safely assume that @messages is returned in the
+ * same state that it has been provided.
*/
-void
-nact_main_window_remove_deleted( NactMainWindow *window )
+gboolean
+nact_main_window_remove_deleted( NactMainWindow *window, GSList **messages )
{
+ gboolean delete_ok = TRUE;
NactApplication *application;
NAUpdater *updater;
GList *it;
NAObject *item;
+ GList *not_deleted;
- g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+ g_return_val_if_fail( NACT_IS_MAIN_WINDOW( window ), FALSE );
if( !window->private->dispose_has_run ){
application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
updater = nact_application_get_updater( application );
+ not_deleted = NULL;
for( it = window->private->deleted ; it ; it = it->next ){
item = NA_OBJECT( it->data );
- actually_delete_item( window, item, updater );
+ delete_ok = actually_delete_item( window, item, updater, ¬_deleted, messages );
}
na_object_unref_items( window->private->deleted );
window->private->deleted = NULL;
setup_dialog_title( window );
+
+ if( g_list_length( not_deleted )){
+ nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), not_deleted, NULL );
+ na_object_unref_items( not_deleted );
+ }
}
+
+ return( delete_ok );
}
/*
@@ -1013,31 +1036,43 @@ nact_main_window_remove_deleted( NactMainWindow *window )
* action has been marked as modified when the profile has been deleted,
* and thus updated in the storage subsystem as well as in the pivot
*/
-static void
-actually_delete_item( NactMainWindow *window, NAObject *item, NAUpdater *updater )
+static gboolean
+actually_delete_item( NactMainWindow *window, NAObject *item, NAUpdater *updater, GList **not_deleted, GSList **messages )
{
+ gboolean delete_ok = TRUE;
GList *items, *it;
NAObject *origin;
+ gchar *msg;
g_debug( "nact_main_window_actually_delete_item: item=%p (%s)",
( void * ) item, G_OBJECT_TYPE_NAME( item ));
if( NA_IS_OBJECT_ITEM( item )){
- nact_window_delete_item( NACT_WINDOW( window ), NA_OBJECT_ITEM( item ));
+ msg = NULL;
+ delete_ok = nact_window_delete_item( NACT_WINDOW( window ), NA_OBJECT_ITEM( item ), &msg );
- if( NA_IS_OBJECT_MENU( item )){
+ if( !delete_ok ){
+ *messages = g_slist_append( *messages, msg );
+ *not_deleted = g_list_append( *not_deleted, na_object_ref( item ));
+ g_free( msg );
+
+ } else if( NA_IS_OBJECT_MENU( item )){
items = na_object_get_items( item );
- for( it = items ; it ; it = it->next ){
- actually_delete_item( window, NA_OBJECT( it->data ), updater );
+ for( it = items ; delete_ok && it ; it = it->next ){
+ delete_ok &= actually_delete_item( window, NA_OBJECT( it->data ), updater, not_deleted, messages );
}
}
- origin = ( NAObject * ) na_object_get_origin( item );
- if( origin ){
- na_updater_remove_item( updater, origin );
- g_object_unref( origin );
+ if( delete_ok ){
+ origin = ( NAObject * ) na_object_get_origin( item );
+ if( origin ){
+ na_updater_remove_item( updater, origin );
+ g_object_unref( origin );
+ }
}
}
+
+ return( delete_ok );
}
static gchar *
diff --git a/src/nact/nact-main-window.h b/src/nact/nact-main-window.h
index ae3403d..a4a643f 100644
--- a/src/nact/nact-main-window.h
+++ b/src/nact/nact-main-window.h
@@ -82,7 +82,7 @@ NAObjectItem *nact_main_window_get_item ( const NactMainWindow *windo
gboolean nact_main_window_has_modified_items( const NactMainWindow *window );
void nact_main_window_move_to_deleted ( NactMainWindow *window, GList *items );
void nact_main_window_reload ( NactMainWindow *window );
-void nact_main_window_remove_deleted ( NactMainWindow *window );
+gboolean nact_main_window_remove_deleted ( NactMainWindow *window, GSList **messages );
G_END_DECLS
diff --git a/src/nact/nact-window.c b/src/nact/nact-window.c
index d40690f..78aff6c 100644
--- a/src/nact/nact-window.c
+++ b/src/nact/nact-window.c
@@ -308,6 +308,7 @@ nact_window_is_item_writable( const NactWindow *window, const NAObjectItem *item
* nact_window_save_item:
* @window: this #NactWindow instance.
* @item: the #NAObjectItem to be saved.
+ * @msg: a pointer to a location where wi may allocate a new error message.
*
* Saves a modified item (action or menu) to the I/O storage subsystem.
*
@@ -315,10 +316,14 @@ nact_window_is_item_writable( const NactWindow *window, const NAObjectItem *item
*
* Writing a menu only involves writing its NAObjectItem properties,
* along with the list and the order of its subitems, but not the
- * subitems themselves (because they may be unmodified)
+ * subitems themselves (because they may be unmodified).
+ *
+ * 2010-12-13 pwi v 3.0.3
+ * As we are displaying a summary of errors from the calling function,
+ * we no more care here of displaying each individual error message.
*/
gboolean
-nact_window_save_item( NactWindow *window, NAObjectItem *item )
+nact_window_save_item( NactWindow *window, NAObjectItem *item, gchar **msg )
{
static const gchar *thisfn = "nact_window_save_item";
gboolean save_ok = FALSE;
@@ -326,7 +331,6 @@ nact_window_save_item( NactWindow *window, NAObjectItem *item )
NAUpdater *updater;
GSList *messages = NULL;
guint ret;
- gchar *msgerr;
g_debug( "%s: window=%p, item=%p (%s)", thisfn,
( void * ) window, ( void * ) item, G_OBJECT_TYPE_NAME( item ));
@@ -341,23 +345,12 @@ nact_window_save_item( NactWindow *window, NAObjectItem *item )
ret = na_updater_write_item( updater, item, &messages );
g_debug( "nact_window_save_item: ret=%d", ret );
- msgerr = NULL;
-
if( messages ){
- msgerr = na_core_utils_slist_join_at_end( messages, "\n" );
+ *msg = na_core_utils_slist_join_at_end( messages, "\n" );
na_core_utils_slist_free( messages );
} else if( ret != NA_IIO_PROVIDER_CODE_OK ){
- msgerr = na_io_provider_get_return_code_label( ret );
- }
-
- if( msgerr ){
- base_window_error_dlg(
- BASE_WINDOW( window ),
- GTK_MESSAGE_WARNING,
- _( "An error has occured when trying to save the item" ),
- msgerr );
- g_free( msgerr );
+ *msg = na_io_provider_get_return_code_label( ret );
}
save_ok = ( ret == NA_IIO_PROVIDER_CODE_OK );
@@ -372,9 +365,13 @@ nact_window_save_item( NactWindow *window, NAObjectItem *item )
* @item: the item (action or menu) to delete.
*
* Deleted an item from the I/O storage subsystem.
+ *
+ * 2010-12-13 pwi v 3.0.3
+ * As we are displaying a summary of errors from the calling function,
+ * we no more care here of displaying each individual error message.
*/
gboolean
-nact_window_delete_item( NactWindow *window, const NAObjectItem *item )
+nact_window_delete_item( NactWindow *window, const NAObjectItem *item, gchar **msg )
{
static const gchar *thisfn = "nact_window_delete_item";
gboolean delete_ok = FALSE;
@@ -398,12 +395,11 @@ nact_window_delete_item( NactWindow *window, const NAObjectItem *item )
ret = na_updater_delete_item( updater, item, &messages );
if( messages ){
- base_window_error_dlg(
- BASE_WINDOW( window ),
- GTK_MESSAGE_WARNING,
- _( "An error has occured when trying to delete the item" ),
- ( const gchar * ) messages->data );
+ *msg = na_core_utils_slist_join_at_end( messages, "\n" );
na_core_utils_slist_free( messages );
+
+ } else if( ret != NA_IIO_PROVIDER_CODE_OK ){
+ *msg = na_io_provider_get_return_code_label( ret );
}
delete_ok = ( ret == NA_IIO_PROVIDER_CODE_OK );
diff --git a/src/nact/nact-window.h b/src/nact/nact-window.h
index 22504c8..565242b 100644
--- a/src/nact/nact-window.h
+++ b/src/nact/nact-window.h
@@ -75,8 +75,8 @@ gboolean nact_window_has_writable_providers( NactWindow *window );
gboolean nact_window_is_item_writable( const NactWindow *window, const NAObjectItem *item, guint *reason );
-gboolean nact_window_save_item ( NactWindow *window, NAObjectItem *item );
-gboolean nact_window_delete_item( NactWindow *window, const NAObjectItem *item );
+gboolean nact_window_save_item ( NactWindow *window, NAObjectItem *item, gchar **msgerr );
+gboolean nact_window_delete_item( NactWindow *window, const NAObjectItem *item, gchar **msgerr );
void nact_window_count_level_zero_items( GList *items, guint *actions, guint *profiles, guint *menus );
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]