Преглед на файлове

Merge pull request #3618 from cryptomator/feature/dialog-builder

Feature: SimpleDialogBuilder
mindmonk преди 5 месеца
родител
ревизия
de3b2715c7
променени са 30 файла, в които са добавени 361 реда и са изтрити 628 реда
  1. 1 3
      src/main/java/org/cryptomator/ui/common/FxmlFile.java
  2. 75 0
      src/main/java/org/cryptomator/ui/dialogs/Dialogs.java
  3. 138 0
      src/main/java/org/cryptomator/ui/dialogs/SimpleDialog.java
  4. 61 0
      src/main/java/org/cryptomator/ui/dialogs/SimpleDialogController.java
  5. 0 34
      src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndComponent.java
  6. 0 34
      src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndController.java
  7. 0 57
      src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndModule.java
  8. 0 13
      src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndScoped.java
  9. 0 14
      src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndWindow.java
  10. 0 4
      src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java
  11. 12 7
      src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java
  12. 1 2
      src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java
  13. 12 6
      src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java
  14. 15 5
      src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnknownErrorController.java
  15. 15 5
      src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java
  16. 7 6
      src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java
  17. 11 5
      src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java
  18. 0 34
      src/main/java/org/cryptomator/ui/removecert/RemoveCertComponent.java
  19. 0 32
      src/main/java/org/cryptomator/ui/removecert/RemoveCertController.java
  20. 0 56
      src/main/java/org/cryptomator/ui/removecert/RemoveCertModule.java
  21. 0 13
      src/main/java/org/cryptomator/ui/removecert/RemoveCertScoped.java
  22. 0 14
      src/main/java/org/cryptomator/ui/removecert/RemoveCertWindow.java
  23. 0 39
      src/main/java/org/cryptomator/ui/removevault/RemoveVaultComponent.java
  24. 0 40
      src/main/java/org/cryptomator/ui/removevault/RemoveVaultController.java
  25. 0 59
      src/main/java/org/cryptomator/ui/removevault/RemoveVaultModule.java
  26. 0 13
      src/main/java/org/cryptomator/ui/removevault/RemoveVaultScoped.java
  27. 0 14
      src/main/java/org/cryptomator/ui/removevault/RemoveVaultWindow.java
  28. 0 53
      src/main/resources/fxml/dokany_support_end.fxml
  29. 0 52
      src/main/resources/fxml/remove_vault.fxml
  30. 13 14
      src/main/resources/fxml/remove_cert.fxml

+ 1 - 3
src/main/java/org/cryptomator/ui/common/FxmlFile.java

