changeset 914:9427c91951e8

basic infrastructure for early error and dangerous operations checking it needs more work
author nadvornik
date Tue, 22 Jul 2008 21:46:08 +0000
parents 2f9edd196dca
children 8cca92a61c6c
files src/filedata.c src/typedefs.h src/utilops.c
diffstat 3 files changed, 134 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/filedata.c	Tue Jul 22 18:27:12 2008 +0000
+++ b/src/filedata.c	Tue Jul 22 21:46:08 2008 +0000
@@ -1621,12 +1621,54 @@
 
 /*
  * check dest paths - dest image exists, etc.
- * returns FIXME
  * it should detect all possible problems with the planned operation
+ * FIXME: add more tests
  */
+
+gint file_data_check_ci_dest(FileData *fd)
+{
+	gint ret = CHANGE_OK;
+	
+	g_assert(fd->change);
+	
+	if (fd->change->dest &&
+	    strcmp(fd->change->dest, fd->path) != 0 &&
+	    isname(fd->change->dest))
+		{
+		ret |= CHANGE_DEST_EXISTS;
+		DEBUG_1("Change checked: destination exists: %s -> %s", fd->path, fd->change->dest);
+		}
+	
+	if (!access_file(fd->path, R_OK))
+		{
+		ret |= CHANGE_NO_PERM;
+		DEBUG_1("Change checked: no read permission: %s", fd->path);
+		}
+		
+	fd->change->error = ret;
+	if (ret == 0) DEBUG_1("Change checked: OK: %s", fd->path);
+
+	return ret;
+}
+
  
 gint file_data_sc_check_ci_dest(FileData *fd)
 {
+	GList *work;
+	int ret;
+
+	ret = file_data_check_ci_dest(fd);
+
+	work = fd->sidecar_files;
+	while (work)
+		{
+		FileData *sfd = work->data;
+
+		ret |= file_data_check_ci_dest(sfd);
+		work = work->next;
+		}
+
+	return ret;
 }
 
 
--- a/src/typedefs.h	Tue Jul 22 18:27:12 2008 +0000
+++ b/src/typedefs.h	Tue Jul 22 21:46:08 2008 +0000
@@ -149,6 +149,13 @@
 	NOTIFY_TYPE_CHANGE        /* generic change described by fd->change */
 } NotifyType;
 
+typedef enum {
+	CHANGE_OK          = 0,
+	CHANGE_DEST_EXISTS = 1 << 0,
+	CHANGE_ERROR_MASK  = (~0) << 1, /* the values below are fatal errors */
+	CHANGE_NO_PERM     = 1 << 1
+} ChangeError;
+
 
 #define MAX_SPLIT_IMAGES 4
 
@@ -427,6 +434,7 @@
 	FileDataChangeType type;
 	gchar *source;
 	gchar *dest;
+	gint error;
 };
 
 struct _FileData {
--- a/src/utilops.c	Tue Jul 22 18:27:12 2008 +0000
+++ b/src/utilops.c	Tue Jul 22 21:46:08 2008 +0000
@@ -800,6 +800,87 @@
 		}
 }
 
+
+static void file_util_check_resume_cb(GenericDialog *gd, gpointer data)
+{
+	UtilityData *ud = data;
+	ud->phase = UTILITY_PHASE_CHECKED;
+	file_util_dialog_run(ud);
+}
+
+static void file_util_check_abort_cb(GenericDialog *gd, gpointer data)
+{
+	UtilityData *ud = data;
+	ud->phase = UTILITY_PHASE_START;
+	file_util_dialog_run(ud);
+}
+
+void file_util_check_ci(UtilityData *ud)
+{
+	gint error = CHANGE_OK;
+	
+	if (ud->dir_fd)
+		{
+		error = file_data_sc_check_ci_dest(ud->dir_fd);
+		}
+	else
+		{
+		GList *work = ud->flist;
+		while (work)
+			{
+			FileData *fd;
+
+			fd = work->data;
+			work = work->next;
+			
+			error |= file_data_sc_check_ci_dest(fd);
+			}
+		}
+
+	if (!error)
+		{
+		ud->phase = UTILITY_PHASE_CHECKED;
+		file_util_dialog_run(ud);
+		return;
+		}
+
+	// FIXME: the dialogs needs better error messages with a list of files and error descriptions
+	if (!(error & CHANGE_ERROR_MASK))
+		{
+		/* just a warning */
+		GenericDialog *d;
+
+		d = file_util_gen_dlg("This operation can be dangerous", GQ_WMCLASS, "dlg_confirm",
+					ud->parent, TRUE,
+					file_util_check_abort_cb, ud);
+
+		generic_dialog_add_message(d, GTK_STOCK_DIALOG_WARNING, NULL, "Really continue?");
+
+		generic_dialog_add_button(d, GTK_STOCK_GO_FORWARD, _("Co_ntinue"),
+					  file_util_check_resume_cb, TRUE);
+		gtk_widget_show(d->dialog);
+		return;
+		}
+	else
+		{
+		/* fatal error */
+		GenericDialog *d;
+
+		d = file_util_gen_dlg("This operation can't continue", GQ_WMCLASS, "dlg_confirm",
+					ud->parent, TRUE,
+					file_util_check_abort_cb, ud);
+		generic_dialog_add_message(d, GTK_STOCK_DIALOG_WARNING, NULL, "This operation can't continue");
+
+		gtk_widget_show(d->dialog);
+		return;
+		}
+
+}
+
+
+
+
+
 static void file_util_cancel_cb(GenericDialog *gd, gpointer data)
 {
 	UtilityData *ud = data;
@@ -1360,8 +1441,8 @@
 			ud->phase = UTILITY_PHASE_ENTERING;
 			break;
 		case UTILITY_PHASE_ENTERING:
-			/* FIXME use file_data_sc_check_ci_dest to detect problems and eventually go back to PHASE_START 
-			or to PHASE_CANCEL */
+			file_util_check_ci(ud);
+			break;
 		
 			ud->phase = UTILITY_PHASE_CHECKED;
 		case UTILITY_PHASE_CHECKED: