From 782c82871bdea8d6091e9335823240af8e0f04d7 Mon Sep 17 00:00:00 2001
From: tkellner <tkellner@174cde9d-5d70-4d2a-aa98-46368bc2aaf7>
Date: Wed, 10 Apr 2013 19:10:00 +0000
Subject: + ignore option for error dialog + resumeable exception for settings
 validation

git-svn-id: https://joinup.ec.europa.eu/svn/pdf-over/trunk@168 174cde9d-5d70-4d2a-aa98-46368bc2aaf7
---
 .../main/java/at/asit/pdfover/gui/Constants.java   |   5 +
 .../composites/AdvancedConfigurationComposite.java |  42 +++--
 .../gui/composites/BaseConfigurationComposite.java |  13 +-
 .../gui/composites/ConfigurationComposite.java     | 171 ++++++++++++++-------
 .../gui/composites/DataSourceSelectComposite.java  |   2 +-
 .../composites/SimpleConfigurationComposite.java   |  26 +++-
 .../at/asit/pdfover/gui/controls/ErrorDialog.java  |  52 +++++--
 .../exceptions/OutputfolderDontExistException.java |  39 +++++
 .../OutputfolderNotADirectoryException.java        |  42 +++++
 .../gui/exceptions/ResumeableException.java        |  58 +++++++
 .../pdfover/gui/workflow/StateMachineImpl.java     |   3 +-
 .../pdfover/gui/workflow/states/LocalBKUState.java |   6 +-
 .../gui/workflow/states/MobileBKUState.java        |   3 +-
 .../pdfover/gui/workflow/states/OutputState.java   |   3 +-
 .../workflow/states/PrepareConfigurationState.java |   3 +-
 .../gui/workflow/states/PrepareSigningState.java   |   5 +-
 .../pdfover/gui/workflow/states/SigningState.java  |   6 +-
 .../at/asit/pdfover/gui/messages.properties        |   6 +
 18 files changed, 381 insertions(+), 104 deletions(-)
 create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/exceptions/OutputfolderDontExistException.java
 create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/exceptions/OutputfolderNotADirectoryException.java
 create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/exceptions/ResumeableException.java

(limited to 'pdf-over-gui/src')

diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/Constants.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/Constants.java
index 9a0a659b..23aee948 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/Constants.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/Constants.java
@@ -50,6 +50,11 @@ public class Constants {
 	/** Main bar inactive text color */
 	public static final Color MAINBAR_INACTIVE_TEXTCOLOR = new Color(display, 0x40, 0x40, 0x40);
 
+	/**
+	 * Drag and Drop background color
+	 */
+	public static final Color DROP_BACK = new Color(display, 0xFF, 0xFF, 0xFF);
+	
 	/** Drop border color */
 	public static final Color DROP_BORDER_COLOR = MAINBAR_ACTIVE_BACK_LIGHT;
 
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/AdvancedConfigurationComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/AdvancedConfigurationComposite.java
index 72e047c4..05b16824 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/AdvancedConfigurationComposite.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/AdvancedConfigurationComposite.java
@@ -43,6 +43,9 @@ import org.slf4j.LoggerFactory;
 import at.asit.pdfover.gui.Constants;
 import at.asit.pdfover.gui.Messages;
 import at.asit.pdfover.gui.controls.ErrorDialog;
+import at.asit.pdfover.gui.controls.ErrorDialog.ERROR_BUTTONS;
+import at.asit.pdfover.gui.exceptions.OutputfolderDontExistException;
+import at.asit.pdfover.gui.exceptions.OutputfolderNotADirectoryException;
 import at.asit.pdfover.gui.workflow.ConfigurationContainer;
 import at.asit.pdfover.gui.workflow.states.State;
 import at.asit.pdfover.signator.BKUs;
@@ -106,10 +109,14 @@ public class AdvancedConfigurationComposite extends BaseConfigurationComposite {
 
 		FontData[] fD_btnAutomatischePositionierung = this.btnAutomatischePositionierung
 				.getFont().getFontData();
-		fD_btnAutomatischePositionierung[0].setHeight(Constants.TEXT_SIZE_BUTTON);
+		fD_btnAutomatischePositionierung[0]
+				.setHeight(Constants.TEXT_SIZE_BUTTON);
 		this.btnAutomatischePositionierung.setFont(new Font(Display
 				.getCurrent(), fD_btnAutomatischePositionierung[0]));
 
+		this.btnAutomatischePositionierung.setToolTipText(Messages
+				.getString("advanced_config.AutoPosition_ToolTip")); //$NON-NLS-1$
+
 		this.btnAutomatischePositionierung
 				.addSelectionListener(new SelectionAdapter() {
 
@@ -225,6 +232,9 @@ public class AdvancedConfigurationComposite extends BaseConfigurationComposite {
 
 		this.cmbBKUAuswahl.setLayoutData(fd_cmbBKUAuswahl);
 
+		this.cmbBKUAuswahl.setToolTipText(Messages
+				.getString("advanced_config.BKUSelection_ToolTip")); //$NON-NLS-1$
+
 		this.cmbBKUAuswahl.addSelectionListener(new SelectionAdapter() {
 
 			@Override
@@ -294,6 +304,9 @@ public class AdvancedConfigurationComposite extends BaseConfigurationComposite {
 			}
 		});
 
+		this.txtOutputFolder.setToolTipText(Messages
+				.getString("advanced_config.OutputFolder_ToolTip")); //$NON-NLS-1$
+
 		Button btnBrowse = new Button(grpSpeicherort, SWT.NONE);
 		fd_text.right = new FormAttachment(btnBrowse, -5);
 
@@ -383,7 +396,8 @@ public class AdvancedConfigurationComposite extends BaseConfigurationComposite {
 			this.performBKUSelectionChanged(bkuvalue);
 		} catch (Exception ex) {
 			log.error("Failed to parse BKU value: " + selected, ex); //$NON-NLS-1$
-			ErrorDialog dialog = new ErrorDialog(getShell(), Messages.getString("error.InvalidBKU"), false); //$NON-NLS-1$
+			ErrorDialog dialog = new ErrorDialog(getShell(),
+					Messages.getString("error.InvalidBKU"), ERROR_BUTTONS.OK); //$NON-NLS-1$
 			dialog.open();
 		}
 	}
@@ -451,19 +465,23 @@ public class AdvancedConfigurationComposite extends BaseConfigurationComposite {
 	 * ()
 	 */
 	@Override
-	public void validateSettings() throws Exception {
+	public void validateSettings(int resumeIndex) throws Exception {
 		
 		String foldername = this.configurationContainer.getOutputFolder();
 		
-		if (foldername != null && !foldername.equals("")) { //$NON-NLS-1$
-			File outputFolder = new File(foldername);
-			if (!outputFolder.exists()) {
-				throw new Exception(String.format(Messages.getString("exception.PathNotExist"), outputFolder.getAbsolutePath())); //$NON-NLS-1$
-			}
-
-			if (!outputFolder.isDirectory()) {
-				throw new Exception(String.format(Messages.getString("exception.PathNotDirectory"), outputFolder.getAbsolutePath())); //$NON-NLS-1$
-			}
+		switch (resumeIndex) {
+			case 0:
+				if (foldername != null && !foldername.isEmpty()) {
+					File outputFolder = new File(foldername);
+					if (!outputFolder.exists()) {
+						throw new OutputfolderDontExistException(outputFolder, 1); 
+					}
+					if (!outputFolder.isDirectory()) {
+						throw new OutputfolderNotADirectoryException(outputFolder);
+					}
+				}
+				// Fall through
+			case 1:
 		}
 	}
 }
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/BaseConfigurationComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/BaseConfigurationComposite.java
index db3304d5..00e4ebb0 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/BaseConfigurationComposite.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/BaseConfigurationComposite.java
@@ -77,8 +77,15 @@ public abstract class BaseConfigurationComposite extends StateComposite {
 	
 	/**
 	 * Called before exit.
-	 * The method validates every setting in the configuration before exit  
-	 * @throws Exception 
+	 * The method validates every setting in the configuration before exit
+	 * 
+	 * There might be settings when the user can decide to ignore a validation exception
+	 * (for example the Outputfolder validation)
+	 * In this case, the validator throws a ResumableException, which includes the
+	 * validator index to resume from (should the user choose to ignore the error)
+	 * 
+	 * @param resumeFrom Resume from this validator index (initially 0)
+	 * @throws Exception
 	 */
-	public abstract void validateSettings() throws Exception;
+	public abstract void validateSettings(int resumeFrom) throws Exception;
 }
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/ConfigurationComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/ConfigurationComposite.java
index 2b62d651..c170e5df 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/ConfigurationComposite.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/ConfigurationComposite.java
@@ -29,9 +29,11 @@ import org.slf4j.LoggerFactory;
 import at.asit.pdfover.gui.Constants;
 import at.asit.pdfover.gui.Messages;
 import at.asit.pdfover.gui.controls.ErrorDialog;
+import at.asit.pdfover.gui.controls.ErrorDialog.ERROR_BUTTONS;
 import at.asit.pdfover.gui.exceptions.InvalidEmblemFile;
 import at.asit.pdfover.gui.exceptions.InvalidNumberException;
 import at.asit.pdfover.gui.exceptions.InvalidPortException;
+import at.asit.pdfover.gui.exceptions.ResumeableException;
 import at.asit.pdfover.gui.workflow.ConfigManipulator;
 import at.asit.pdfover.gui.workflow.ConfigProvider;
 import at.asit.pdfover.gui.workflow.ConfigurationContainer;
@@ -56,12 +58,12 @@ import org.eclipse.swt.layout.FormAttachment;
  * Composite for hosting configuration composites
  */
 public class ConfigurationComposite extends StateComposite {
-	
+
 	/**
 	 * The PDF Signer used to produce signature block preview
 	 */
 	protected PDFSigner signer;
-	
+
 	/**
 	 * @return the signer
 	 */
@@ -70,7 +72,8 @@ public class ConfigurationComposite extends StateComposite {
 	}
 
 	/**
-	 * @param signer the signer to set
+	 * @param signer
+	 *            the signer to set
 	 */
 	public void setSigner(PDFSigner signer) {
 		this.signer = signer;
@@ -160,8 +163,9 @@ public class ConfigurationComposite extends StateComposite {
 								.useAutoPositioning());
 			}
 
-			this.configurationContainer.setPlaceholderTransparency(
-					this.configProvider.getPlaceholderTransparency());
+			this.configurationContainer
+					.setPlaceholderTransparency(this.configProvider
+							.getPlaceholderTransparency());
 
 			this.configurationContainer.setBKUSelection(this.configProvider
 					.getDefaultBKU());
@@ -225,16 +229,17 @@ public class ConfigurationComposite extends StateComposite {
 		TabItem simpleTabItem = new TabItem(tabFolder, SWT.NONE);
 		simpleTabItem.setText(Messages.getString("config.Simple")); //$NON-NLS-1$
 
-		ScrolledComposite simpleCompositeScr = new ScrolledComposite(
-				tabFolder, SWT.H_SCROLL | SWT.V_SCROLL);
+		ScrolledComposite simpleCompositeScr = new ScrolledComposite(tabFolder,
+				SWT.H_SCROLL | SWT.V_SCROLL);
 		simpleTabItem.setControl(simpleCompositeScr);
 		this.simpleConfigComposite = new SimpleConfigurationComposite(
-				simpleCompositeScr, SWT.NONE, state, this.configurationContainer);
+				simpleCompositeScr, SWT.NONE, state,
+				this.configurationContainer);
 		simpleCompositeScr.setContent(this.simpleConfigComposite);
 		simpleCompositeScr.setExpandHorizontal(true);
 		simpleCompositeScr.setExpandVertical(true);
-		simpleCompositeScr.setMinSize(
-				this.simpleConfigComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+		simpleCompositeScr.setMinSize(this.simpleConfigComposite.computeSize(
+				SWT.DEFAULT, SWT.DEFAULT));
 
 		TabItem advancedTabItem = new TabItem(tabFolder, SWT.NONE);
 		advancedTabItem.setText(Messages.getString("config.Advanced")); //$NON-NLS-1$
@@ -243,12 +248,13 @@ public class ConfigurationComposite extends StateComposite {
 				tabFolder, SWT.H_SCROLL | SWT.V_SCROLL);
 		advancedTabItem.setControl(advancedCompositeScr);
 		this.advancedConfigComposite = new AdvancedConfigurationComposite(
-				advancedCompositeScr, SWT.NONE, state, this.configurationContainer);
+				advancedCompositeScr, SWT.NONE, state,
+				this.configurationContainer);
 		advancedCompositeScr.setContent(this.advancedConfigComposite);
 		advancedCompositeScr.setExpandHorizontal(true);
 		advancedCompositeScr.setExpandVertical(true);
-		advancedCompositeScr.setMinSize(
-				this.advancedConfigComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+		advancedCompositeScr.setMinSize(this.advancedConfigComposite
+				.computeSize(SWT.DEFAULT, SWT.DEFAULT));
 
 		tabFolder.setSelection(simpleTabItem);
 
@@ -270,8 +276,9 @@ public class ConfigurationComposite extends StateComposite {
 
 		FontData[] fD_btnSpeichern = btnSpeichern.getFont().getFontData();
 		fD_btnSpeichern[0].setHeight(Constants.TEXT_SIZE_BUTTON);
-		btnSpeichern.setFont(new Font(Display.getCurrent(), fD_btnSpeichern[0]));
-		
+		btnSpeichern
+				.setFont(new Font(Display.getCurrent(), fD_btnSpeichern[0]));
+
 		Button btnAbbrechen = new Button(this, SWT.NONE);
 		FormData fd_btnAbrechen = new FormData();
 		fd_btnAbrechen.right = new FormAttachment(btnSpeichern, -10);
@@ -288,7 +295,8 @@ public class ConfigurationComposite extends StateComposite {
 
 		FontData[] fD_btnAbbrechen = btnAbbrechen.getFont().getFontData();
 		fD_btnAbbrechen[0].setHeight(Constants.TEXT_SIZE_BUTTON);
-		btnAbbrechen.setFont(new Font(Display.getCurrent(), fD_btnAbbrechen[0]));
+		btnAbbrechen
+				.setFont(new Font(Display.getCurrent(), fD_btnAbbrechen[0]));
 
 		FormData fd_composite = new FormData();
 		fd_composite.top = new FormAttachment(0, 5);
@@ -300,53 +308,103 @@ public class ConfigurationComposite extends StateComposite {
 		this.compositeStack.topControl = tabFolder;
 
 		this.doLayout();
-}
+	}
 
 	boolean storeConfiguration() {
-
+		boolean status = false;
+		boolean redo = false;
+		int resumeIndex = 0;
 		try {
-			this.simpleConfigComposite.validateSettings();
-			this.advancedConfigComposite.validateSettings();
+			do {
+				try {
+					this.simpleConfigComposite.validateSettings(resumeIndex);
+
+					redo = false;
+					status = true;
+				} catch (ResumeableException e) {
+					log.error("Settings validation failed!", e); //$NON-NLS-1$
+					ErrorDialog dialog = new ErrorDialog(getShell(),
+							e.getMessage(), ERROR_BUTTONS.ABORT_RETRY_IGNORE);
+					int rc = dialog.open();
+
+					redo = (rc == SWT.RETRY);
+					if (rc == SWT.IGNORE)
+					{
+						resumeIndex = e.getResumeIndex();
+						redo = true;
+					}
+				}
+			} while (redo);
 
-			// Write current Configuration
-			this.configManipulator.setDefaultBKU(this.configurationContainer
-					.getBKUSelection());
-			this.configManipulator
-					.setDefaultMobileNumber(this.configurationContainer
-							.getNumber());
-			if (this.configurationContainer.getAutomaticPosition()) {
-				this.configManipulator
-						.setDefaultSignaturePosition(new SignaturePosition());
-			} else {
-				this.configManipulator.setDefaultSignaturePosition(null);
+			if (!status) {
+				return false;
 			}
 
-			this.configManipulator.setPlaceholderTransparency(
-					this.configurationContainer.getPlaceholderTransparency());
-
-			this.configManipulator
-					.setDefaultOutputFolder(this.configurationContainer
-							.getOutputFolder());
-
-			this.configManipulator.setProxyHost(this.configurationContainer
-					.getProxyHost());
-			this.configManipulator.setProxyPort(this.configurationContainer
-					.getProxyPort());
-			this.configManipulator.setDefaultEmblem(this.configurationContainer
-					.getEmblem());
-
+			status = false;
+			redo = false;
+			resumeIndex = 0;
+
+			do {
+				try {
+					this.advancedConfigComposite.validateSettings(resumeIndex);
+
+					redo = false;
+					status = true;
+				} catch (ResumeableException e) {
+					log.error("Settings validation failed!", e); //$NON-NLS-1$
+					ErrorDialog dialog = new ErrorDialog(getShell(),
+							e.getMessage(), ERROR_BUTTONS.ABORT_RETRY_IGNORE);
+					int rc = dialog.open();
+
+					redo = (rc == SWT.RETRY);
+					if (rc == SWT.IGNORE)
+					{
+						resumeIndex = e.getResumeIndex();
+						redo = true;
+					}
+				}
+			} while (redo);
 		} catch (Exception e) {
 			log.error("Settings validation failed!", e); //$NON-NLS-1$
-			ErrorDialog dialog = new ErrorDialog(
-					getShell(),
-					e.getMessage(),
-					false);
+			ErrorDialog dialog = new ErrorDialog(getShell(), e.getMessage(),
+					ERROR_BUTTONS.OK);
 			dialog.open();
 			return false;
 		}
 
-		boolean status = false;
-		boolean redo = false;
+		if (!status) {
+			return false;
+		}
+
+		// Write current Configuration
+		this.configManipulator.setDefaultBKU(this.configurationContainer
+				.getBKUSelection());
+		this.configManipulator
+				.setDefaultMobileNumber(this.configurationContainer.getNumber());
+		if (this.configurationContainer.getAutomaticPosition()) {
+			this.configManipulator
+					.setDefaultSignaturePosition(new SignaturePosition());
+		} else {
+			this.configManipulator.setDefaultSignaturePosition(null);
+		}
+
+		this.configManipulator
+				.setPlaceholderTransparency(this.configurationContainer
+						.getPlaceholderTransparency());
+
+		this.configManipulator
+				.setDefaultOutputFolder(this.configurationContainer
+						.getOutputFolder());
+
+		this.configManipulator.setProxyHost(this.configurationContainer
+				.getProxyHost());
+		this.configManipulator.setProxyPort(this.configurationContainer
+				.getProxyPort());
+		this.configManipulator.setDefaultEmblem(this.configurationContainer
+				.getEmblem());
+
+		status = false;
+		redo = false;
 		do {
 			// Save current config to file
 			try {
@@ -355,11 +413,12 @@ public class ConfigurationComposite extends StateComposite {
 				status = true;
 			} catch (IOException e) {
 				log.error("Failed to save configuration to file!", e); //$NON-NLS-1$
-				ErrorDialog dialog = new ErrorDialog(getShell(), 
-						Messages.getString("error.FailedToSaveSettings"), true); //$NON-NLS-1$
-				redo = dialog.open();
-				
-				//return false;
+				ErrorDialog dialog = new ErrorDialog(
+						getShell(),
+						Messages.getString("error.FailedToSaveSettings"), ERROR_BUTTONS.RETRY_CANCEL); //$NON-NLS-1$
+				redo = (dialog.open() == SWT.RETRY);
+
+				// return false;
 			}
 		} while (redo);
 		return status;
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/DataSourceSelectComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/DataSourceSelectComposite.java
index 8c3c1e25..17252457 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/DataSourceSelectComposite.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/DataSourceSelectComposite.java
@@ -151,7 +151,7 @@ public class DataSourceSelectComposite extends StateComposite {
 		super(parent, style, state);
 
 		this.activeBackground = Constants.MAINBAR_ACTIVE_BACK_LIGHT;
-		this.inactiveBackground = Constants.MAINBAR_INACTIVE_BACK;
+		this.inactiveBackground = this.getBackground();//Constants.MAINBAR_INACTIVE_BACK;
 		this.inactiveBorder = Constants.MAINBAR_ACTIVE_BACK_LIGHT;
 		this.activeBorder = Constants.MAINBAR_ACTIVE_BACK_DARK;
 		this.backgroundColor = this.inactiveBackground;
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SimpleConfigurationComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SimpleConfigurationComposite.java
index f5fc34ce..6e707156 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SimpleConfigurationComposite.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SimpleConfigurationComposite.java
@@ -60,6 +60,7 @@ import at.asit.pdfover.gui.Constants;
 import at.asit.pdfover.gui.Messages;
 import at.asit.pdfover.gui.controls.ErrorDialog;
 import at.asit.pdfover.gui.controls.ErrorMarker;
+import at.asit.pdfover.gui.controls.ErrorDialog.ERROR_BUTTONS;
 import at.asit.pdfover.gui.exceptions.InvalidNumberException;
 import at.asit.pdfover.gui.exceptions.InvalidPortException;
 import at.asit.pdfover.gui.utils.ImageConverter;
@@ -125,6 +126,7 @@ public class SimpleConfigurationComposite extends BaseConfigurationComposite {
 			this.fd_txtMobileNumber.bottom = new FormAttachment(100);
 			this.fd_txtMobileNumber.right = new FormAttachment(100, -42);
 			this.txtMobileNumber.setLayoutData(this.fd_txtMobileNumber);
+			this.txtMobileNumber.setToolTipText(Messages.getString("simple_config.ExampleNumber_ToolTip")); //$NON-NLS-1$
 	
 			this.txtMobileNumberErrorMarker = new ErrorMarker(composite_2,
 					SWT.NATIVE, null, "", this.txtMobileNumber); //$NON-NLS-1$
@@ -407,7 +409,7 @@ public class SimpleConfigurationComposite extends BaseConfigurationComposite {
 			this.proxyHostErrorMarker.setLayoutData(fd_marker);
 			this.proxyHostErrorMarker.setVisible(false);
 			this.txtProxyHost.setLayoutData(fd_txtProxyHost);
-	
+			this.txtProxyHost.setToolTipText(Messages.getString("simple_config.ProxyHost_ToolTip")); //$NON-NLS-1$
 			this.txtProxyHost.setMessage(Messages
 					.getString("simple_config.ProxyHostTemplate")); //$NON-NLS-1$
 	
@@ -450,7 +452,8 @@ public class SimpleConfigurationComposite extends BaseConfigurationComposite {
 			this.fd_txtProxyPort.right = new FormAttachment(100, -42);
 			this.fd_txtProxyPort.bottom = new FormAttachment(100);
 			this.txtProxyPort.setLayoutData(this.fd_txtProxyPort);
-	
+			this.txtProxyPort.setToolTipText(Messages.getString("simple_config.ProxyPort_ToolTip")); //$NON-NLS-1$
+			
 			FontData[] fD_txtProxyPort = this.txtProxyPort.getFont().getFontData();
 			fD_txtProxyPort[0].setHeight(Constants.TEXT_SIZE_NORMAL);
 			this.txtProxyPort.setFont(new Font(Display.getCurrent(),
@@ -711,7 +714,7 @@ public class SimpleConfigurationComposite extends BaseConfigurationComposite {
 		} catch (Exception ex) {
 			log.error("processEmblemChanged: ", ex); //$NON-NLS-1$
 			ErrorDialog dialog = new ErrorDialog(getShell(),
-					Messages.getString("error.FailedToLoadEmblem"), false); //$NON-NLS-1$
+					Messages.getString("error.FailedToLoadEmblem"), ERROR_BUTTONS.OK); //$NON-NLS-1$
 			dialog.open();
 		}
 	}
@@ -865,7 +868,7 @@ public class SimpleConfigurationComposite extends BaseConfigurationComposite {
 				log.error("Failed to load emblem: ", e1); //$NON-NLS-1$
 				ErrorDialog dialog = new ErrorDialog(
 						getShell(),
-						Messages.getString("error.FailedToLoadEmblem"), false); //$NON-NLS-1$
+						Messages.getString("error.FailedToLoadEmblem"), ERROR_BUTTONS.OK); //$NON-NLS-1$
 				dialog.open();
 			}
 		}
@@ -892,10 +895,17 @@ public class SimpleConfigurationComposite extends BaseConfigurationComposite {
 	 * ()
 	 */
 	@Override
-	public void validateSettings() throws Exception {
-		this.plainMobileNumberSetter();
+	public void validateSettings(int resumeFrom) throws Exception {
+		switch (resumeFrom) {
+			case 0:
+				this.plainMobileNumberSetter();
+				// Fall through
+			case 1:
+				this.plainProxyHostSetter();
+				// Fall through
+			case 2:
+				this.plainProxyPortSetter();
+		}
 		//this.plainEmblemSetter(this.emblemFile);
-		this.plainProxyHostSetter();
-		this.plainProxyPortSetter();
 	}
 }
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/controls/ErrorDialog.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/controls/ErrorDialog.java
index 88392d98..7cefb857 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/controls/ErrorDialog.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/controls/ErrorDialog.java
@@ -30,16 +30,44 @@ public class ErrorDialog {
 	private MessageBox box;
 	
 	/**
-	 * @param parent
-	 * @param message
-	 * @param canRetry
+	 * Message box buttons
 	 */
-	public ErrorDialog(Shell parent, String message, boolean canRetry) {
+	public enum ERROR_BUTTONS {
+		/**
+		 * Display only ok button
+		 */
+		OK,
+		/**
+		 * Display retry and cancel buttons
+		 */
+		RETRY_CANCEL,
+		/**
+		 * Display abort, retry and ignore buttons
+		 */
+		ABORT_RETRY_IGNORE
+	};
+	
+	/**
+	 * @param parent The parent shell
+	 * @param message The error message
+	 * @param button The buttons to be shown
+	 */
+	public ErrorDialog(Shell parent, String message, ERROR_BUTTONS button) {
+		this.initialize(parent, message, button);
+	}
+	
+	private void initialize(Shell parent, String message, ERROR_BUTTONS button) {
 		int boxstyle = SWT.ICON_ERROR ;
-		if(canRetry) {
-			boxstyle |= SWT.RETRY| SWT.CANCEL;
-		} else {
+		switch(button) {
+		case OK:
 			boxstyle |= SWT.OK;
+			break;
+		case RETRY_CANCEL:
+			boxstyle |= SWT.RETRY| SWT.CANCEL;
+			break;
+		case ABORT_RETRY_IGNORE:
+			boxstyle |= SWT.RETRY| SWT.ABORT | SWT.IGNORE;
+			break;
 		}
 		
 		this.box = new MessageBox(parent, boxstyle);
@@ -50,13 +78,9 @@ public class ErrorDialog {
 	/**
 	 * Open error dialog
 	 * 
-	 * @return if the user wants to retry the action which caused the error
+	 * @return SWT.OK | SWT.IGNORE | SWT.ABORT | SWT.RETRY | SWT.CANCEL
 	 */
-	public boolean open() {
-		int rc = this.box.open();
-		if(rc == SWT.RETRY) {
-			return true;
-		} 
-		return false;
+	public int open() {
+		return this.box.open();
 	}
 }
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/exceptions/OutputfolderDontExistException.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/exceptions/OutputfolderDontExistException.java
new file mode 100644
index 00000000..d7e5ba01
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/exceptions/OutputfolderDontExistException.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012 by A-SIT, Secure Information Technology Center Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package at.asit.pdfover.gui.exceptions;
+
+import java.io.File;
+
+import at.asit.pdfover.gui.Messages;
+
+/**
+ * 
+ */
+public class OutputfolderDontExistException extends ResumeableException {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -1005495921021280599L;
+	
+	/**
+	 * @param folder The file
+	 * @param resumeIndex The resume Index
+	 */
+	public OutputfolderDontExistException(final File folder, int resumeIndex) {
+		super(String.format(Messages.getString("exception.PathNotExist"), folder.getAbsolutePath()), resumeIndex); //$NON-NLS-1$
+	}
+
+}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/exceptions/OutputfolderNotADirectoryException.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/exceptions/OutputfolderNotADirectoryException.java
new file mode 100644
index 00000000..50759790
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/exceptions/OutputfolderNotADirectoryException.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2012 by A-SIT, Secure Information Technology Center Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package at.asit.pdfover.gui.exceptions;
+
+// Imports
+import java.io.File;
+
+
+import at.asit.pdfover.gui.Messages;
+
+/**
+ * 
+ */
+/**
+ * 
+ */
+public class OutputfolderNotADirectoryException extends Exception {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -3270628002264772405L;
+	
+	/**
+	 * @param folder The file
+	 */
+	public OutputfolderNotADirectoryException(File folder) {
+		super(String.format(Messages.getString("exception.PathNotDirectory"), folder.getAbsolutePath())); //$NON-NLS-1$
+	}
+}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/exceptions/ResumeableException.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/exceptions/ResumeableException.java
new file mode 100644
index 00000000..a4add193
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/exceptions/ResumeableException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012 by A-SIT, Secure Information Technology Center Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package at.asit.pdfover.gui.exceptions;
+
+/**
+ * 
+ */
+public class ResumeableException extends Exception {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -607216270516492225L;
+
+	private int resumeIndex = 0;
+	
+	/**
+	 * Create a new resumable exception, thrown by a validator which can be ignored
+	 * @param msg Error message
+	 * @param resumeIndex Validator index to resume from
+	 */
+	public ResumeableException(String msg, int resumeIndex) {
+		super(msg);
+		this.resumeIndex = resumeIndex;
+	}
+
+	/**
+	 * Create a new resumable exception, thrown by a validator which can be ignored
+	 * @param msg Error message
+	 * @param cause Exception causing this one
+	 * @param resumeIndex Validator index to resume from
+	 */
+	public ResumeableException(String msg, Throwable cause, int resumeIndex) {
+		super(msg, cause);
+		this.resumeIndex = resumeIndex;
+	}
+
+	/**
+	 * @return the resumeIndex
+	 */
+	public int getResumeIndex() {
+		return this.resumeIndex;
+	}
+
+}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachineImpl.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachineImpl.java
index db20bde3..8ef85bd1 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachineImpl.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachineImpl.java
@@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory;
 import at.asit.pdfover.gui.MainWindow;
 import at.asit.pdfover.gui.Messages;
 import at.asit.pdfover.gui.controls.ErrorDialog;
+import at.asit.pdfover.gui.controls.ErrorDialog.ERROR_BUTTONS;
 import at.asit.pdfover.gui.workflow.states.PrepareConfigurationState;
 import at.asit.pdfover.gui.workflow.states.State;
 
@@ -87,7 +88,7 @@ public class StateMachineImpl implements StateMachine, GUIProvider {
 			} catch (Exception e) {
 				log.error("StateMachine update: ", e); //$NON-NLS-1$
 				ErrorDialog errorState = new ErrorDialog(this.getMainShell(), 
-						Messages.getString("error.Unexpected"), false); //$NON-NLS-1$
+						Messages.getString("error.Unexpected"), ERROR_BUTTONS.OK); //$NON-NLS-1$
 				//errorState.setException(e);
 				//jumpToState(errorState);
 				errorState.open();
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/LocalBKUState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/LocalBKUState.java
index 234b4317..46daf8f7 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/LocalBKUState.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/LocalBKUState.java
@@ -20,6 +20,7 @@ import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.HttpException;
 import org.apache.commons.httpclient.HttpStatus;
 import org.apache.commons.httpclient.methods.PostMethod;
+import org.eclipse.swt.SWT;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -27,6 +28,7 @@ import at.asit.pdfover.gui.MainWindow.Buttons;
 import at.asit.pdfover.gui.MainWindowBehavior;
 import at.asit.pdfover.gui.Messages;
 import at.asit.pdfover.gui.controls.ErrorDialog;
+import at.asit.pdfover.gui.controls.ErrorDialog.ERROR_BUTTONS;
 import at.asit.pdfover.gui.workflow.StateMachine;
 import at.asit.pdfover.gui.workflow.Status;
 import at.asit.pdfover.signator.SLRequest;
@@ -171,8 +173,8 @@ public class LocalBKUState extends State {
 			ErrorDialog dialog = new ErrorDialog(
 					this.stateMachine.getGUIProvider().getMainShell(), 
 					Messages.getString("error.LocalBKU"), //$NON-NLS-1$
-					true);
-			if (!dialog.open()) {
+					ERROR_BUTTONS.RETRY_CANCEL);
+			if (dialog.open() != SWT.RETRY) {
 				this.stateMachine.exit();
 				return;
 			}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java
index 326eb12f..401d71f3 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java
@@ -27,6 +27,7 @@ import at.asit.pdfover.gui.composites.MobileBKUEnterNumberComposite;
 import at.asit.pdfover.gui.composites.MobileBKUEnterTANComposite;
 import at.asit.pdfover.gui.composites.WaitingComposite;
 import at.asit.pdfover.gui.controls.ErrorDialog;
+import at.asit.pdfover.gui.controls.ErrorDialog.ERROR_BUTTONS;
 import at.asit.pdfover.gui.workflow.StateMachine;
 import at.asit.pdfover.gui.workflow.states.mobilebku.MobileBKUCommunicationState;
 import at.asit.pdfover.gui.workflow.states.mobilebku.MobileBKUStatus;
@@ -152,7 +153,7 @@ public class MobileBKUState extends State {
 		if (this.threadException != null) {
 			ErrorDialog error = new ErrorDialog(
 					this.stateMachine.getGUIProvider().getMainShell(),
-					Messages.getString("error.Unexpected"), false); //$NON-NLS-1$
+					Messages.getString("error.Unexpected"), ERROR_BUTTONS.OK); //$NON-NLS-1$
 			// error.setException(this.threadException);
 			// this.setNextState(error);
 			error.open();
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OutputState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OutputState.java
index 5ed273ca..a6ec93bd 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OutputState.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OutputState.java
@@ -29,6 +29,7 @@ import at.asit.pdfover.gui.MainWindowBehavior;
 import at.asit.pdfover.gui.Messages;
 import at.asit.pdfover.gui.composites.OutputComposite;
 import at.asit.pdfover.gui.controls.ErrorDialog;
+import at.asit.pdfover.gui.controls.ErrorDialog.ERROR_BUTTONS;
 import at.asit.pdfover.gui.workflow.StateMachine;
 import at.asit.pdfover.gui.workflow.Status;
 import at.asit.pdfover.signator.DocumentSource;
@@ -100,7 +101,7 @@ public class OutputState extends State {
 					} catch (IOException e) {
 						log.error("Failed to save signed document to configured output folder.", e); //$NON-NLS-1$
 						ErrorDialog dialog = new ErrorDialog(outputComposite.getShell(), 
-								Messages.getString("error.SaveOutputFolder"), false); //$NON-NLS-1$
+								Messages.getString("error.SaveOutputFolder"), ERROR_BUTTONS.OK); //$NON-NLS-1$
 						dialog.open();
 					}
 				}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareConfigurationState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareConfigurationState.java
index e5117768..29a17ad9 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareConfigurationState.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareConfigurationState.java
@@ -39,6 +39,7 @@ import at.asit.pdfover.gui.cliarguments.PhoneNumberArgument;
 import at.asit.pdfover.gui.cliarguments.ProxyHostArgument;
 import at.asit.pdfover.gui.cliarguments.ProxyPortArgument;
 import at.asit.pdfover.gui.controls.ErrorDialog;
+import at.asit.pdfover.gui.controls.ErrorDialog.ERROR_BUTTONS;
 import at.asit.pdfover.gui.exceptions.InitializationException;
 import at.asit.pdfover.gui.utils.Unzipper;
 import at.asit.pdfover.gui.workflow.ConfigManipulator;
@@ -244,7 +245,7 @@ public class PrepareConfigurationState extends State {
 			ErrorDialog error = new ErrorDialog(this.stateMachine
 					.getGUIProvider().getMainShell(), 
 					Messages.getString("error.Initialization"), //$NON-NLS-1$
-					false);
+					ERROR_BUTTONS.OK);
 			// error.setException(e);
 			// this.setNextState(error);
 			error.open();
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareSigningState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareSigningState.java
index 6381038f..77362682 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareSigningState.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareSigningState.java
@@ -25,6 +25,7 @@ import at.asit.pdfover.gui.MainWindowBehavior;
 import at.asit.pdfover.gui.Messages;
 import at.asit.pdfover.gui.composites.WaitingComposite;
 import at.asit.pdfover.gui.controls.ErrorDialog;
+import at.asit.pdfover.gui.controls.ErrorDialog.ERROR_BUTTONS;
 import at.asit.pdfover.gui.workflow.ConfigProvider;
 import at.asit.pdfover.gui.workflow.StateMachine;
 import at.asit.pdfover.gui.workflow.Status;
@@ -155,9 +156,9 @@ public class PrepareSigningState extends State {
 		if(this.threadException != null) {
 			ErrorDialog error = new ErrorDialog(this.stateMachine.getGUIProvider().getMainShell(),
 					Messages.getString("error.PrepareDocument"),  //$NON-NLS-1$
-					true);
+					ERROR_BUTTONS.RETRY_CANCEL);
 			this.threadException = null;
-			if(error.open()) {
+			if(error.open() == SWT.RETRY) {
 				this.stateMachine.update();
 			} else {
 				this.stateMachine.exit();
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/SigningState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/SigningState.java
index e16e4cb3..932a6d8a 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/SigningState.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/SigningState.java
@@ -16,11 +16,13 @@
 package at.asit.pdfover.gui.workflow.states;
 
 //Imports
+import org.eclipse.swt.SWT;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import at.asit.pdfover.gui.Messages;
 import at.asit.pdfover.gui.controls.ErrorDialog;
+import at.asit.pdfover.gui.controls.ErrorDialog.ERROR_BUTTONS;
 import at.asit.pdfover.gui.workflow.StateMachine;
 import at.asit.pdfover.gui.workflow.Status;
 import at.asit.pdfover.signator.Signer;
@@ -87,9 +89,9 @@ public class SigningState extends State {
 		
 		if(this.threadException != null) {
 			ErrorDialog error = new ErrorDialog(this.stateMachine.getGUIProvider().getMainShell(),
-					Messages.getString("error.Signatur"), true);  //$NON-NLS-1$
+					Messages.getString("error.Signatur"), ERROR_BUTTONS.RETRY_CANCEL);  //$NON-NLS-1$
 			this.threadException = null;
-			if(error.open()) {
+			if(error.open() == SWT.RETRY) {
 				this.setNextState(new BKUSelectionState(this.stateMachine));
 			} else {
 				this.stateMachine.exit();
diff --git a/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages.properties b/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages.properties
index 51a5ae9a..a594a7dc 100644
--- a/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages.properties
+++ b/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages.properties
@@ -15,6 +15,9 @@ advanced_config.OutputFolder_Title=Output location
 advanced_config.SigPHTransparency=Signature placeholder transparency
 advanced_config.SigPHTransparencyMax=Opaque
 advanced_config.SigPHTransparencyMin=Invisible
+advanced_config.AutoPosition_ToolTip=Activate this option to automatically position the signature
+advanced_config.OutputFolder_ToolTip=Select the folder where the signed document will be saved automatically (clear this field to disable automatic saving)
+advanced_config.BKUSelection_ToolTip=Select the default BKU to use during signature
 argument.error.output=is not a directory
 argument.help.bku=Select the BKU to use values are: LOCAL, MOBILE (example: -b <option>
 argument.help.config=Defines which configuration file to use. Example: -c <config file>
@@ -101,6 +104,9 @@ simple_config.ProxyPort=Port:
 simple_config.ProxyPortTemplate=port proxy server [1-65535]
 simple_config.Proxy_Title=Proxy
 simple_config.ClearEmblem=Clear
+simple_config.ExampleNumber_ToolTip=To use a default mobile phone number enter it here
+simple_config.ProxyHost_ToolTip=To use a proxy server enter the hostname or the IP here
+simple_config.ProxyPort_ToolTip=To use a proxy server enter the port number here
 tanEnter.ReferenceValue=Reference value
 tanEnter.TAN=TAN:
 tanEnter.tries=tries left!
-- 
cgit v1.2.3