@@ -12,7 +12,6 @@ public enum FxmlFile {
 	CONVERTVAULT_HUBTOPASSWORD_START("/fxml/convertvault_hubtopassword_start.fxml"), //
 	CONVERTVAULT_HUBTOPASSWORD_CONVERT("/fxml/convertvault_hubtopassword_convert.fxml"), //
 	CONVERTVAULT_HUBTOPASSWORD_SUCCESS("/fxml/convertvault_hubtopassword_success.fxml"), //
-	DOKANY_SUPPORT_END("/fxml/dokany_support_end.fxml"), //
 	ERROR("/fxml/error.fxml"), //
 	FORGET_PASSWORD("/fxml/forget_password.fxml"), //
 	HEALTH_START("/fxml/health_start.fxml"), //
@@ -45,9 +44,8 @@ public enum FxmlFile {
 	RECOVERYKEY_RESET_PASSWORD("/fxml/recoverykey_reset_password.fxml"), //
 	RECOVERYKEY_RESET_PASSWORD_SUCCESS("/fxml/recoverykey_reset_password_success.fxml"), //
 	RECOVERYKEY_SUCCESS("/fxml/recoverykey_success.fxml"), //
-	REMOVE_CERT("/fxml/remove_cert.fxml"), //
-	REMOVE_VAULT("/fxml/remove_vault.fxml"), //
 	SHARE_VAULT("/fxml/share_vault.fxml"), //
+	SIMPLE_DIALOG("/fxml/simple_dialog.fxml"), //
 	UPDATE_REMINDER("/fxml/update_reminder.fxml"), //
 	UNLOCK_ENTER_PASSWORD("/fxml/unlock_enter_password.fxml"),
 	UNLOCK_REQUIRES_RESTART("/fxml/unlock_requires_restart.fxml"), //

+ 75 - 0
src/main/java/org/cryptomator/ui/dialogs/Dialogs.java

@@ -0,0 +1,75 @@
+package org.cryptomator.ui.dialogs;
+
+import org.cryptomator.common.settings.Settings;
+import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.ui.controls.FontAwesome5Icon;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javafx.collections.ObservableList;
+import javafx.stage.Stage;
+import java.util.ResourceBundle;
+import java.util.function.Consumer;
+
+@Singleton
+public class Dialogs {
+
+	private final ResourceBundle resourceBundle;
+
+	@Inject
+	public Dialogs(ResourceBundle resourceBundle) {
+		this.resourceBundle = resourceBundle;
+	}
+
+	private static final Logger LOG = LoggerFactory.getLogger(Dialogs.class);
+
+	private SimpleDialog.Builder createDialogBuilder() {
+		return new SimpleDialog.Builder(resourceBundle);
+	}
+
+	public SimpleDialog.Builder prepareRemoveVaultDialog(Stage window, Vault vault, ObservableList<Vault> vaults) {
+		return createDialogBuilder().setOwner(window) //
+				.setTitleKey("removeVault.title", vault.getDisplayName()) //
+				.setMessageKey("removeVault.message") //
+				.setDescriptionKey("removeVault.description") //
+				.setIcon(FontAwesome5Icon.QUESTION) //
+				.setOkButtonKey("removeVault.confirmBtn") //
+				.setCancelButtonKey("generic.button.cancel") //
+				.setOkAction(stage -> {
+					LOG.debug("Removing vault {}.", vault.getDisplayName());
+					vaults.remove(vault);
+					stage.close();
+				});
+	}
+
+	public SimpleDialog.Builder prepareRemoveCertDialog(Stage window, Settings settings) {
+		return createDialogBuilder() //
+				.setOwner(window) //
+				.setTitleKey("removeCert.title") //
+				.setMessageKey("removeCert.message") //
+				.setDescriptionKey("removeCert.description") //
+				.setIcon(FontAwesome5Icon.QUESTION) //
+				.setOkButtonKey("removeCert.confirmBtn") //
+				.setCancelButtonKey("generic.button.cancel") //
+				.setOkAction(stage -> {
+					settings.licenseKey.set(null);
+					stage.close();
+				});
+	}
+
+	public SimpleDialog.Builder prepareDokanySupportEndDialog(Stage window, Consumer<Stage> cancelAction) {
+		return createDialogBuilder() //
+				.setOwner(window) //
+				.setTitleKey("dokanySupportEnd.title") //
+				.setMessageKey("dokanySupportEnd.message") //
+				.setDescriptionKey("dokanySupportEnd.description") //
+				.setIcon(FontAwesome5Icon.QUESTION) //
+				.setOkButtonKey("generic.button.close") //
+				.setCancelButtonKey("dokanySupportEnd.preferencesBtn") //
+				.setOkAction(Stage::close) //
+				.setCancelAction(cancelAction);
+	}
+
+}

+ 138 - 0
src/main/java/org/cryptomator/ui/dialogs/SimpleDialog.java

@@ -0,0 +1,138 @@
+package org.cryptomator.ui.dialogs;
+
+import org.cryptomator.ui.common.FxmlFile;
+import org.cryptomator.ui.common.FxmlLoaderFactory;
+import org.cryptomator.ui.controls.FontAwesome5Icon;
+
+import javafx.scene.Scene;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.IllegalFormatException;
+import java.util.Objects;
+import java.util.ResourceBundle;
+import java.util.function.Consumer;
+
+public class SimpleDialog {
+
+	private final ResourceBundle resourceBundle;
+
+	private final Stage dialogStage;
+
+	SimpleDialog(Builder builder) throws IOException {
+		this.resourceBundle = builder.resourceBundle;
+		dialogStage = new Stage();
+		dialogStage.initOwner(builder.owner);
+		dialogStage.initModality(Modality.WINDOW_MODAL);
+		dialogStage.setTitle(resolveText(builder.titleKey, builder.titleArgs));
+		dialogStage.setResizable(false);
+
+		FxmlLoaderFactory loaderFactory = FxmlLoaderFactory.forController(
+				new SimpleDialogController(resolveText(builder.messageKey, null),
+						resolveText(builder.descriptionKey, null),
+						builder.icon,resolveText(builder.okButtonKey, null),
+						resolveText(builder.cancelButtonKey, null),
+						() -> builder.okAction.accept(dialogStage),
+						() -> builder.cancelAction.accept(dialogStage)),
+				Scene::new, builder.resourceBundle);
+
+		dialogStage.setScene(new Scene(loaderFactory.load(FxmlFile.SIMPLE_DIALOG.getRessourcePathString()).getRoot()));
+	}
+
+	public void showAndWait() {
+		dialogStage.showAndWait();
+	}
+
+	private String resolveText(String key, String[] args) {
+		if (key == null || key.isEmpty() || !resourceBundle.containsKey(key)) {
+			throw new IllegalArgumentException(String.format("Invalid key: '%s'. Key not found in ResourceBundle.", key));
+		}
+		String text = resourceBundle.getString(key);
+		try {
+			return args != null && args.length > 0 ? String.format(text, (Object[]) args) : text;
+		} catch (IllegalFormatException e) {
+			throw new IllegalArgumentException("Formatting error: Check if arguments match placeholders in the text.", e);
+		}
+	}
+
+	public static class Builder {
+
+		private Stage owner;
+		private final ResourceBundle resourceBundle;
+		private String titleKey;
+		private String[] titleArgs;
+		private String messageKey;
+		private String descriptionKey;
+		private String okButtonKey;
+		private String cancelButtonKey;
+
+		private FontAwesome5Icon icon;
+		private Consumer<Stage> okAction = Stage::close;
+		private Consumer<Stage> cancelAction = Stage::close;
+
+		public Builder(ResourceBundle resourceBundle) {
+			this.resourceBundle = resourceBundle;
+		}
+
+		public Builder setOwner(Stage owner) {
+			this.owner = owner;
+			return this;
+		}
+
+		public Builder setTitleKey(String titleKey, String... args) {
+			this.titleKey = titleKey;
+			this.titleArgs = args;
+			return this;
+		}
+
+		public Builder setMessageKey(String messageKey) {
+			this.messageKey = messageKey;
+			return this;
+		}
+
+		public Builder setDescriptionKey(String descriptionKey) {
+			this.descriptionKey = descriptionKey;
+			return this;
+		}
+
+		public Builder setIcon(FontAwesome5Icon icon) {
+			this.icon = icon;
+			return this;
+		}
+
+		public Builder setOkButtonKey(String okButtonKey) {
+			this.okButtonKey = okButtonKey;
+			return this;
+		}
+
+		public Builder setCancelButtonKey(String cancelButtonKey) {
+			this.cancelButtonKey = cancelButtonKey;
+			return this;
+		}
+
+		public Builder setOkAction(Consumer<Stage> okAction) {
+			this.okAction = okAction;
+			return this;
+		}
+
+		public Builder setCancelAction(Consumer<Stage> cancelAction) {
+			this.cancelAction = cancelAction;
+			return this;
+		}
+
+		public SimpleDialog build() {
+			Objects.requireNonNull(titleKey,"SimpleDialog titleKey must be set.");
+			Objects.requireNonNull(messageKey,"SimpleDialog messageKey must be set.");
+			Objects.requireNonNull(descriptionKey,"SimpleDialog descriptionKey must be set.");
+			Objects.requireNonNull(okButtonKey,"SimpleDialog okButtonKey must be set.");
+			Objects.requireNonNull(cancelButtonKey,"SimpleDialog cancelButtonKey must be set.");
+
+			try {
+				return new SimpleDialog(this);
+			} catch (IOException e) {
+				throw new UncheckedIOException("Failed to create SimpleDialog.", e);
+			}
+		}
+	}
+}

+ 61 - 0
src/main/java/org/cryptomator/ui/dialogs/SimpleDialogController.java

@@ -0,0 +1,61 @@
+package org.cryptomator.ui.dialogs;
+
+import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.controls.FontAwesome5Icon;
+
+import javafx.fxml.FXML;
+
+public class SimpleDialogController implements FxController {
+
+	private final String message;
+	private final String description;
+	private final FontAwesome5Icon icon;
+	private final String okButtonText;
+	private final String cancelButtonText;
+	private final Runnable okAction;
+	private final Runnable cancelAction;
+
+	public SimpleDialogController(String message, String description, FontAwesome5Icon icon, String okButtonText, String cancelButtonText, Runnable okAction, Runnable cancelAction) {
+		this.message = message;
+		this.description = description;
+		this.icon = icon;
+		this.okButtonText = okButtonText;
+		this.cancelButtonText = cancelButtonText;
+		this.okAction = okAction;
+		this.cancelAction = cancelAction;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public FontAwesome5Icon getIcon() {
+		return icon;
+	}
+
+	public String getOkButtonText() {
+		return okButtonText;
+	}
+
+	public String getCancelButtonText() {
+		return cancelButtonText;
+	}
+
+	@FXML
+	private void handleOk() {
+		if (okAction != null) {
+			okAction.run();
+		}
+	}
+
+	@FXML
+	private void handleCancel() {
+		if (cancelAction != null) {
+			cancelAction.run();
+		}
+	}
+}

+ 0 - 34
src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndComponent.java

@@ -1,34 +0,0 @@
-package org.cryptomator.ui.dokanysupportend;
-
-import dagger.Lazy;
-import dagger.Subcomponent;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlScene;
-
-import javafx.scene.Scene;
-import javafx.stage.Stage;
-
-@DokanySupportEndScoped
-@Subcomponent(modules = {DokanySupportEndModule.class})
-public interface DokanySupportEndComponent {
-
-	@DokanySupportEndWindow
-	Stage window();
-
-	@FxmlScene(FxmlFile.DOKANY_SUPPORT_END)
-	Lazy<Scene> dokanySupportEndScene();
-
-
-	default void showDokanySupportEndWindow() {
-		Stage stage = window();
-		stage.setScene(dokanySupportEndScene().get());
-		stage.sizeToScene();
-		stage.show();
-	}
-
-	@Subcomponent.Factory
-	interface Factory {
-
-		DokanySupportEndComponent create();
-	}
-}

+ 0 - 34
src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndController.java

@@ -1,34 +0,0 @@
-package org.cryptomator.ui.dokanysupportend;
-
-import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.fxapp.FxApplicationWindows;
-import org.cryptomator.ui.preferences.SelectedPreferencesTab;
-
-import javax.inject.Inject;
-import javafx.fxml.FXML;
-import javafx.stage.Stage;
-
-
-@DokanySupportEndScoped
-public class DokanySupportEndController implements FxController {
-
-	private final Stage window;
-	private final FxApplicationWindows applicationWindows;
-
-	@Inject
-	DokanySupportEndController(@DokanySupportEndWindow Stage window, FxApplicationWindows applicationWindows) {
-		this.window = window;
-		this.applicationWindows = applicationWindows;
-	}
-
-	@FXML
-	public void close() {
-		window.close();
-	}
-
-	public void openVolumePreferences() {
-		applicationWindows.showPreferencesWindow(SelectedPreferencesTab.VOLUME);
-		window.close();
-	}
-
-}

+ 0 - 57
src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndModule.java

@@ -1,57 +0,0 @@
-package org.cryptomator.ui.dokanysupportend;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoMap;
-import org.cryptomator.ui.common.DefaultSceneFactory;
-import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.common.FxControllerKey;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlLoaderFactory;
-import org.cryptomator.ui.common.FxmlScene;
-import org.cryptomator.ui.common.StageFactory;
-
-import javax.inject.Provider;
-import javafx.scene.Scene;
-import javafx.stage.Modality;
-import javafx.stage.Stage;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-@Module
-abstract class DokanySupportEndModule {
-
-	@Provides
-	@DokanySupportEndWindow
-	@DokanySupportEndScoped
-	static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
-		return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
-	}
-
-	@Provides
-	@DokanySupportEndWindow
-	@DokanySupportEndScoped
-	static Stage provideStage(StageFactory factory, ResourceBundle resourceBundle) {
-		Stage stage = factory.create();
-		stage.setTitle(resourceBundle.getString("dokanySupportEnd.title"));
-		stage.setMinWidth(500);
-		stage.setMinHeight(100);
-		stage.initModality(Modality.APPLICATION_MODAL);
-		return stage;
-	}
-
-	@Provides
-	@FxmlScene(FxmlFile.DOKANY_SUPPORT_END)
-	@DokanySupportEndScoped
-	static Scene provideDokanySupportEndScene(@DokanySupportEndWindow FxmlLoaderFactory fxmlLoaders) {
-		return fxmlLoaders.createScene(FxmlFile.DOKANY_SUPPORT_END);
-	}
-
-
-	@Binds
-	@IntoMap
-	@FxControllerKey(DokanySupportEndController.class)
-	abstract FxController bindDokanySupportEndController(DokanySupportEndController controller);
-
-}

+ 0 - 13
src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndScoped.java

@@ -1,13 +0,0 @@
-package org.cryptomator.ui.dokanysupportend;
-
-import javax.inject.Scope;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-@Scope
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@interface DokanySupportEndScoped {
-
-}

+ 0 - 14
src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndWindow.java

@@ -1,14 +0,0 @@
-package org.cryptomator.ui.dokanysupportend;
-
-import javax.inject.Qualifier;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-@interface DokanySupportEndWindow {
-
-}

+ 0 - 4
src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java

@@ -7,14 +7,12 @@ package org.cryptomator.ui.fxapp;
 
 import dagger.Module;
 import dagger.Provides;
-import org.cryptomator.ui.dokanysupportend.DokanySupportEndComponent;
 import org.cryptomator.ui.error.ErrorComponent;
 import org.cryptomator.ui.health.HealthCheckComponent;
 import org.cryptomator.ui.lock.LockComponent;
 import org.cryptomator.ui.mainwindow.MainWindowComponent;
 import org.cryptomator.ui.preferences.PreferencesComponent;
 import org.cryptomator.ui.quit.QuitComponent;
-import org.cryptomator.ui.removecert.RemoveCertComponent;
 import org.cryptomator.ui.sharevault.ShareVaultComponent;
 import org.cryptomator.ui.traymenu.TrayMenuComponent;
 import org.cryptomator.ui.unlock.UnlockComponent;
@@ -35,8 +33,6 @@ import java.io.InputStream;
 		ErrorComponent.class, //
 		HealthCheckComponent.class, //
 		UpdateReminderComponent.class, //
-		DokanySupportEndComponent.class, //
-		RemoveCertComponent.class, //
 		ShareVaultComponent.class})
 abstract class FxApplicationModule {
 

+ 12 - 7
src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java

@@ -5,7 +5,7 @@ import dagger.Lazy;
 import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.common.vaults.VaultState;
 import org.cryptomator.integrations.tray.TrayIntegrationProvider;
-import org.cryptomator.ui.dokanysupportend.DokanySupportEndComponent;
+import org.cryptomator.ui.dialogs.Dialogs;
 import org.cryptomator.ui.error.ErrorComponent;
 import org.cryptomator.ui.lock.LockComponent;
 import org.cryptomator.ui.mainwindow.MainWindowComponent;
@@ -49,13 +49,13 @@ public class FxApplicationWindows {
 	private final QuitComponent.Builder quitWindowBuilder;
 	private final UnlockComponent.Factory unlockWorkflowFactory;
 	private final UpdateReminderComponent.Factory updateReminderWindowFactory;
-	private final DokanySupportEndComponent.Factory dokanySupportEndWindowBuilder;
 	private final LockComponent.Factory lockWorkflowFactory;
 	private final ErrorComponent.Factory errorWindowFactory;
 	private final ExecutorService executor;
 	private final VaultOptionsComponent.Factory vaultOptionsWindow;
 	private final ShareVaultComponent.Factory shareVaultWindow;
 	private final FilteredList<Window> visibleWindows;
+	private final Dialogs dialogs;
 
 	@Inject
 	public FxApplicationWindows(@PrimaryStage Stage primaryStage, //
@@ -65,12 +65,12 @@ public class FxApplicationWindows {
 								QuitComponent.Builder quitWindowBuilder, //
 								UnlockComponent.Factory unlockWorkflowFactory, //
 								UpdateReminderComponent.Factory updateReminderWindowFactory, //
-								DokanySupportEndComponent.Factory dokanySupportEndWindowBuilder, //
 								LockComponent.Factory lockWorkflowFactory, //
 								ErrorComponent.Factory errorWindowFactory, //
 								VaultOptionsComponent.Factory vaultOptionsWindow, //
 								ShareVaultComponent.Factory shareVaultWindow, //
-								ExecutorService executor) {
+								ExecutorService executor, //
+								Dialogs dialogs) {
 		this.primaryStage = primaryStage;
 		this.trayIntegration = trayIntegration;
 		this.mainWindow = mainWindow;
@@ -78,13 +78,13 @@ public class FxApplicationWindows {
 		this.quitWindowBuilder = quitWindowBuilder;
 		this.unlockWorkflowFactory = unlockWorkflowFactory;
 		this.updateReminderWindowFactory = updateReminderWindowFactory;
-		this.dokanySupportEndWindowBuilder = dokanySupportEndWindowBuilder;
 		this.lockWorkflowFactory = lockWorkflowFactory;
 		this.errorWindowFactory = errorWindowFactory;
 		this.executor = executor;
 		this.vaultOptionsWindow = vaultOptionsWindow;
 		this.shareVaultWindow = shareVaultWindow;
 		this.visibleWindows = Window.getWindows().filtered(Window::isShowing);
+		this.dialogs = dialogs;
 	}
 
 	public void initialize() {
@@ -147,10 +147,15 @@ public class FxApplicationWindows {
 	}
 
 	public void showDokanySupportEndWindow() {
-		CompletableFuture.runAsync(() -> dokanySupportEndWindowBuilder.create().showDokanySupportEndWindow(), Platform::runLater);
+		CompletableFuture.runAsync(() -> dialogs.prepareDokanySupportEndDialog(
+				mainWindow.get().window(),
+				stage -> {
+					showPreferencesWindow(SelectedPreferencesTab.VOLUME);
+					stage.close();
+				}
+		).build().showAndWait(), Platform::runLater);
 	}
 
-
 	public CompletionStage<Void> startUnlockWorkflow(Vault vault, @Nullable Stage owner) {
 		return CompletableFuture.supplyAsync(() -> {
 					Preconditions.checkState(vault.stateProperty().transition(VaultState.Value.LOCKED, VaultState.Value.PROCESSING), "Vault not locked.");

+ 1 - 2
src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java

@@ -16,7 +16,6 @@ import org.cryptomator.ui.common.StageInitializer;
 import org.cryptomator.ui.error.ErrorComponent;
 import org.cryptomator.ui.fxapp.PrimaryStage;
 import org.cryptomator.ui.migration.MigrationComponent;
-import org.cryptomator.ui.removevault.RemoveVaultComponent;
 import org.cryptomator.ui.stats.VaultStatisticsComponent;
 import org.cryptomator.ui.wrongfilealert.WrongFileAlertComponent;
 
@@ -30,7 +29,7 @@ import javafx.stage.Stage;
 import java.util.Map;
 import java.util.ResourceBundle;
 
-@Module(subcomponents = {AddVaultWizardComponent.class, MigrationComponent.class, RemoveVaultComponent.class, VaultStatisticsComponent.class, WrongFileAlertComponent.class, ErrorComponent.class})
+@Module(subcomponents = {AddVaultWizardComponent.class, MigrationComponent.class, VaultStatisticsComponent.class, WrongFileAlertComponent.class, ErrorComponent.class})
 abstract class MainWindowModule {
 
 	@Provides

+ 12 - 6
src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java

@@ -3,10 +3,11 @@ package org.cryptomator.ui.mainwindow;
 import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.common.vaults.VaultListManager;
 import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.removevault.RemoveVaultComponent;
+import org.cryptomator.ui.dialogs.Dialogs;
 
 import javax.inject.Inject;
 import javafx.beans.property.ObjectProperty;
+import javafx.collections.ObservableList;
 import javafx.fxml.FXML;
 import javafx.stage.FileChooser;
 import javafx.stage.Stage;
@@ -19,17 +20,22 @@ import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB;
 public class VaultDetailMissingVaultController implements FxController {
 
 	private final ObjectProperty<Vault> vault;
-	private final RemoveVaultComponent.Builder removeVault;
+	private final ObservableList<Vault> vaults;
 	private final ResourceBundle resourceBundle;
 	private final Stage window;
-
+	private final Dialogs dialogs;
 
 	@Inject
-	public VaultDetailMissingVaultController(ObjectProperty<Vault> vault, RemoveVaultComponent.Builder removeVault, ResourceBundle resourceBundle, @MainWindow Stage window) {
+	public VaultDetailMissingVaultController(ObjectProperty<Vault> vault, //
+											 ObservableList<Vault> vaults, //
+											 ResourceBundle resourceBundle, //
+											 @MainWindow Stage window, //
+											 Dialogs dialogs) {
 		this.vault = vault;
-		this.removeVault = removeVault;
+		this.vaults = vaults;
 		this.resourceBundle = resourceBundle;
 		this.window = window;
+		this.dialogs = dialogs;
 	}
 
 	@FXML
@@ -39,7 +45,7 @@ public class VaultDetailMissingVaultController implements FxController {
 
 	@FXML
 	void didClickRemoveVault() {
-		removeVault.vault(vault.get()).build().showRemoveVault();
+		dialogs.prepareRemoveVaultDialog(window, vault.get(), vaults).build().showAndWait();
 	}
 
 	@FXML

+ 15 - 5
src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnknownErrorController.java

@@ -3,12 +3,13 @@ package org.cryptomator.ui.mainwindow;
 import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.common.vaults.VaultListManager;
 import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.dialogs.Dialogs;
 import org.cryptomator.ui.fxapp.FxApplicationWindows;
-import org.cryptomator.ui.removevault.RemoveVaultComponent;
 
 import javax.inject.Inject;
 import javax.inject.Named;
 import javafx.beans.property.ObjectProperty;
+import javafx.collections.ObservableList;
 import javafx.fxml.FXML;
 import javafx.stage.Stage;
 
@@ -18,14 +19,23 @@ public class VaultDetailUnknownErrorController implements FxController {
 	private final ObjectProperty<Vault> vault;
 	private final FxApplicationWindows appWindows;
 	private final Stage errorWindow;
-	private final RemoveVaultComponent.Builder removeVault;
+	private final ObservableList<Vault> vaults;
+	private final Stage mainWindow;
+	private final Dialogs dialogs;
 
 	@Inject
-	public VaultDetailUnknownErrorController(ObjectProperty<Vault> vault, FxApplicationWindows appWindows, @Named("errorWindow") Stage errorWindow, RemoveVaultComponent.Builder removeVault) {
+	public VaultDetailUnknownErrorController(@MainWindow Stage mainWindow, //
+											 ObjectProperty<Vault> vault, //
+											 ObservableList<Vault> vaults, //
+											 FxApplicationWindows appWindows, //
+											 @Named("errorWindow") Stage errorWindow, //
+											 Dialogs dialogs) {
+		this.mainWindow = mainWindow;
 		this.vault = vault;
+		this.vaults = vaults;
 		this.appWindows = appWindows;
 		this.errorWindow = errorWindow;
-		this.removeVault = removeVault;
+		this.dialogs = dialogs;
 	}
 
 	@FXML
@@ -40,6 +50,6 @@ public class VaultDetailUnknownErrorController implements FxController {
 
 	@FXML
 	void didClickRemoveVault() {
-		removeVault.vault(vault.get()).build().showRemoveVault();
+		dialogs.prepareRemoveVaultDialog(mainWindow, vault.get(), vaults).build().showAndWait();
 	}
 }

+ 15 - 5
src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java

@@ -5,8 +5,8 @@ import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.common.vaults.VaultState;
 import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.VaultService;
+import org.cryptomator.ui.dialogs.Dialogs;
 import org.cryptomator.ui.fxapp.FxApplicationWindows;
-import org.cryptomator.ui.removevault.RemoveVaultComponent;
 import org.cryptomator.ui.vaultoptions.SelectedVaultOptionsTab;
 import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
 
@@ -14,6 +14,7 @@ import javax.inject.Inject;
 import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.ReadOnlyObjectProperty;
 import javafx.beans.value.ObservableValue;
+import javafx.collections.ObservableList;
 import javafx.fxml.FXML;
 import javafx.stage.Stage;
 import java.util.EnumSet;
@@ -33,23 +34,32 @@ public class VaultListContextMenuController implements FxController {
 	private final FxApplicationWindows appWindows;
 	private final VaultService vaultService;
 	private final KeychainManager keychain;
-	private final RemoveVaultComponent.Builder removeVault;
 	private final VaultOptionsComponent.Factory vaultOptionsWindow;
 	private final ObservableValue<VaultState.Value> selectedVaultState;
 	private final ObservableValue<Boolean> selectedVaultPassphraseStored;
 	private final ObservableValue<Boolean> selectedVaultRemovable;
 	private final ObservableValue<Boolean> selectedVaultUnlockable;
 	private final ObservableValue<Boolean> selectedVaultLockable;
+	private final ObservableList<Vault> vaults;
+	private final Dialogs dialogs;
 
 	@Inject
-	VaultListContextMenuController(ObjectProperty<Vault> selectedVault, @MainWindow Stage mainWindow, FxApplicationWindows appWindows, VaultService vaultService, KeychainManager keychain, RemoveVaultComponent.Builder removeVault, VaultOptionsComponent.Factory vaultOptionsWindow) {
+	VaultListContextMenuController(ObjectProperty<Vault> selectedVault, //
+								   ObservableList<Vault> vaults, //
+								   @MainWindow Stage mainWindow, //
+								   FxApplicationWindows appWindows, //
+								   VaultService vaultService, //
+								   KeychainManager keychain, //
+								   VaultOptionsComponent.Factory vaultOptionsWindow, //
+								   Dialogs dialogs) {
 		this.selectedVault = selectedVault;
+		this.vaults = vaults;
 		this.mainWindow = mainWindow;
 		this.appWindows = appWindows;
 		this.vaultService = vaultService;
 		this.keychain = keychain;
-		this.removeVault = removeVault;
 		this.vaultOptionsWindow = vaultOptionsWindow;
+		this.dialogs = dialogs;
 
 		this.selectedVaultState = selectedVault.flatMap(Vault::stateProperty).orElse(null);
 		this.selectedVaultPassphraseStored = selectedVault.map(this::isPasswordStored).orElse(false);
@@ -65,7 +75,7 @@ public class VaultListContextMenuController implements FxController {
 	@FXML
 	public void didClickRemoveVault() {
 		var vault = Objects.requireNonNull(selectedVault.get());
-		removeVault.vault(vault).build().showRemoveVault();
+		dialogs.prepareRemoveVaultDialog(mainWindow, vault, vaults).build().showAndWait();
 	}
 
 	@FXML

+ 7 - 6
src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java

@@ -9,9 +9,9 @@ import org.cryptomator.cryptofs.DirStructure;
 import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
 import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.VaultService;
+import org.cryptomator.ui.dialogs.Dialogs;
 import org.cryptomator.ui.fxapp.FxApplicationWindows;
 import org.cryptomator.ui.preferences.SelectedPreferencesTab;
-import org.cryptomator.ui.removevault.RemoveVaultComponent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -66,12 +66,13 @@ public class VaultListController implements FxController {
 	private final VaultListCellFactory cellFactory;
 	private final AddVaultWizardComponent.Builder addVaultWizard;
 	private final BooleanBinding emptyVaultList;
-	private final RemoveVaultComponent.Builder removeVaultDialogue;
 	private final VaultListManager vaultListManager;
 	private final BooleanProperty draggingVaultOver = new SimpleBooleanProperty();
 	private final ResourceBundle resourceBundle;
 	private final FxApplicationWindows appWindows;
 	private final ObservableValue<Double> cellSize;
+	private final Dialogs dialogs;
+
 	public ListView<Vault> vaultList;
 	public StackPane root;
 	@FXML
@@ -86,21 +87,21 @@ public class VaultListController implements FxController {
 						VaultListCellFactory cellFactory, //
 						VaultService vaultService, //
 						AddVaultWizardComponent.Builder addVaultWizard, //
-						RemoveVaultComponent.Builder removeVaultDialogue, //
 						VaultListManager vaultListManager, //
 						ResourceBundle resourceBundle, //
 						FxApplicationWindows appWindows, //
-						Settings settings) {
+						Settings settings, //
+						Dialogs dialogs) {
 		this.mainWindow = mainWindow;
 		this.vaults = vaults;
 		this.selectedVault = selectedVault;
 		this.cellFactory = cellFactory;
 		this.vaultService = vaultService;
 		this.addVaultWizard = addVaultWizard;
-		this.removeVaultDialogue = removeVaultDialogue;
 		this.vaultListManager = vaultListManager;
 		this.resourceBundle = resourceBundle;
 		this.appWindows = appWindows;
+		this.dialogs = dialogs;
 
 		this.emptyVaultList = Bindings.isEmpty(vaults);
 
@@ -212,7 +213,7 @@ public class VaultListController implements FxController {
 	private void pressedShortcutToRemoveVault() {
 		final var vault = selectedVault.get();
 		if (vault != null && EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION).contains(vault.getState())) {
-			removeVaultDialogue.vault(vault).build().showRemoveVault();
+			dialogs.prepareRemoveVaultDialog(mainWindow, vault, vaults).build().showAndWait();
 		}
 	}
 

+ 11 - 5
src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java

@@ -5,7 +5,7 @@ import org.cryptomator.common.LicenseHolder;
 import org.cryptomator.common.settings.Settings;
 import org.cryptomator.common.settings.UiTheme;
 import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.removecert.RemoveCertComponent;
+import org.cryptomator.ui.dialogs.Dialogs;
 
 import javax.inject.Inject;
 import javafx.application.Application;
@@ -15,6 +15,7 @@ import javafx.scene.control.TextArea;
 import javafx.scene.control.TextFormatter;
 import javafx.stage.Stage;
 
+
 @PreferencesScoped
 public class SupporterCertificateController implements FxController {
 
@@ -26,18 +27,22 @@ public class SupporterCertificateController implements FxController {
 	private final Stage window;
 	private final LicenseHolder licenseHolder;
 	private final Settings settings;
-	private final RemoveCertComponent.Builder removeCert;
+	private final Dialogs dialogs;
 
 	@FXML
 	private TextArea supporterCertificateField;
 
 	@Inject
-	SupporterCertificateController(Application application, @PreferencesWindow Stage window, LicenseHolder licenseHolder, Settings settings, RemoveCertComponent.Builder removeCert) {
+	SupporterCertificateController(Application application, //
+								   @PreferencesWindow Stage window,  //
+								   LicenseHolder licenseHolder, //
+								   Settings settings, //
+								   Dialogs dialogs) {
 		this.application = application;
 		this.window = window;
 		this.licenseHolder = licenseHolder;
 		this.settings = settings;
-		this.removeCert = removeCert;
+		this.dialogs = dialogs;
 	}
 
 	@FXML
@@ -84,10 +89,11 @@ public class SupporterCertificateController implements FxController {
 
 	@FXML
 	void didClickRemoveCert() {
-		removeCert.build().showRemoveCert(window);
+		dialogs.prepareRemoveCertDialog(window, settings).build().showAndWait();
 	}
 
 	public LicenseHolder getLicenseHolder() {
 		return licenseHolder;
 	}
+
 }

+ 0 - 34
src/main/java/org/cryptomator/ui/removecert/RemoveCertComponent.java

@@ -1,34 +0,0 @@
-package org.cryptomator.ui.removecert;
-
-import dagger.Lazy;
-import dagger.Subcomponent;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlScene;
-
-import javafx.scene.Scene;
-import javafx.stage.Stage;
-
-@RemoveCertScoped
-@Subcomponent(modules = {RemoveCertModule.class})
-public interface RemoveCertComponent {
-
-	@RemoveCertWindow
-	Stage window();
-
-	@FxmlScene(FxmlFile.REMOVE_CERT)
-	Lazy<Scene> scene();
-
-	default void showRemoveCert(Stage owner) {
-		Stage stage = window();
-		stage.setScene(scene().get());
-		stage.sizeToScene();
-		stage.initOwner(owner);
-		stage.show();
-	}
-
-	@Subcomponent.Builder
-	interface Builder {
-		RemoveCertComponent build();
-	}
-
-}

+ 0 - 32
src/main/java/org/cryptomator/ui/removecert/RemoveCertController.java

@@ -1,32 +0,0 @@
-package org.cryptomator.ui.removecert;
-
-import org.cryptomator.common.settings.Settings;
-import org.cryptomator.ui.common.FxController;
-
-import javax.inject.Inject;
-import javafx.fxml.FXML;
-import javafx.stage.Stage;
-
-@RemoveCertScoped
-public class RemoveCertController implements FxController {
-
-	private final Stage window;
-	private final Settings settings;
-
-	@Inject
-	public RemoveCertController(@RemoveCertWindow Stage window, Settings settings) {
-		this.window = window;
-		this.settings = settings;
-	}
-
-	@FXML
-	public void close() {
-		window.close();
-	}
-
-	@FXML
-	public void remove() {
-		settings.licenseKey.set(null);
-		window.close();
-	}
-}

+ 0 - 56
src/main/java/org/cryptomator/ui/removecert/RemoveCertModule.java

@@ -1,56 +0,0 @@
-package org.cryptomator.ui.removecert;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoMap;
-import org.cryptomator.ui.common.DefaultSceneFactory;
-import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.common.FxControllerKey;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlLoaderFactory;
-import org.cryptomator.ui.common.FxmlScene;
-import org.cryptomator.ui.common.StageFactory;
-
-import javax.inject.Provider;
-import javafx.scene.Scene;
-import javafx.stage.Modality;
-import javafx.stage.Stage;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-@Module
-abstract class RemoveCertModule {
-
-	@Provides
-	@RemoveCertWindow
-	@RemoveCertScoped
-	static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
-		return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
-	}
-
-	@Provides
-	@RemoveCertWindow
-	@RemoveCertScoped
-	static Stage provideStage(StageFactory factory, ResourceBundle resourceBundle) {
-		Stage stage = factory.create();
-		stage.setTitle(resourceBundle.getString("removeCert.title"));
-		stage.setResizable(false);
-		stage.initModality(Modality.WINDOW_MODAL);
-		return stage;
-	}
-
-	@Provides
-	@FxmlScene(FxmlFile.REMOVE_CERT)
-	@RemoveCertScoped
-	static Scene provideRemoveCertScene(@RemoveCertWindow FxmlLoaderFactory fxmlLoaders) {
-		return fxmlLoaders.createScene(FxmlFile.REMOVE_CERT);
-	}
-
-	// ------------------
-
-	@Binds
-	@IntoMap
-	@FxControllerKey(RemoveCertController.class)
-	abstract FxController bindRemoveCertController(RemoveCertController controller);
-}

+ 0 - 13
src/main/java/org/cryptomator/ui/removecert/RemoveCertScoped.java

@@ -1,13 +0,0 @@
-package org.cryptomator.ui.removecert;
-
-import javax.inject.Scope;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-@Scope
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-public @interface RemoveCertScoped {
-
-}

+ 0 - 14
src/main/java/org/cryptomator/ui/removecert/RemoveCertWindow.java

@@ -1,14 +0,0 @@
-package org.cryptomator.ui.removecert;
-
-import javax.inject.Qualifier;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-@interface RemoveCertWindow {
-
-}

+ 0 - 39
src/main/java/org/cryptomator/ui/removevault/RemoveVaultComponent.java

@@ -1,39 +0,0 @@
-package org.cryptomator.ui.removevault;
-
-import dagger.BindsInstance;
-import dagger.Lazy;
-import dagger.Subcomponent;
-import org.cryptomator.common.vaults.Vault;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlScene;
-
-import javafx.scene.Scene;
-import javafx.stage.Stage;
-
-@RemoveVaultScoped
-@Subcomponent(modules = {RemoveVaultModule.class})
-public interface RemoveVaultComponent {
-
-	@RemoveVaultWindow
-	Stage window();
-
-	@FxmlScene(FxmlFile.REMOVE_VAULT)
-	Lazy<Scene> scene();
-
-	default void showRemoveVault() {
-		Stage stage = window();
-		stage.setScene(scene().get());
-		stage.sizeToScene();
-		stage.show();
-	}
-
-	@Subcomponent.Builder
-	interface Builder {
-
-		@BindsInstance
-		Builder vault(@RemoveVaultWindow Vault vault);
-
-		RemoveVaultComponent build();
-	}
-
-}

+ 0 - 40
src/main/java/org/cryptomator/ui/removevault/RemoveVaultController.java

@@ -1,40 +0,0 @@
-package org.cryptomator.ui.removevault;
-
-import org.cryptomator.common.vaults.Vault;
-import org.cryptomator.ui.common.FxController;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
-import javafx.collections.ObservableList;
-import javafx.fxml.FXML;
-import javafx.stage.Stage;
-
-@RemoveVaultScoped
-public class RemoveVaultController implements FxController {
-
-	private static final Logger LOG = LoggerFactory.getLogger(RemoveVaultController.class);
-
-	private final Stage window;
-	private final Vault vault;
-	private final ObservableList<Vault> vaults;
-
-	@Inject
-	public RemoveVaultController(@RemoveVaultWindow Stage window, @RemoveVaultWindow Vault vault, ObservableList<Vault> vaults) {
-		this.window = window;
-		this.vault = vault;
-		this.vaults = vaults;
-	}
-
-	@FXML
-	public void close() {
-		window.close();
-	}
-
-	@FXML
-	public void finish() {
-		vaults.remove(vault);
-		LOG.debug("Removing vault {}.", vault.getDisplayName());
-		window.close();
-	}
-}

+ 0 - 59
src/main/java/org/cryptomator/ui/removevault/RemoveVaultModule.java

@@ -1,59 +0,0 @@
-package org.cryptomator.ui.removevault;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoMap;
-import org.cryptomator.common.vaults.Vault;
-import org.cryptomator.ui.common.DefaultSceneFactory;
-import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.common.FxControllerKey;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlLoaderFactory;
-import org.cryptomator.ui.common.FxmlScene;
-import org.cryptomator.ui.common.StageFactory;
-import org.cryptomator.ui.fxapp.PrimaryStage;
-
-import javax.inject.Provider;
-import javafx.scene.Scene;
-import javafx.stage.Modality;
-import javafx.stage.Stage;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-@Module
-abstract class RemoveVaultModule {
-
-	@Provides
-	@RemoveVaultWindow
-	@RemoveVaultScoped
-	static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
-		return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
-	}
-
-	@Provides
-	@RemoveVaultWindow
-	@RemoveVaultScoped
-	static Stage provideStage(StageFactory factory, @PrimaryStage Stage primaryStage, @RemoveVaultWindow Vault vault, ResourceBundle resourceBundle) {
-		Stage stage = factory.create();
-		stage.setTitle(String.format(resourceBundle.getString("removeVault.title"), vault.getDisplayName()));
-		stage.setResizable(false);
-		stage.initModality(Modality.WINDOW_MODAL);
-		stage.initOwner(primaryStage);
-		return stage;
-	}
-
-	@Provides
-	@FxmlScene(FxmlFile.REMOVE_VAULT)
-	@RemoveVaultScoped
-	static Scene provideRemoveVaultScene(@RemoveVaultWindow FxmlLoaderFactory fxmlLoaders) {
-		return fxmlLoaders.createScene(FxmlFile.REMOVE_VAULT);
-	}
-
-	// ------------------
-
-	@Binds
-	@IntoMap
-	@FxControllerKey(RemoveVaultController.class)
-	abstract FxController bindRemoveVaultController(RemoveVaultController controller);
-}

+ 0 - 13
src/main/java/org/cryptomator/ui/removevault/RemoveVaultScoped.java

@@ -1,13 +0,0 @@
-package org.cryptomator.ui.removevault;
-
-import javax.inject.Scope;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-@Scope
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-public @interface RemoveVaultScoped {
-
-}

+ 0 - 14
src/main/java/org/cryptomator/ui/removevault/RemoveVaultWindow.java

@@ -1,14 +0,0 @@
-package org.cryptomator.ui.removevault;
-
-import javax.inject.Qualifier;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-@interface RemoveVaultWindow {
-
-}

+ 0 - 53
src/main/resources/fxml/dokany_support_end.fxml

@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
-<?import javafx.geometry.Insets?>
-<?import javafx.scene.control.Button?>
-<?import javafx.scene.control.ButtonBar?>
-<?import javafx.scene.control.Label?>
-<?import javafx.scene.Group?>
-<?import javafx.scene.layout.HBox?>
-<?import javafx.scene.layout.Region?>
-<?import javafx.scene.layout.StackPane?>
-<?import javafx.scene.layout.VBox?>
-<?import javafx.scene.shape.Circle?>
-<HBox xmlns:fx="http://javafx.com/fxml"
-	  xmlns="http://javafx.com/javafx"
-	  fx:controller="org.cryptomator.ui.dokanysupportend.DokanySupportEndController"
-	  minWidth="500"
-	  prefWidth="500"
-	  minHeight="145"
-	  spacing="12"
-	  alignment="TOP_LEFT">
-	<padding>
-		<Insets topRightBottomLeft="12"/>
-	</padding>
-	<children>
-		<Group>
-			<StackPane>
-				<padding>
-					<Insets topRightBottomLeft="6"/>
-				</padding>
-				<Circle styleClass="glyph-icon-primary" radius="24"/>
-				<FontAwesome5IconView styleClass="glyph-icon-white" glyph="EXCLAMATION" glyphSize="24"/>
-			</StackPane>
-		</Group>
-
-		<VBox HBox.hgrow="ALWAYS">
-			<Label styleClass="label-large" text="%dokanySupportEnd.message" wrapText="true">
-				<padding>
-					<Insets bottom="6" top="6"/>
-				</padding>
-			</Label>
-			<Label text="%dokanySupportEnd.description" wrapText="true"/>
-			<Region VBox.vgrow="ALWAYS" minHeight="18"/>
-			<ButtonBar buttonMinWidth="120" buttonOrder="+UC">
-				<buttons>
-					<Button text="%dokanySupportEnd.preferencesBtn" ButtonBar.buttonData="OTHER" cancelButton="true" onAction="#openVolumePreferences"/>
-					<Button text="%generic.button.close" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close" defaultButton="true"/>
-				</buttons>
-			</ButtonBar>
-
-		</VBox>
-	</children>
-</HBox>

+ 0 - 52
src/main/resources/fxml/remove_vault.fxml

@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
-<?import javafx.geometry.Insets?>
-<?import javafx.scene.control.Button?>
-<?import javafx.scene.control.ButtonBar?>
-<?import javafx.scene.control.Label?>
-<?import javafx.scene.layout.HBox?>
-<?import javafx.scene.layout.StackPane?>
-<?import javafx.scene.layout.VBox?>
-<?import javafx.scene.shape.Circle?>
-<?import javafx.scene.Group?>
-<?import javafx.scene.layout.Region?>
-<HBox xmlns:fx="http://javafx.com/fxml"
-	  xmlns="http://javafx.com/javafx"
-	  fx:controller="org.cryptomator.ui.removevault.RemoveVaultController"
-	  minWidth="400"
-	  maxWidth="400"
-	  minHeight="145"
-	  spacing="12"
-	  alignment="TOP_LEFT">
-	<padding>
-		<Insets topRightBottomLeft="12"/>
-	</padding>
-	<children>
-		<Group>
-			<StackPane>
-				<padding>
-					<Insets topRightBottomLeft="6"/>
-				</padding>
-				<Circle styleClass="glyph-icon-primary" radius="24"/>
-				<FontAwesome5IconView styleClass="glyph-icon-white" glyph="QUESTION" glyphSize="24"/>
-			</StackPane>
-		</Group>
-		<VBox HBox.hgrow="ALWAYS">
-			<Label styleClass="label-large" text="%removeVault.message" wrapText="true" textAlignment="LEFT">
-				<padding>
-					<Insets bottom="6" top="6"/>
-				</padding>
-			</Label>
-			<Label text="%removeVault.description" wrapText="true" textAlignment="LEFT" />
-
-			<Region VBox.vgrow="ALWAYS" minHeight="18"/>
-			<ButtonBar buttonMinWidth="120" buttonOrder="+CI">
-				<buttons>
-					<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" defaultButton="true" cancelButton="true" onAction="#close"/>
-					<Button text="%generic.button.remove" ButtonBar.buttonData="FINISH" onAction="#finish"/>
-				</buttons>
-			</ButtonBar>
-		</VBox>
-	</children>
-</HBox>

+ 13 - 14
src/main/resources/fxml/remove_cert.fxml

@@ -1,19 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
-<?import javafx.geometry.Insets?>
-<?import javafx.scene.control.Button?>
-<?import javafx.scene.control.ButtonBar?>
 <?import javafx.scene.control.Label?>
 <?import javafx.scene.layout.HBox?>
+<?import javafx.scene.control.Button?>
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.Group?>
 <?import javafx.scene.layout.StackPane?>
-<?import javafx.scene.layout.VBox?>
 <?import javafx.scene.shape.Circle?>
-<?import javafx.scene.Group?>
+<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
+<?import javafx.scene.layout.VBox?>
 <?import javafx.scene.layout.Region?>
+<?import javafx.scene.control.ButtonBar?>
 <HBox xmlns:fx="http://javafx.com/fxml"
 	  xmlns="http://javafx.com/javafx"
-	  fx:controller="org.cryptomator.ui.removecert.RemoveCertController"
+	  fx:controller="org.cryptomator.ui.dialogs.SimpleDialogController"
 	  minWidth="400"
 	  maxWidth="400"
 	  minHeight="145"
@@ -28,24 +28,23 @@
 					<Insets topRightBottomLeft="6"/>
 				</padding>
 				<Circle styleClass="glyph-icon-primary" radius="24"/>
-				<FontAwesome5IconView styleClass="glyph-icon-white" glyph="QUESTION" glyphSize="24"/>
+				<FontAwesome5IconView glyph="${controller.icon}" styleClass="glyph-icon-white" glyphSize="24"/>
 			</StackPane>
 		</Group>
 		<VBox HBox.hgrow="ALWAYS">
-			<Label styleClass="label-large" text="%removeCert.message" wrapText="true" >
+			<Label text="${controller.message}" styleClass="label-large" wrapText="true">
 				<padding>
 					<Insets bottom="6" top="6"/>
 				</padding>
 			</Label>
-			<Label text="%removeCert.description" wrapText="true" />
-
+			<Label text="${controller.description}" wrapText="true"/>
 			<Region VBox.vgrow="ALWAYS" minHeight="18"/>
 			<ButtonBar buttonMinWidth="120" buttonOrder="+CI">
 				<buttons>
-					<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" defaultButton="true" cancelButton="true" onAction="#close"/>
-					<Button text="%generic.button.remove" ButtonBar.buttonData="FINISH" onAction="#remove"/>
+					<Button text="${controller.cancelButtonText}" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#handleCancel"/>
+					<Button text="${controller.okButtonText}" ButtonBar.buttonData="FINISH" defaultButton="true" onAction="#handleOk"/>
 				</buttons>
 			</ButtonBar>
 		</VBox>
 	</children>
-</HBox>
+</HBox>