Settings-tab refactoring: move General-application and Goldleaf-related options blocks to separate fxmls.
Move list of the GoldLeaf supported versions to the AppPreferences class.
This commit is contained in:
parent
d1500f264b
commit
63d3f7d527
15 changed files with 311 additions and 220 deletions
2
pom.xml
2
pom.xml
|
@ -8,7 +8,7 @@
|
||||||
<name>NS-USBloader</name>
|
<name>NS-USBloader</name>
|
||||||
|
|
||||||
<artifactId>ns-usbloader</artifactId>
|
<artifactId>ns-usbloader</artifactId>
|
||||||
<version>4.2-SNAPSHOT</version>
|
<version>4.2.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<url>https://github.com/developersu/ns-usbloader/</url>
|
<url>https://github.com/developersu/ns-usbloader/</url>
|
||||||
<description>
|
<description>
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package nsusbloader;
|
package nsusbloader;
|
||||||
|
|
||||||
import nsusbloader.Controllers.SettingsController;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
@ -29,6 +27,7 @@ public class AppPreferences {
|
||||||
|
|
||||||
private final Preferences preferences;
|
private final Preferences preferences;
|
||||||
private final Locale locale;
|
private final Locale locale;
|
||||||
|
public static final String[] goldleafSupportedVersions = {"v0.5", "v0.7.x", "v0.8"};
|
||||||
|
|
||||||
private AppPreferences(){
|
private AppPreferences(){
|
||||||
this.preferences = Preferences.userRoot().node("NS-USBloader");
|
this.preferences = Preferences.userRoot().node("NS-USBloader");
|
||||||
|
@ -54,6 +53,7 @@ public class AppPreferences {
|
||||||
netUsb = "USB";
|
netUsb = "USB";
|
||||||
return netUsb;
|
return netUsb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTheme(String theme){ preferences.put("THEME", theme); }
|
public void setTheme(String theme){ preferences.put("THEME", theme); }
|
||||||
public void setProtocol(String protocol){ preferences.put("PROTOCOL", protocol); }
|
public void setProtocol(String protocol){ preferences.put("PROTOCOL", protocol); }
|
||||||
public void setNetUsb(String netUsb){ preferences.put("NETUSB", netUsb); }
|
public void setNetUsb(String netUsb){ preferences.put("NETUSB", netUsb); }
|
||||||
|
@ -109,8 +109,8 @@ public class AppPreferences {
|
||||||
public void setNspFileFilterGL(boolean prop){preferences.putBoolean("GL_NSP_FILTER", prop);}
|
public void setNspFileFilterGL(boolean prop){preferences.putBoolean("GL_NSP_FILTER", prop);}
|
||||||
|
|
||||||
public String getGlVersion(){
|
public String getGlVersion(){
|
||||||
int recentGlVersionIndex = SettingsController.glSupportedVersions.length - 1;
|
int recentGlVersionIndex = goldleafSupportedVersions.length - 1;
|
||||||
String recentGlVersion = SettingsController.glSupportedVersions[recentGlVersionIndex];
|
String recentGlVersion = goldleafSupportedVersions[recentGlVersionIndex];
|
||||||
return preferences.get("gl_version", recentGlVersion);
|
return preferences.get("gl_version", recentGlVersion);
|
||||||
}
|
}
|
||||||
public void setGlVersion(String version){ preferences.put("gl_version", version);}
|
public void setGlVersion(String version){ preferences.put("gl_version", version);}
|
||||||
|
|
|
@ -201,7 +201,7 @@ public class FrontController implements Initializable {
|
||||||
|
|
||||||
if (getSelectedProtocol().equals("TinFoil") && MediatorControl.getInstance().getContoller().getSettingsCtrlr().getTinfoilSettings().isXciNszXczSupport())
|
if (getSelectedProtocol().equals("TinFoil") && MediatorControl.getInstance().getContoller().getSettingsCtrlr().getTinfoilSettings().isXciNszXczSupport())
|
||||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NSP/XCI/NSZ/XCZ", "*.nsp", "*.xci", "*.nsz", "*.xcz"));
|
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NSP/XCI/NSZ/XCZ", "*.nsp", "*.xci", "*.nsz", "*.xcz"));
|
||||||
else if (getSelectedProtocol().equals("GoldLeaf") && (! MediatorControl.getInstance().getContoller().getSettingsCtrlr().getNSPFileFilterForGL()))
|
else if (getSelectedProtocol().equals("GoldLeaf") && (! MediatorControl.getInstance().getContoller().getSettingsCtrlr().getGoldleafSettings().getNSPFileFilterForGL()))
|
||||||
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Any file", "*.*"),
|
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Any file", "*.*"),
|
||||||
new FileChooser.ExtensionFilter("NSP ROM", "*.nsp")
|
new FileChooser.ExtensionFilter("NSP ROM", "*.nsp")
|
||||||
);
|
);
|
||||||
|
@ -266,10 +266,11 @@ public class FrontController implements Initializable {
|
||||||
SettingsController settings = MediatorControl.getInstance().getContoller().getSettingsCtrlr();
|
SettingsController settings = MediatorControl.getInstance().getContoller().getSettingsCtrlr();
|
||||||
// If USB selected
|
// If USB selected
|
||||||
if (getSelectedProtocol().equals("GoldLeaf") ){
|
if (getSelectedProtocol().equals("GoldLeaf") ){
|
||||||
usbNetCommunications = new UsbCommunications(nspToUpload, "GoldLeaf" + settings.getGlVer(), settings.getNSPFileFilterForGL());
|
final SettingsBlockGoldleafController goldleafSettings = settings.getGoldleafSettings();
|
||||||
|
usbNetCommunications = new UsbCommunications(nspToUpload, "GoldLeaf" + goldleafSettings.getGlVer(), goldleafSettings.getNSPFileFilterForGL());
|
||||||
}
|
}
|
||||||
else if (( getSelectedProtocol().equals("TinFoil") && getSelectedNetUsb().equals("USB") )){
|
else if (( getSelectedProtocol().equals("TinFoil") && getSelectedNetUsb().equals("USB") )){
|
||||||
usbNetCommunications = new UsbCommunications(nspToUpload, "TinFoil", settings.getNSPFileFilterForGL());
|
usbNetCommunications = new UsbCommunications(nspToUpload, "TinFoil", false);
|
||||||
}
|
}
|
||||||
else { // NET INSTALL OVER TINFOIL
|
else { // NET INSTALL OVER TINFOIL
|
||||||
final String ipValidationPattern = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
|
final String ipValidationPattern = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
|
||||||
|
@ -332,10 +333,11 @@ public class FrontController implements Initializable {
|
||||||
List<File> filesDropped = event.getDragboard().getFiles();
|
List<File> filesDropped = event.getDragboard().getFiles();
|
||||||
SettingsController settingsController = MediatorControl.getInstance().getContoller().getSettingsCtrlr();
|
SettingsController settingsController = MediatorControl.getInstance().getContoller().getSettingsCtrlr();
|
||||||
SettingsBlockTinfoilController tinfoilSettings = settingsController.getTinfoilSettings();
|
SettingsBlockTinfoilController tinfoilSettings = settingsController.getTinfoilSettings();
|
||||||
|
SettingsBlockGoldleafController goldleafController = settingsController.getGoldleafSettings();
|
||||||
|
|
||||||
if (getSelectedProtocol().equals("TinFoil") && tinfoilSettings.isXciNszXczSupport())
|
if (getSelectedProtocol().equals("TinFoil") && tinfoilSettings.isXciNszXczSupport())
|
||||||
filesDropped.removeIf(file -> ! file.getName().toLowerCase().matches("(.*\\.nsp$)|(.*\\.xci$)|(.*\\.nsz$)|(.*\\.xcz$)"));
|
filesDropped.removeIf(file -> ! file.getName().toLowerCase().matches("(.*\\.nsp$)|(.*\\.xci$)|(.*\\.nsz$)|(.*\\.xcz$)"));
|
||||||
else if (getSelectedProtocol().equals("GoldLeaf") && (! settingsController.getNSPFileFilterForGL()))
|
else if (getSelectedProtocol().equals("GoldLeaf") && (! goldleafController.getNSPFileFilterForGL()))
|
||||||
filesDropped.removeIf(file -> (file.isDirectory() && ! file.getName().toLowerCase().matches(".*\\.nsp$")));
|
filesDropped.removeIf(file -> (file.isDirectory() && ! file.getName().toLowerCase().matches(".*\\.nsp$")));
|
||||||
else
|
else
|
||||||
filesDropped.removeIf(file -> ! file.getName().toLowerCase().matches(".*\\.nsp$"));
|
filesDropped.removeIf(file -> ! file.getName().toLowerCase().matches(".*\\.nsp$"));
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class NSLMainController implements Initializable {
|
||||||
List<String> result = updTask.getValue();
|
List<String> result = updTask.getValue();
|
||||||
if (result != null){
|
if (result != null){
|
||||||
if (!result.get(0).isEmpty()) {
|
if (!result.get(0).isEmpty()) {
|
||||||
SettingsTabController.setNewVersionLink(result.get(0));
|
SettingsTabController.getGenericSettings().setNewVersionLink(result.get(0));
|
||||||
ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionAval"), resourceBundle.getString("windowTitleNewVersionAval") + ": " + result.get(0) + "\n\n" + result.get(1));
|
ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionAval"), resourceBundle.getString("windowTitleNewVersionAval") + ": " + result.get(0) + "\n\n" + result.get(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ public class NSLMainController implements Initializable {
|
||||||
/**
|
/**
|
||||||
* Provide hostServices to Settings tab
|
* Provide hostServices to Settings tab
|
||||||
* */
|
* */
|
||||||
public void setHostServices(HostServices hs ){ SettingsTabController.registerHostServices(hs);}
|
public void setHostServices(HostServices hs ){ SettingsTabController.getGenericSettings().registerHostServices(hs);}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get 'Settings' controller
|
* Get 'Settings' controller
|
||||||
|
|
|
@ -73,6 +73,8 @@ public class RcmController implements Initializable {
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||||
this.rb = resourceBundle;
|
this.rb = resourceBundle;
|
||||||
|
final AppPreferences preferences = AppPreferences.getInstance();
|
||||||
|
|
||||||
rcmToggleGrp.selectToggle(pldrRadio1);
|
rcmToggleGrp.selectToggle(pldrRadio1);
|
||||||
pldrRadio1.setOnAction(e -> statusLbl.setText(""));
|
pldrRadio1.setOnAction(e -> statusLbl.setText(""));
|
||||||
pldrRadio2.setOnAction(e -> statusLbl.setText(""));
|
pldrRadio2.setOnAction(e -> statusLbl.setText(""));
|
||||||
|
@ -80,11 +82,11 @@ public class RcmController implements Initializable {
|
||||||
pldrRadio4.setOnAction(e -> statusLbl.setText(""));
|
pldrRadio4.setOnAction(e -> statusLbl.setText(""));
|
||||||
pldrRadio5.setOnAction(e -> statusLbl.setText(""));
|
pldrRadio5.setOnAction(e -> statusLbl.setText(""));
|
||||||
|
|
||||||
String recentRcm1 = AppPreferences.getInstance().getRecentRcm(1);
|
String recentRcm1 = preferences.getRecentRcm(1);
|
||||||
String recentRcm2 = AppPreferences.getInstance().getRecentRcm(2);
|
String recentRcm2 = preferences.getRecentRcm(2);
|
||||||
String recentRcm3 = AppPreferences.getInstance().getRecentRcm(3);
|
String recentRcm3 = preferences.getRecentRcm(3);
|
||||||
String recentRcm4 = AppPreferences.getInstance().getRecentRcm(4);
|
String recentRcm4 = preferences.getRecentRcm(4);
|
||||||
String recentRcm5 = AppPreferences.getInstance().getRecentRcm(5);
|
String recentRcm5 = preferences.getRecentRcm(5);
|
||||||
|
|
||||||
if (File.separator.equals("/"))
|
if (File.separator.equals("/"))
|
||||||
this.myRegexp = "^.+/";
|
this.myRegexp = "^.+/";
|
||||||
|
@ -112,7 +114,6 @@ public class RcmController implements Initializable {
|
||||||
payloadFPathLbl5.setText(recentRcm5);
|
payloadFPathLbl5.setText(recentRcm5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: write logic ?? Like in case PAYLOADER exist, button active. If not: not active?
|
|
||||||
injectPldBtn.setOnAction(actionEvent -> smash());
|
injectPldBtn.setOnAction(actionEvent -> smash());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019-2020 Dmitry Isaenko
|
||||||
|
|
||||||
|
This file is part of NS-USBloader.
|
||||||
|
|
||||||
|
NS-USBloader is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
NS-USBloader is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package nsusbloader.Controllers;
|
||||||
|
|
||||||
|
import javafx.application.HostServices;
|
||||||
|
import javafx.concurrent.Task;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.CheckBox;
|
||||||
|
import javafx.scene.control.ChoiceBox;
|
||||||
|
import javafx.scene.control.Hyperlink;
|
||||||
|
import javafx.scene.layout.Region;
|
||||||
|
import nsusbloader.AppPreferences;
|
||||||
|
import nsusbloader.ModelControllers.UpdatesChecker;
|
||||||
|
import nsusbloader.ServiceWindow;
|
||||||
|
import nsusbloader.UI.LocaleHolder;
|
||||||
|
import nsusbloader.UI.SettingsLanguagesSetup;
|
||||||
|
import nsusbloader.Utilities.WindowsDrivers.DriversInstall;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
public class SettingsBlockGenericController implements Initializable {
|
||||||
|
@FXML
|
||||||
|
private ChoiceBox<LocaleHolder> languagesChB;
|
||||||
|
@FXML
|
||||||
|
private Button submitLanguageBtn,
|
||||||
|
driversInstallBtn,
|
||||||
|
checkForUpdBtn;
|
||||||
|
@FXML
|
||||||
|
private CheckBox autoCheckForUpdatesCB;
|
||||||
|
@FXML
|
||||||
|
private Hyperlink newVersionHyperlink;
|
||||||
|
|
||||||
|
private ResourceBundle resourceBundle;
|
||||||
|
|
||||||
|
private HostServices hostServices;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||||
|
this.resourceBundle = resourceBundle;
|
||||||
|
final AppPreferences preferences = AppPreferences.getInstance();
|
||||||
|
|
||||||
|
autoCheckForUpdatesCB.setSelected(preferences.getAutoCheckUpdates());
|
||||||
|
|
||||||
|
Region btnSwitchImage = new Region();
|
||||||
|
btnSwitchImage.getStyleClass().add("regionUpdatesCheck");
|
||||||
|
checkForUpdBtn.setGraphic(btnSwitchImage);
|
||||||
|
|
||||||
|
setDriversInstallFeature();
|
||||||
|
|
||||||
|
SettingsLanguagesSetup settingsLanguagesSetup = new SettingsLanguagesSetup();
|
||||||
|
languagesChB.setItems(settingsLanguagesSetup.getLanguages());
|
||||||
|
languagesChB.getSelectionModel().select(settingsLanguagesSetup.getRecentLanguage());
|
||||||
|
|
||||||
|
newVersionHyperlink.setOnAction(e-> hostServices.showDocument(newVersionHyperlink.getText()));
|
||||||
|
checkForUpdBtn.setOnAction(e->checkForUpdatesAction());
|
||||||
|
submitLanguageBtn.setOnAction(e->languageButtonAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDriversInstallFeature(){
|
||||||
|
if (isWindows()){
|
||||||
|
Region btnDrvImage = new Region();
|
||||||
|
btnDrvImage.getStyleClass().add("regionWindows");
|
||||||
|
driversInstallBtn.setGraphic(btnDrvImage);
|
||||||
|
driversInstallBtn.setVisible(true);
|
||||||
|
driversInstallBtn.setOnAction(actionEvent -> new DriversInstall(resourceBundle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private boolean isWindows(){
|
||||||
|
return System.getProperty("os.name").toLowerCase().replace(" ", "").contains("windows");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkForUpdatesAction(){
|
||||||
|
Task<List<String>> updTask = new UpdatesChecker();
|
||||||
|
updTask.setOnSucceeded(event->{
|
||||||
|
List<String> result = updTask.getValue();
|
||||||
|
|
||||||
|
if (result == null){
|
||||||
|
ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionUnknown"),
|
||||||
|
resourceBundle.getString("windowBodyNewVersionUnknown"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.get(0).isEmpty()){
|
||||||
|
ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionNOTAval"),
|
||||||
|
resourceBundle.getString("windowBodyNewVersionNOTAval"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setNewVersionLink(result.get(0));
|
||||||
|
ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionAval"),
|
||||||
|
resourceBundle.getString("windowTitleNewVersionAval")+": "+result.get(0) + "\n\n" + result.get(1));
|
||||||
|
});
|
||||||
|
Thread updates = new Thread(updTask);
|
||||||
|
updates.setDaemon(true);
|
||||||
|
updates.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void languageButtonAction(){
|
||||||
|
LocaleHolder localeHolder = languagesChB.getSelectionModel().getSelectedItem();
|
||||||
|
AppPreferences.getInstance().setLocale(localeHolder.getLocaleCode());
|
||||||
|
Locale newLocale = localeHolder.getLocale();
|
||||||
|
ServiceWindow.getInfoNotification("",
|
||||||
|
ResourceBundle.getBundle("locale", newLocale).getString("windowBodyRestartToApplyLang"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getAutoCheckForUpdates(){ return autoCheckForUpdatesCB.isSelected(); }
|
||||||
|
|
||||||
|
protected void registerHostServices(HostServices hostServices){ this.hostServices = hostServices;}
|
||||||
|
|
||||||
|
void setNewVersionLink(String newVer){
|
||||||
|
newVersionHyperlink.setVisible(true);
|
||||||
|
newVersionHyperlink.setText("https://github.com/developersu/ns-usbloader/releases/tag/"+newVer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePreferencesOnExit() {
|
||||||
|
AppPreferences.getInstance().setAutoCheckUpdates(getAutoCheckForUpdates());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019-2020 Dmitry Isaenko
|
||||||
|
|
||||||
|
This file is part of NS-USBloader.
|
||||||
|
|
||||||
|
NS-USBloader is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
NS-USBloader is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package nsusbloader.Controllers;
|
||||||
|
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.control.CheckBox;
|
||||||
|
import javafx.scene.control.ChoiceBox;
|
||||||
|
import nsusbloader.AppPreferences;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
public class SettingsBlockGoldleafController implements Initializable {
|
||||||
|
@FXML
|
||||||
|
private CheckBox nspFilesFilterForGLCB;
|
||||||
|
@FXML
|
||||||
|
private ChoiceBox<String> glVersionChoiceBox;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||||
|
final AppPreferences preferences = AppPreferences.getInstance();
|
||||||
|
|
||||||
|
nspFilesFilterForGLCB.setSelected(preferences.getNspFileFilterGL());
|
||||||
|
glVersionChoiceBox.getItems().addAll(AppPreferences.goldleafSupportedVersions);
|
||||||
|
|
||||||
|
glVersionChoiceBox.getSelectionModel().select(preferences.getGlVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getNSPFileFilterForGL(){return nspFilesFilterForGLCB.isSelected(); }
|
||||||
|
|
||||||
|
public String getGlVer() {
|
||||||
|
return glVersionChoiceBox.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePreferencesOnExit(){
|
||||||
|
final AppPreferences preferences = AppPreferences.getInstance();
|
||||||
|
|
||||||
|
preferences.setNspFileFilterGL(getNSPFileFilterForGL());
|
||||||
|
preferences.setGlVersion(getGlVer());
|
||||||
|
}
|
||||||
|
}
|
|
@ -145,7 +145,7 @@ public class SettingsBlockTinfoilController implements Initializable {
|
||||||
public boolean isNoRequestsServe(){ return noRequestsServeCB.isSelected(); }
|
public boolean isNoRequestsServe(){ return noRequestsServeCB.isSelected(); }
|
||||||
public boolean isValidateNSHostName(){ return validateNSHostNameCB.isSelected(); }
|
public boolean isValidateNSHostName(){ return validateNSHostNameCB.isSelected(); }
|
||||||
|
|
||||||
public void updatePreferencesOnExit(){
|
void updatePreferencesOnExit(){
|
||||||
AppPreferences preferences = AppPreferences.getInstance();
|
AppPreferences preferences = AppPreferences.getInstance();
|
||||||
|
|
||||||
preferences.setNsIpValidationNeeded(isValidateNSHostName());
|
preferences.setNsIpValidationNeeded(isValidateNSHostName());
|
||||||
|
|
|
@ -18,158 +18,23 @@
|
||||||
*/
|
*/
|
||||||
package nsusbloader.Controllers;
|
package nsusbloader.Controllers;
|
||||||
|
|
||||||
import javafx.application.HostServices;
|
|
||||||
import javafx.concurrent.Task;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
|
||||||
import javafx.scene.control.*;
|
|
||||||
import javafx.scene.layout.Region;
|
|
||||||
import javafx.scene.layout.VBox;
|
|
||||||
import nsusbloader.AppPreferences;
|
|
||||||
import nsusbloader.ServiceWindow;
|
|
||||||
import nsusbloader.ModelControllers.UpdatesChecker;
|
|
||||||
import nsusbloader.UI.LocaleHolder;
|
|
||||||
import nsusbloader.UI.SettingsLanguagesSetup;
|
|
||||||
import nsusbloader.Utilities.WindowsDrivers.DriversInstall;
|
|
||||||
|
|
||||||
import java.net.URL;
|
public class SettingsController {
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class SettingsController implements Initializable {
|
|
||||||
@FXML
|
@FXML
|
||||||
private CheckBox nspFilesFilterForGLCB,
|
private SettingsBlockGenericController settingsBlockGenericController;
|
||||||
autoCheckUpdCb;
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
private Hyperlink newVersionLink;
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
private Button langBtn,
|
|
||||||
checkForUpdBtn,
|
|
||||||
drvInstBtn;
|
|
||||||
@FXML
|
|
||||||
private ChoiceBox<LocaleHolder> langCB;
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
private ChoiceBox<String> glVersionChoiceBox;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private SettingsBlockTinfoilController settingsBlockTinfoilController;
|
private SettingsBlockTinfoilController settingsBlockTinfoilController;
|
||||||
|
@FXML
|
||||||
|
private SettingsBlockGoldleafController settingsBlockGoldleafController;
|
||||||
|
|
||||||
private HostServices hostServices;
|
public SettingsBlockGenericController getGenericSettings(){ return settingsBlockGenericController; }
|
||||||
|
public SettingsBlockGoldleafController getGoldleafSettings(){ return settingsBlockGoldleafController; }
|
||||||
public static final String[] glSupportedVersions = {"v0.5", "v0.7.x", "v0.8"};
|
|
||||||
|
|
||||||
private ResourceBundle resourceBundle;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
|
||||||
this.resourceBundle = resourceBundle;
|
|
||||||
final AppPreferences preferences = AppPreferences.getInstance();
|
|
||||||
|
|
||||||
nspFilesFilterForGLCB.setSelected(preferences.getNspFileFilterGL());
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
newVersionLink.setVisible(false);
|
|
||||||
newVersionLink.setOnAction(e-> hostServices.showDocument(newVersionLink.getText()));
|
|
||||||
|
|
||||||
autoCheckUpdCb.setSelected(preferences.getAutoCheckUpdates());
|
|
||||||
|
|
||||||
Region btnSwitchImage = new Region();
|
|
||||||
btnSwitchImage.getStyleClass().add("regionUpdatesCheck");
|
|
||||||
checkForUpdBtn.setGraphic(btnSwitchImage);
|
|
||||||
|
|
||||||
checkForUpdBtn.setOnAction(e->checkForUpdatesAction());
|
|
||||||
|
|
||||||
setDriversInstallFeature();
|
|
||||||
|
|
||||||
SettingsLanguagesSetup settingsLanguagesSetup = new SettingsLanguagesSetup();
|
|
||||||
langCB.setItems(settingsLanguagesSetup.getLanguages());
|
|
||||||
langCB.getSelectionModel().select(settingsLanguagesSetup.getRecentLanguage());
|
|
||||||
|
|
||||||
configureLanguageButton();
|
|
||||||
|
|
||||||
// Set supported old versions
|
|
||||||
glVersionChoiceBox.getItems().addAll(glSupportedVersions);
|
|
||||||
String oldVer = preferences.getGlVersion(); // Overhead; Too much validation of consistency
|
|
||||||
glVersionChoiceBox.getSelectionModel().select(oldVer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkForUpdatesAction(){
|
|
||||||
Task<List<String>> updTask = new UpdatesChecker();
|
|
||||||
updTask.setOnSucceeded(event->{
|
|
||||||
List<String> result = updTask.getValue();
|
|
||||||
|
|
||||||
if (result == null){
|
|
||||||
ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionUnknown"),
|
|
||||||
resourceBundle.getString("windowBodyNewVersionUnknown"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.get(0).isEmpty()){
|
|
||||||
ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionNOTAval"),
|
|
||||||
resourceBundle.getString("windowBodyNewVersionNOTAval"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setNewVersionLink(result.get(0));
|
|
||||||
ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionAval"),
|
|
||||||
resourceBundle.getString("windowTitleNewVersionAval")+": "+result.get(0) + "\n\n" + result.get(1));
|
|
||||||
});
|
|
||||||
Thread updates = new Thread(updTask);
|
|
||||||
updates.setDaemon(true);
|
|
||||||
updates.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setDriversInstallFeature(){
|
|
||||||
if (isWindows()){
|
|
||||||
Region btnDrvImage = new Region();
|
|
||||||
btnDrvImage.getStyleClass().add("regionWindows");
|
|
||||||
drvInstBtn.setGraphic(btnDrvImage);
|
|
||||||
drvInstBtn.setVisible(true);
|
|
||||||
drvInstBtn.setOnAction(actionEvent -> new DriversInstall(resourceBundle));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private boolean isWindows(){
|
|
||||||
return System.getProperty("os.name").toLowerCase().replace(" ", "").contains("windows");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void configureLanguageButton(){
|
|
||||||
langBtn.setOnAction(e->languageButtonAction());
|
|
||||||
}
|
|
||||||
private void languageButtonAction(){
|
|
||||||
LocaleHolder localeHolder = langCB.getSelectionModel().getSelectedItem();
|
|
||||||
AppPreferences.getInstance().setLocale(localeHolder.getLocaleCode());
|
|
||||||
Locale newLocale = localeHolder.getLocale();
|
|
||||||
ServiceWindow.getInfoNotification("",
|
|
||||||
ResourceBundle.getBundle("locale", newLocale).getString("windowBodyRestartToApplyLang"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getNSPFileFilterForGL(){return nspFilesFilterForGLCB.isSelected(); }
|
|
||||||
|
|
||||||
public boolean getAutoCheckForUpdates(){ return autoCheckUpdCb.isSelected(); }
|
|
||||||
|
|
||||||
public void registerHostServices(HostServices hostServices){this.hostServices = hostServices;}
|
|
||||||
|
|
||||||
public void setNewVersionLink(String newVer){
|
|
||||||
newVersionLink.setVisible(true);
|
|
||||||
newVersionLink.setText("https://github.com/developersu/ns-usbloader/releases/tag/"+newVer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGlVer() {
|
|
||||||
return glVersionChoiceBox.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SettingsBlockTinfoilController getTinfoilSettings(){ return settingsBlockTinfoilController; }
|
public SettingsBlockTinfoilController getTinfoilSettings(){ return settingsBlockTinfoilController; }
|
||||||
|
|
||||||
public void updatePreferencesOnExit(){
|
public void updatePreferencesOnExit(){
|
||||||
AppPreferences preferences = AppPreferences.getInstance();
|
settingsBlockGenericController.updatePreferencesOnExit();
|
||||||
|
settingsBlockGoldleafController.updatePreferencesOnExit();
|
||||||
preferences.setAutoCheckUpdates(getAutoCheckForUpdates());
|
|
||||||
preferences.setNspFileFilterGL(getNSPFileFilterForGL());
|
|
||||||
preferences.setGlVersion(getGlVer());
|
|
||||||
|
|
||||||
settingsBlockTinfoilController.updatePreferencesOnExit();
|
settingsBlockTinfoilController.updatePreferencesOnExit();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -32,7 +32,7 @@ import java.util.ResourceBundle;
|
||||||
|
|
||||||
public class NSLMain extends Application {
|
public class NSLMain extends Application {
|
||||||
|
|
||||||
public static final String appVersion = "v4.2";
|
public static final String appVersion = "v4.2.1";
|
||||||
public static boolean isCli;
|
public static boolean isCli;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package nsusbloader.cli;
|
package nsusbloader.cli;
|
||||||
|
|
||||||
|
import nsusbloader.AppPreferences;
|
||||||
import nsusbloader.COM.USB.UsbCommunications;
|
import nsusbloader.COM.USB.UsbCommunications;
|
||||||
import nsusbloader.Controllers.SettingsController;
|
import nsusbloader.Controllers.SettingsController;
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@ public class GoldLeafCli {
|
||||||
private String getGlSupportedVersions(){
|
private String getGlSupportedVersions(){
|
||||||
StringBuilder builder = new StringBuilder("Supported versions: \n");
|
StringBuilder builder = new StringBuilder("Supported versions: \n");
|
||||||
|
|
||||||
for (String a : SettingsController.glSupportedVersions){
|
for (String a : AppPreferences.goldleafSupportedVersions){
|
||||||
builder.append("\t");
|
builder.append("\t");
|
||||||
builder.append(a);
|
builder.append(a);
|
||||||
builder.append("\n");
|
builder.append("\n");
|
||||||
|
@ -98,7 +99,7 @@ public class GoldLeafCli {
|
||||||
"Try 'ns-usbloader -g help' for more information.");
|
"Try 'ns-usbloader -g help' for more information.");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String version : SettingsController.glSupportedVersions){
|
for (String version : AppPreferences.goldleafSupportedVersions){
|
||||||
if (version.equals(goldLeafVersion))
|
if (version.equals(goldLeafVersion))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ Steps to roll NXDT functionality back:
|
||||||
<SVGPath content="M9,22A1,1 0 0,1 8,21V18H4A2,2 0 0,1 2,16V4C2,2.89 2.9,2 4,2H20A2,2 0 0,1 22,4V16A2,2 0 0,1 20,18H13.9L10.2,21.71C10,21.9 9.75,22 9.5,22V22H9M10,16V19.08L13.08,16H20V4H4V16H10M17,11H15V9H17V11M13,11H11V9H13V11M9,11H7V9H9V11Z" />
|
<SVGPath content="M9,22A1,1 0 0,1 8,21V18H4A2,2 0 0,1 2,16V4C2,2.89 2.9,2 4,2H20A2,2 0 0,1 22,4V16A2,2 0 0,1 20,18H13.9L10.2,21.71C10,21.9 9.75,22 9.5,22V22H9M10,16V19.08L13.08,16H20V4H4V16H10M17,11H15V9H17V11M13,11H11V9H13V11M9,11H7V9H9V11Z" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab closable="false" >
|
<Tab closable="false" disable="true">
|
||||||
<content>
|
<content>
|
||||||
<fx:include fx:id="NXDTab" source="NXDTab.fxml" VBox.vgrow="ALWAYS" />
|
<fx:include fx:id="NXDTab" source="NXDTab.fxml" VBox.vgrow="ALWAYS" />
|
||||||
</content>
|
</content>
|
||||||
|
|
47
src/main/resources/SettingsBlockGeneric.fxml
Normal file
47
src/main/resources/SettingsBlockGeneric.fxml
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.CheckBox?>
|
||||||
|
<?import javafx.scene.control.ChoiceBox?>
|
||||||
|
<?import javafx.scene.control.Hyperlink?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.Pane?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
|
||||||
|
<VBox spacing="5.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.SettingsBlockGenericController">
|
||||||
|
<children>
|
||||||
|
<Label text="%tab2_Lbl_ApplicationSettings" />
|
||||||
|
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||||
|
<children>
|
||||||
|
<Label text="%tab2_Lbl_Language" />
|
||||||
|
<ChoiceBox fx:id="languagesChB" prefWidth="180.0" />
|
||||||
|
<Button fx:id="submitLanguageBtn" mnemonicParsing="false" text="OK" />
|
||||||
|
<VBox alignment="CENTER_RIGHT" HBox.hgrow="ALWAYS">
|
||||||
|
<children>
|
||||||
|
<Button fx:id="driversInstallBtn" mnemonicParsing="false" text="%tab2_Btn_InstallDrivers" visible="false" />
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
</children>
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets left="5.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</HBox>
|
||||||
|
<HBox>
|
||||||
|
<children>
|
||||||
|
<VBox>
|
||||||
|
<children>
|
||||||
|
<CheckBox fx:id="autoCheckForUpdatesCB" mnemonicParsing="false" text="%tab2_Cb_AutoCheckForUpdates" />
|
||||||
|
<Hyperlink fx:id="newVersionHyperlink" />
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
<Pane HBox.hgrow="ALWAYS" />
|
||||||
|
<Button fx:id="checkForUpdBtn" mnemonicParsing="false" />
|
||||||
|
</children>
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets left="5.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</HBox>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
29
src/main/resources/SettingsBlockGoldleaf.fxml
Normal file
29
src/main/resources/SettingsBlockGoldleaf.fxml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.CheckBox?>
|
||||||
|
<?import javafx.scene.control.ChoiceBox?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
|
||||||
|
|
||||||
|
<VBox spacing="5.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1"
|
||||||
|
fx:controller="nsusbloader.Controllers.SettingsBlockGoldleafController">
|
||||||
|
<children>
|
||||||
|
<Label text="GoldLeaf" />
|
||||||
|
<CheckBox fx:id="nspFilesFilterForGLCB" mnemonicParsing="false" text="%tab2_Cb_GLshowNspOnly">
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets left="5.0" />
|
||||||
|
</VBox.margin></CheckBox>
|
||||||
|
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||||
|
<children>
|
||||||
|
<Label text="%tab2_Cb_GlVersion" />
|
||||||
|
<ChoiceBox fx:id="glVersionChoiceBox" prefWidth="75.0" />
|
||||||
|
</children>
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets left="5.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</HBox>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
|
@ -1,72 +1,21 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.Button?>
|
|
||||||
<?import javafx.scene.control.CheckBox?>
|
|
||||||
<?import javafx.scene.control.ChoiceBox?>
|
|
||||||
<?import javafx.scene.control.Hyperlink?>
|
|
||||||
<?import javafx.scene.control.Label?>
|
|
||||||
<?import javafx.scene.control.ScrollPane?>
|
<?import javafx.scene.control.ScrollPane?>
|
||||||
<?import javafx.scene.control.Separator?>
|
<?import javafx.scene.control.Separator?>
|
||||||
<?import javafx.scene.control.TextField?>
|
|
||||||
<?import javafx.scene.layout.HBox?>
|
|
||||||
<?import javafx.scene.layout.Pane?>
|
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
|
||||||
<ScrollPane fitToWidth="true" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.SettingsController">
|
<ScrollPane fitToWidth="true" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.SettingsController">
|
||||||
<VBox spacing="5.0">
|
<VBox spacing="5.0">
|
||||||
<children>
|
<children>
|
||||||
<Label text="%tab2_Lbl_ApplicationSettings" />
|
<fx:include fx:id="settingsBlockGeneric" source="SettingsBlockGeneric.fxml"/>
|
||||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
|
||||||
<children>
|
|
||||||
<Label text="%tab2_Lbl_Language" />
|
|
||||||
<ChoiceBox fx:id="langCB" prefWidth="180.0" />
|
|
||||||
<Button fx:id="langBtn" mnemonicParsing="false" text="OK" />
|
|
||||||
<VBox alignment="CENTER_RIGHT" HBox.hgrow="ALWAYS">
|
|
||||||
<children>
|
|
||||||
<Button fx:id="drvInstBtn" mnemonicParsing="false" text="%tab2_Btn_InstallDrivers" visible="false" />
|
|
||||||
</children>
|
|
||||||
</VBox>
|
|
||||||
</children>
|
|
||||||
<VBox.margin>
|
|
||||||
<Insets left="5.0" />
|
|
||||||
</VBox.margin>
|
|
||||||
</HBox>
|
|
||||||
<HBox>
|
|
||||||
<children>
|
|
||||||
<VBox>
|
|
||||||
<children>
|
|
||||||
<CheckBox fx:id="autoCheckUpdCb" mnemonicParsing="false" text="%tab2_Cb_AutoCheckForUpdates" />
|
|
||||||
<Hyperlink fx:id="newVersionLink" />
|
|
||||||
</children>
|
|
||||||
</VBox>
|
|
||||||
<Pane HBox.hgrow="ALWAYS" />
|
|
||||||
<Button fx:id="checkForUpdBtn" mnemonicParsing="false" />
|
|
||||||
</children>
|
|
||||||
<VBox.margin>
|
|
||||||
<Insets left="5.0" />
|
|
||||||
</VBox.margin>
|
|
||||||
</HBox>
|
|
||||||
<Separator prefWidth="200.0" />
|
<Separator prefWidth="200.0" />
|
||||||
<Label text="GoldLeaf" />
|
<fx:include fx:id="settingsBlockGoldleaf" source="SettingsBlockGoldleaf.fxml"/>
|
||||||
<CheckBox fx:id="nspFilesFilterForGLCB" mnemonicParsing="false" text="%tab2_Cb_GLshowNspOnly">
|
|
||||||
<VBox.margin>
|
|
||||||
<Insets left="5.0" />
|
|
||||||
</VBox.margin></CheckBox>
|
|
||||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
|
||||||
<children>
|
|
||||||
<Label text="%tab2_Cb_GlVersion" />
|
|
||||||
<ChoiceBox fx:id="glVersionChoiceBox" prefWidth="75.0" />
|
|
||||||
</children>
|
|
||||||
<VBox.margin>
|
|
||||||
<Insets left="5.0" />
|
|
||||||
</VBox.margin>
|
|
||||||
</HBox>
|
|
||||||
<Separator prefWidth="200.0" />
|
<Separator prefWidth="200.0" />
|
||||||
<fx:include fx:id="settingsBlockTinfoil" source="SettingsBlockTinfoil.fxml"/>
|
<fx:include fx:id="settingsBlockTinfoil" source="SettingsBlockTinfoil.fxml"/>
|
||||||
</children>
|
</children>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets bottom="5.0" left="15.0" right="15.0" top="5.0" />
|
<Insets bottom="5.0" left="15.0" right="15.0" top="5.0" />
|
||||||
</padding>
|
</padding>
|
||||||
</VBox>
|
</VBox>
|
||||||
</ScrollPane>
|
</ScrollPane>
|
||||||
|
|
Loading…
Reference in a new issue