From cda10c54039d4784387c7f9229a74865a19e634b Mon Sep 17 00:00:00 2001
From: tobias <thinkdifferent055@gmail.com>
Date: Sat, 20 Nov 2021 18:01:22 +0100
Subject: [PATCH] #174 - Add settings section for remote playwall instances

---
 .../de/tobias/playpad/view/PseudoClasses.java |   2 -
 .../playpad/settings/GlobalSettings.java      |  14 +-
 .../api/settings/WebApiRemoteSettings.java    |  48 +++++++
 .../settings/WebApiSettings.java              |  15 +-
 .../plugin/webapi/lang/base_de.properties     |  16 ++-
 .../plugin/webapi/view/WebApiSettings.fxml    |  63 +++++++--
 .../playpad/plugin/api/WebApiPlugin.scala     |   6 +-
 .../WebApiSettingsViewController.scala        | 130 ++++++++++++++++++
 .../WebApiSettingsViewController.scala        |  81 -----------
 9 files changed, 262 insertions(+), 113 deletions(-)
 create mode 100644 PlayWallPlugins/PlayWallPluginWebAPI/src/main/java/de/tobias/playpad/plugin/api/settings/WebApiRemoteSettings.java
 rename PlayWallPlugins/PlayWallPluginWebAPI/src/main/java/de/tobias/playpad/plugin/api/{websocket => }/settings/WebApiSettings.java (55%)
 create mode 100644 PlayWallPlugins/PlayWallPluginWebAPI/src/main/scala/de/tobias/playpad/plugin/api/settings/WebApiSettingsViewController.scala
 delete mode 100644 PlayWallPlugins/PlayWallPluginWebAPI/src/main/scala/de/tobias/playpad/plugin/api/websocket/settings/WebApiSettingsViewController.scala

diff --git a/PlayWall/src/main/java/de/tobias/playpad/view/PseudoClasses.java b/PlayWall/src/main/java/de/tobias/playpad/view/PseudoClasses.java
index 3af53dd3..1a62b1c1 100644
--- a/PlayWall/src/main/java/de/tobias/playpad/view/PseudoClasses.java
+++ b/PlayWall/src/main/java/de/tobias/playpad/view/PseudoClasses.java
@@ -15,6 +15,4 @@ public class PseudoClasses {
 	public static final PseudoClass DRAG_CLASS = PseudoClass.getPseudoClass("drag");
 
 	public static final PseudoClass DEACTIVATED_CLASS = PseudoClass.getPseudoClass("deactivated");
-
-
 }
diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/settings/GlobalSettings.java b/PlayWallCore/src/main/java/de/tobias/playpad/settings/GlobalSettings.java
index 38d09edc..3ca3f35b 100644
--- a/PlayWallCore/src/main/java/de/tobias/playpad/settings/GlobalSettings.java
+++ b/PlayWallCore/src/main/java/de/tobias/playpad/settings/GlobalSettings.java
@@ -34,7 +34,7 @@ public class GlobalSettings {
 	private Path savePath;
 
 	// Key Binding
-	private KeyCollection keyCollection = new KeyCollection();
+	private final KeyCollection keyCollection = new KeyCollection();
 
 	// Update
 	private boolean autoUpdate = true;
@@ -114,13 +114,11 @@ public class GlobalSettings {
 		return openLastDocument;
 	}
 
-	public boolean isEnableAutosave()
-	{
+	public boolean isEnableAutosave() {
 		return enableAutosave;
 	}
 
-	public int getAutosaveIntervalInMinutes()
-	{
+	public int getAutosaveIntervalInMinutes() {
 		return autosaveIntervalInMinutes;
 	}
 
@@ -169,13 +167,11 @@ public class GlobalSettings {
 		this.openLastDocument = openLastDocument;
 	}
 
-	public void setEnableAutosave(boolean enableAutosave)
-	{
+	public void setEnableAutosave(boolean enableAutosave) {
 		this.enableAutosave = enableAutosave;
 	}
 
-	public void setAutosaveIntervalInMinutes(int autosaveIntervalInMinutes)
-	{
+	public void setAutosaveIntervalInMinutes(int autosaveIntervalInMinutes) {
 		this.autosaveIntervalInMinutes = autosaveIntervalInMinutes;
 	}
 
diff --git a/PlayWallPlugins/PlayWallPluginWebAPI/src/main/java/de/tobias/playpad/plugin/api/settings/WebApiRemoteSettings.java b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/java/de/tobias/playpad/plugin/api/settings/WebApiRemoteSettings.java
new file mode 100644
index 00000000..40c5d72a
--- /dev/null
+++ b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/java/de/tobias/playpad/plugin/api/settings/WebApiRemoteSettings.java
@@ -0,0 +1,48 @@
+package de.tobias.playpad.plugin.api.settings;
+
+import de.thecodelabs.storage.settings.annotation.Key;
+import de.tobias.playpad.Displayable;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+public class WebApiRemoteSettings implements Displayable {
+	@Key
+	private String name;
+	@Key
+	private String serverAddress;
+	@Key
+	private int port;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+		displayProperty.set(name);
+	}
+
+	public String getServerAddress() {
+		return serverAddress;
+	}
+
+	public void setServerAddress(String serverAddress) {
+		this.serverAddress = serverAddress;
+	}
+
+	public int getPort() {
+		return port;
+	}
+
+	public void setPort(int port) {
+		this.port = port;
+	}
+
+	private final StringProperty displayProperty = new SimpleStringProperty();
+
+	@Override
+	public StringProperty displayProperty() {
+		displayProperty.set(name);
+		return displayProperty;
+	}
+}
diff --git a/PlayWallPlugins/PlayWallPluginWebAPI/src/main/java/de/tobias/playpad/plugin/api/websocket/settings/WebApiSettings.java b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/java/de/tobias/playpad/plugin/api/settings/WebApiSettings.java
similarity index 55%
rename from PlayWallPlugins/PlayWallPluginWebAPI/src/main/java/de/tobias/playpad/plugin/api/websocket/settings/WebApiSettings.java
rename to PlayWallPlugins/PlayWallPluginWebAPI/src/main/java/de/tobias/playpad/plugin/api/settings/WebApiSettings.java
index c5b35f5f..0d34d964 100644
--- a/PlayWallPlugins/PlayWallPluginWebAPI/src/main/java/de/tobias/playpad/plugin/api/websocket/settings/WebApiSettings.java
+++ b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/java/de/tobias/playpad/plugin/api/settings/WebApiSettings.java
@@ -1,14 +1,19 @@
-package de.tobias.playpad.plugin.api.websocket.settings;
+package de.tobias.playpad.plugin.api.settings;
 
 import de.thecodelabs.storage.settings.annotation.FilePath;
 import de.thecodelabs.storage.settings.annotation.Key;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @FilePath("webapi.json")
 public class WebApiSettings {
 	@Key
 	private boolean enabled = false;
 	@Key
 	private int port = 9876;
+	@Key
+	private List<WebApiRemoteSettings> remoteSettings = new ArrayList<>();
 
 	public boolean isEnabled() {
 		return enabled;
@@ -25,4 +30,12 @@ public class WebApiSettings {
 	public void setPort(int port) {
 		this.port = port;
 	}
+
+	public List<WebApiRemoteSettings> getRemoteSettings() {
+		return remoteSettings;
+	}
+
+	public void setRemoteSettings(List<WebApiRemoteSettings> remoteSettings) {
+		this.remoteSettings = remoteSettings;
+	}
 }
diff --git a/PlayWallPlugins/PlayWallPluginWebAPI/src/main/resources/plugin/webapi/lang/base_de.properties b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/resources/plugin/webapi/lang/base_de.properties
index 0b7b9cf8..7a95dbf9 100644
--- a/PlayWallPlugins/PlayWallPluginWebAPI/src/main/resources/plugin/webapi/lang/base_de.properties
+++ b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/resources/plugin/webapi/lang/base_de.properties
@@ -1,5 +1,13 @@
 webapi.settings=WebAPI
-webapi.settings.enable=WebAPI
-webapi.settings.enabled=Aktiv
-webapi.settings.port=Port
-webapi.settings.restart=\u00C4nderungen an den Einstellungen werden erst mit einem Neustart von PlayWall wirksam.
\ No newline at end of file
+webapi-settings.server=Fernsteuerung
+webapi.settings.server.enable=WebAPI
+webapi.settings.server.enabled=Aktiv
+webapi.settings.server.port=Port
+webapi.settings.server.restart=\u00C4nderungen an den Einstellungen werden erst mit einem Neustart von PlayWall wirksam.
+
+webapi-settings.remote=PlayWall Instanzen fernsteuern
+webapi-settings.remote.name=Name
+webapi-settings.remote.address=IP-Address/Host
+webapi-settings.remote.port=Port
+webapi-settings.remote.add=Hinzuf\u00FCgen
+webapi-settings.remote.remove=L\u00F6schen
diff --git a/PlayWallPlugins/PlayWallPluginWebAPI/src/main/resources/plugin/webapi/view/WebApiSettings.fxml b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/resources/plugin/webapi/view/WebApiSettings.fxml
index 473dba8d..affd019e 100644
--- a/PlayWallPlugins/PlayWallPluginWebAPI/src/main/resources/plugin/webapi/view/WebApiSettings.fxml
+++ b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/resources/plugin/webapi/view/WebApiSettings.fxml
@@ -2,32 +2,69 @@
 
 <?import de.thecodelabs.utils.ui.scene.input.NumberTextField?>
 <?import javafx.geometry.Insets?>
-<?import javafx.scene.control.CheckBox?>
-<?import javafx.scene.control.Label?>
-<?import javafx.scene.layout.HBox?>
-<?import javafx.scene.layout.VBox?>
-<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="14.0"
-      xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="14.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1">
     <children>
+        <Label text="%webapi-settings.server" underline="true" />
         <HBox alignment="CENTER_LEFT" spacing="14.0">
             <children>
-                <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%webapi.settings.enable"/>
-                <CheckBox fx:id="activeCheckbox" mnemonicParsing="false" text="%webapi.settings.enabled"/>
+                <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%webapi.settings.server.enable" />
+                <CheckBox fx:id="activeCheckbox" mnemonicParsing="false" text="%webapi.settings.server.enabled" />
             </children>
         </HBox>
         <HBox alignment="CENTER_LEFT" spacing="14.0">
             <children>
-                <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%webapi.settings.port"/>
-                <NumberTextField fx:id="portTextField"/>
+                <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%webapi.settings.server.port" />
+                <NumberTextField fx:id="portTextField" />
             </children>
         </HBox>
-        <Label text="%webapi.settings.restart">
+        <Label text="%webapi.settings.server.restart">
             <padding>
-                <Insets left="164.0"/>
+                <Insets left="164.0" />
             </padding>
         </Label>
+      <Separator prefWidth="200.0" />
+      <Label text="%webapi-settings.remote" underline="true" />
+      <HBox spacing="14.0" VBox.vgrow="ALWAYS">
+         <children>
+            <VBox spacing="14.0">
+               <children>
+                  <ListView fx:id="remoteListView" VBox.vgrow="ALWAYS" />
+                  <HBox spacing="14.0">
+                     <children>
+                        <Button fx:id="remoteAddButton" onAction="#onRemoteAddButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="%webapi-settings.remote.add" HBox.hgrow="ALWAYS" />
+                        <Button fx:id="remoteDeleteButton" onAction="#onRemoteDeleteButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="%webapi-settings.remote.remove" HBox.hgrow="ALWAYS" />
+                     </children>
+                  </HBox>
+               </children>
+            </VBox>
+            <VBox spacing="14.0">
+               <children>
+                  <HBox alignment="CENTER_LEFT" spacing="14.0">
+                     <children>
+                        <Label alignment="CENTER_RIGHT" prefWidth="100.0" text="%webapi-settings.remote.name" />
+                        <TextField fx:id="remoteNameTextField" />
+                     </children>
+                  </HBox>
+                  <HBox alignment="CENTER_LEFT" spacing="14.0">
+                     <children>
+                        <Label alignment="CENTER_RIGHT" prefWidth="100.0" text="%webapi-settings.remote.address" />
+                        <TextField fx:id="remoteAddressTextField" />
+                     </children>
+                  </HBox>
+                  <HBox alignment="CENTER_LEFT" spacing="14.0">
+                     <children>
+                        <Label alignment="CENTER_RIGHT" prefWidth="100.0" text="%webapi-settings.remote.port" />
+                        <NumberTextField fx:id="remotePortTextField" />
+                     </children>
+                  </HBox>
+               </children>
+            </VBox>
+         </children>
+      </HBox>
     </children>
     <padding>
-        <Insets bottom="14.0" left="14.0" right="14.0" top="14.0"/>
+        <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
     </padding>
 </VBox>
diff --git a/PlayWallPlugins/PlayWallPluginWebAPI/src/main/scala/de/tobias/playpad/plugin/api/WebApiPlugin.scala b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/scala/de/tobias/playpad/plugin/api/WebApiPlugin.scala
index 0d4d7321..986fd6bb 100644
--- a/PlayWallPlugins/PlayWallPluginWebAPI/src/main/scala/de/tobias/playpad/plugin/api/WebApiPlugin.scala
+++ b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/scala/de/tobias/playpad/plugin/api/WebApiPlugin.scala
@@ -1,7 +1,5 @@
 package de.tobias.playpad.plugin.api
 
-import java.nio.file.{Files, Path}
-
 import de.thecodelabs.logger.Logger
 import de.thecodelabs.plugins.PluginDescriptor
 import de.thecodelabs.plugins.versionizer.PluginArtifact
@@ -10,12 +8,14 @@ import de.thecodelabs.utils.application.ApplicationUtils
 import de.thecodelabs.utils.application.container.PathType
 import de.thecodelabs.utils.util.Localization
 import de.tobias.playpad.PlayPadPlugin
+import de.tobias.playpad.plugin.api.settings.{WebApiSettings, WebApiSettingsViewController}
 import de.tobias.playpad.plugin.api.websocket.WebSocketHandler
 import de.tobias.playpad.plugin.api.websocket.listener.{PadStatusListener, ProjectListener}
-import de.tobias.playpad.plugin.api.websocket.settings.{WebApiSettings, WebApiSettingsViewController}
 import de.tobias.playpad.plugin.{Module, PlayPadPluginStub}
 import spark.{Request, Response, Spark}
 
+import java.nio.file.{Files, Path}
+
 class WebApiPlugin extends PlayPadPluginStub with PluginArtifact {
 
 	private var module: Module = _
diff --git a/PlayWallPlugins/PlayWallPluginWebAPI/src/main/scala/de/tobias/playpad/plugin/api/settings/WebApiSettingsViewController.scala b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/scala/de/tobias/playpad/plugin/api/settings/WebApiSettingsViewController.scala
new file mode 100644
index 00000000..2cf3262c
--- /dev/null
+++ b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/scala/de/tobias/playpad/plugin/api/settings/WebApiSettingsViewController.scala
@@ -0,0 +1,130 @@
+package de.tobias.playpad.plugin.api.settings
+
+import de.thecodelabs.logger.Logger
+import de.thecodelabs.storage.settings.{Storage, StorageTypes}
+import de.thecodelabs.utils.ui.scene.input.NumberTextField
+import de.thecodelabs.utils.util.Localization
+import de.tobias.playpad.plugin.api.WebApiPlugin
+import de.tobias.playpad.settings.GlobalSettings
+import de.tobias.playpad.viewcontroller.option.GlobalSettingsTabViewController
+import javafx.event.ActionEvent
+import javafx.fxml.FXML
+import javafx.scene.control._
+
+import java.nio.file.Files
+
+class WebApiSettingsViewController(val webApiSettings: WebApiSettings) extends GlobalSettingsTabViewController {
+
+	load("plugin/webapi/view", "WebApiSettings", Localization.getBundle)
+
+	@FXML
+	var activeCheckbox: CheckBox = _
+
+	@FXML
+	var portTextField: NumberTextField = _
+
+	@FXML var remoteListView: ListView[WebApiRemoteSettings] = _
+	@FXML var remoteAddButton: Button = _
+	@FXML var remoteDeleteButton: Button = _
+	@FXML var remoteNameTextField: TextField = _
+	@FXML var remoteAddressTextField: TextField = _
+	@FXML var remotePortTextField: NumberTextField = _
+
+	override def init(): Unit = {
+		remoteListView.getItems.setAll(webApiSettings.getRemoteSettings)
+		remoteDeleteButton.disableProperty().bind(remoteListView.getSelectionModel.selectedItemProperty().isNull)
+
+		remoteListView.setCellFactory((_: ListView[WebApiRemoteSettings]) => new ListCell[WebApiRemoteSettings] {
+			override def updateItem(item: WebApiRemoteSettings, empty: Boolean): Unit = {
+				super.updateItem(item, empty)
+				if (!empty) {
+					textProperty().bind(item.displayProperty())
+				} else {
+					textProperty().unbind()
+					setText("")
+				}
+			}
+		})
+		remoteListView.getSelectionModel.selectedItemProperty().addListener((_, oldValue, newValue) => {
+			if (oldValue != null) {
+				saveSettingsToRemoteList(oldValue)
+			}
+			if (newValue != null) {
+				showRemoteConfiguration(newValue)
+			} else {
+				clearTextFields()
+			}
+		})
+	}
+
+	private def saveSettingsToRemoteList(remote: WebApiRemoteSettings): Unit = {
+		remote.setName(remoteNameTextField.getText)
+		remote.setServerAddress(remoteAddressTextField.getText)
+		remote.setPort(remotePortTextField.getText.toInt)
+	}
+
+
+	private def showRemoteConfiguration(remote: WebApiRemoteSettings): Unit = {
+		remoteNameTextField.setText(remote.getName)
+		remoteAddressTextField.setText(remote.getServerAddress)
+		remotePortTextField.setText(remote.getPort.toString)
+	}
+
+	private def clearTextFields(): Unit = {
+		remoteNameTextField.setText("")
+		remoteAddressTextField.setText("")
+		remotePortTextField.setText("")
+	}
+
+	@FXML def onRemoteAddButton(event: ActionEvent): Unit = {
+		val remoteSettings = new WebApiRemoteSettings()
+		remoteSettings.setName("Default")
+		webApiSettings.getRemoteSettings.add(remoteSettings)
+
+		remoteListView.getItems.add(remoteSettings)
+	}
+
+	@FXML def onRemoteDeleteButton(event: ActionEvent): Unit = {
+		val selectedItem = remoteListView.getSelectionModel.getSelectedItem
+		if (selectedItem != null) {
+			remoteListView.getItems.remove(selectedItem)
+			webApiSettings.getRemoteSettings.remove(selectedItem)
+		}
+	}
+
+	override def loadSettings(settings: GlobalSettings): Unit = {
+		activeCheckbox.setSelected(webApiSettings.isEnabled)
+		portTextField.setText(webApiSettings.getPort.toString)
+	}
+
+	override def saveSettings(settings: GlobalSettings): Unit = {
+		webApiSettings.setEnabled(activeCheckbox.isSelected)
+		webApiSettings.setPort(portTextField.getText.toInt)
+
+		val selectedItem = remoteListView.getSelectionModel.getSelectedItem
+		if (selectedItem != null) {
+			saveSettingsToRemoteList(selectedItem)
+		}
+
+		saveToFile()
+	}
+
+	override def needReload(): Boolean = {
+		false
+	}
+
+	override def validSettings(): Boolean = {
+		true
+	}
+
+	override def name(): String = Localization.getString("webapi.settings")
+
+	private def saveToFile(): Unit = {
+		val settingsPath = WebApiPlugin.getWebApiSettingsPath
+		if (Files.notExists(settingsPath)) {
+			Files.createDirectories(settingsPath.getParent)
+		}
+		Storage.save(StorageTypes.JSON, webApiSettings)
+		Logger.info(f"Save WebAPI settings to $settingsPath")
+	}
+}
diff --git a/PlayWallPlugins/PlayWallPluginWebAPI/src/main/scala/de/tobias/playpad/plugin/api/websocket/settings/WebApiSettingsViewController.scala b/PlayWallPlugins/PlayWallPluginWebAPI/src/main/scala/de/tobias/playpad/plugin/api/websocket/settings/WebApiSettingsViewController.scala
deleted file mode 100644
index 4f86d86d..00000000
--- a/PlayWallPlugins/PlayWallPluginWebAPI/src/main/scala/de/tobias/playpad/plugin/api/websocket/settings/WebApiSettingsViewController.scala
+++ /dev/null
@@ -1,81 +0,0 @@
-package de.tobias.playpad.plugin.api.websocket.settings
-
-import java.nio.file.Files
-
-import de.thecodelabs.logger.Logger
-import de.thecodelabs.storage.settings.{Storage, StorageTypes}
-import de.thecodelabs.utils.ui.scene.input.NumberTextField
-import de.thecodelabs.utils.util.Localization
-import de.tobias.playpad.plugin.api.WebApiPlugin
-import de.tobias.playpad.settings.GlobalSettings
-import de.tobias.playpad.viewcontroller.option.GlobalSettingsTabViewController
-import javafx.fxml.FXML
-import javafx.scene.control.CheckBox
-
-class WebApiSettingsViewController(val webApiSettings: WebApiSettings) extends GlobalSettingsTabViewController {
-
-	load("plugin/webapi/view", "WebApiSettings", Localization.getBundle)
-
-	@FXML
-	var activeCheckbox: CheckBox = _
-
-	@FXML
-	var portTextField: NumberTextField = _
-
-	/**
-	 * Lädt alle Einstellungen vom Model in die GUI.
-	 *
-	 * @param settings Aktuelles GlobalSettings
-	 */
-	override def loadSettings(settings: GlobalSettings): Unit = {
-		activeCheckbox.setSelected(webApiSettings.isEnabled)
-		portTextField.setText(webApiSettings.getPort.toString)
-	}
-
-	/**
-	 * Speichert alle Änderungen in das Model.
-	 *
-	 * @param settings Aktuelles GlobalSettings
-	 */
-	override def saveSettings(settings: GlobalSettings): Unit = {
-		webApiSettings.setEnabled(activeCheckbox.isSelected)
-		webApiSettings.setPort(portTextField.getText.toInt)
-
-		saveToFile()
-	}
-
-	/**
-	 * Gibt <code>true</code> zurück, wenn im Hauptprogramm etwas neu geladen werden muss.
-	 *
-	 * @return <code>true</code> Benötigt Reload
-	 */
-	override def needReload(): Boolean = {
-		false
-	}
-
-	/**
-	 * Prüft ob die eingetragen Einstellungen erlaubt sind. Bei falschen Eingaben können die Einstellungen nicht
-	 * geschlossen werden.
-	 *
-	 * @return <code>true</code> Einstellungen erlaubt. <code>false</code> Einstellungen fehlerhaft.
-	 */
-	override def validSettings(): Boolean = {
-		true
-	}
-
-	/**
-	 * Gibt den Namen für den Tab zurück.
-	 *
-	 * @return Display Name des Tabs.
-	 */
-	override def name(): String = Localization.getString("webapi.settings")
-
-	private def saveToFile(): Unit = {
-		val settingsPath = WebApiPlugin.getWebApiSettingsPath
-		if (Files.notExists(settingsPath)) {
-			Files.createDirectories(settingsPath.getParent)
-		}
-		Storage.save(StorageTypes.JSON, webApiSettings)
-		Logger.info(f"Save WebAPI settings to $settingsPath")
-	}
-}
-- 
GitLab