diff --git a/src/main/java/de/bixilon/minosoft/config/profile/ProfileManager.kt b/src/main/java/de/bixilon/minosoft/config/profile/ProfileManager.kt index 2bcf1c587..401bc0573 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/ProfileManager.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/ProfileManager.kt @@ -127,6 +127,43 @@ interface ProfileManager { } + fun deleteAsync(profile: T) { + if (saveLock.isLocked) { + return + } + DefaultThreadPool += { delete(profile) } + } + + fun canDelete(profile: T): Boolean { + return profiles.size > 1 + } + + fun delete(profile: T) { + saveLock.lock() + if (!canDelete(profile)) { + throw IllegalStateException("Can not delete $profile") + } + try { + val name = profile.name + profiles.remove(name) + if (selected == profile) { + selected = profiles.iterator().next().value + } + val file = File(getPath(profile.name)) + if (file.exists()) { + if (!file.delete() || file.exists()) { + throw IOException("Can not delete $file") + } + } + // ToDo: FileWatcherService.unregister(file) + } catch (exception: Exception) { + exception.printStackTrace() + exception.crash() + } finally { + saveLock.unlock() + } + } + fun saveAsync(profile: T) { if (saveLock.isLocked) { return diff --git a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt index 9d21b2e97..f96ca99e8 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt @@ -16,6 +16,7 @@ import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager import de.bixilon.minosoft.data.text.events.ClickEvent import de.bixilon.minosoft.data.text.events.HoverEvent import de.bixilon.minosoft.gui.eros.dialog.ErosErrorReport.Companion.report +import de.bixilon.minosoft.gui.eros.util.JavaFXUtil.file import de.bixilon.minosoft.gui.eros.util.JavaFXUtil.hyperlink import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.util.KUtil.toSynchronizedSet @@ -185,6 +186,7 @@ open class TextComponent( clickEvent?.let { event -> when (event.action) { ClickEvent.ClickEventActions.OPEN_URL -> text.hyperlink(event.value.toString()) + ClickEvent.ClickEventActions.OPEN_FILE -> text.file(event.value.toString()) else -> { NotImplementedError("Unknown action ${event.action}").report() return@let diff --git a/src/main/java/de/bixilon/minosoft/data/text/events/ClickEvent.kt b/src/main/java/de/bixilon/minosoft/data/text/events/ClickEvent.kt index ff8d4ac8b..8c494e4aa 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/events/ClickEvent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/events/ClickEvent.kt @@ -31,6 +31,7 @@ class ClickEvent { Util.checkURL(value.toString()) } check(action != ClickEventActions.OPEN_CONFIRMATION) { "Can not use OPEN_CONFIRMATION in restricted mode!" } + check(action != ClickEventActions.OPEN_FILE) { "Can not use OPEN_FILE in restricted mode!" } } constructor(action: ClickEventActions, value: Any) { @@ -54,6 +55,7 @@ class ClickEvent { SUGGEST_COMMAND, CHANGE_PAGE, OPEN_CONFIRMATION, + OPEN_FILE, ; companion object : ValuesEnum { diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/main/profiles/ProfilesListController.kt b/src/main/java/de/bixilon/minosoft/gui/eros/main/profiles/ProfilesListController.kt index 7a288d70f..cec25db0f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/main/profiles/ProfilesListController.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/main/profiles/ProfilesListController.kt @@ -18,9 +18,12 @@ import de.bixilon.minosoft.config.profile.ProfileManager import de.bixilon.minosoft.config.profile.profiles.Profile import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.data.text.TextComponent +import de.bixilon.minosoft.data.text.events.ClickEvent import de.bixilon.minosoft.gui.eros.controller.EmbeddedJavaFXController import de.bixilon.minosoft.gui.eros.dialog.SimpleErosConfirmationDialog import de.bixilon.minosoft.gui.eros.dialog.profiles.ProfileCreateDialog +import de.bixilon.minosoft.gui.eros.util.JavaFXUtil import de.bixilon.minosoft.util.KUtil.decide import de.bixilon.minosoft.util.KUtil.toResourceLocation import de.bixilon.minosoft.util.delegate.watcher.entry.MapDelegateWatcher.Companion.watchMapFX @@ -146,13 +149,19 @@ class ProfilesListController : EmbeddedJavaFXController() { it.columnConstraints += ColumnConstraints(0.0, -1.0, Double.POSITIVE_INFINITY, Priority.ALWAYS, HPos.LEFT, true) it.add(Button("Delete").apply { + isDisable = !profile.manager.canDelete(profile) setOnAction { SimpleErosConfirmationDialog(confirmButtonText = "minosoft:general.delete".toResourceLocation(), onConfirm = { - TODO("Not yet implemented") + profile.manager.deleteAsync(profile) + JavaFXUtil.runLater { + profilesListViewFX.items.remove(profile) + setProfileInfo(profilesListViewFX.selectionModel.selectedItem) + } }).show() } }, 0, 0) it.add(Button("Edit").apply { + // ToDo: Profile editing isDisable = true }, 1, 0) @@ -194,6 +203,13 @@ class ProfilesListController : EmbeddedJavaFXController() { private val PROFILE_INFO_PROPERTIES: List Any?>> = listOf( "minosoft:profiles.profile.name".toResourceLocation() to { it.name }, "minosoft:profiles.profile.description".toResourceLocation() to { it.description }, + + "minosoft:general.empty".toResourceLocation() to { " " }, + + "minosoft:profiles.profile.disk_path".toResourceLocation() to { + val path = it.manager.getPath(it.name) + TextComponent(it.manager.getPath(it.name), clickEvent = ClickEvent(ClickEvent.ClickEventActions.OPEN_FILE, path)) + }, ) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/util/JavaFXUtil.kt b/src/main/java/de/bixilon/minosoft/gui/eros/util/JavaFXUtil.kt index 44a772ea2..b8ceed666 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/util/JavaFXUtil.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/util/JavaFXUtil.kt @@ -114,6 +114,13 @@ object JavaFXUtil { this.clickable() } + fun Text.file(path: String) { + // ToDo: Open in file browser/default program + this.accessibleRole = AccessibleRole.HYPERLINK + this.styleClass.setAll("hyperlink") + this.clickable() + } + fun Node.clickable() { this.cursorProperty().unsafeCast>().applyStyle(null, Cursor.HAND) }