From b91eb0fda59825fe27d77e9515c8b52de22cf402 Mon Sep 17 00:00:00 2001 From: crschnick Date: Wed, 15 Nov 2023 03:25:18 +0000 Subject: [PATCH] Merge branch 1.7.3-fixes into master --- PRIVACY.md | 21 -- README.md | 4 +- SECURITY.md | 163 -------------- app/build.gradle | 5 +- .../xpipe/app/browser/BrowserClipboard.java | 21 +- .../io/xpipe/app/browser/BrowserComp.java | 123 +++++------ .../app/browser/BrowserFileListModel.java | 3 - .../io/xpipe/app/browser/BrowserModel.java | 62 ++---- .../io/xpipe/app/browser/BrowserNavBar.java | 2 +- .../app/browser/BrowserOverviewComp.java | 43 ++-- .../app/browser/BrowserTransferComp.java | 6 +- .../xpipe/app/browser/BrowserWelcomeComp.java | 4 +- .../xpipe/app/browser/FileSystemHelper.java | 27 +-- .../io/xpipe/app/browser/icon/FileType.java | 16 +- .../io/xpipe/app/comp/base/DropdownComp.java | 1 + .../xpipe/app/comp/base/ListSelectorComp.java | 1 + .../app/comp/base/LoadingOverlayComp.java | 5 - .../io/xpipe/app/comp/base/OsLogoComp.java | 6 +- .../xpipe/app/comp/base/SideMenuBarComp.java | 9 +- .../app/comp/base/SideSplitPaneComp.java | 81 +++++++ .../comp/store/DsStoreProviderChoiceComp.java | 1 + .../app/comp/store/StoreCreationMenu.java | 5 +- .../xpipe/app/comp/store/StoreEntryComp.java | 1 + .../app/comp/store/StoreEntryListComp.java | 2 +- .../comp/store/StoreEntryListStatusComp.java | 138 ++++++++++-- .../app/comp/store/StoreEntryWrapper.java | 4 + .../xpipe/app/comp/store/StoreLayoutComp.java | 21 +- .../app/comp/store/StoreSectionComp.java | 6 +- .../app/comp/store/StoreSectionMiniComp.java | 4 +- .../app/comp/store/StoreSidebarComp.java | 9 +- .../xpipe/app/comp/store/StoreSortComp.java | 122 ----------- .../main/java/io/xpipe/app/core/AppCache.java | 2 +- .../java/io/xpipe/app/core/AppCharsetter.java | 4 +- .../xpipe/app/core/AppExtensionManager.java | 2 +- .../java/io/xpipe/app/core/AppGreetings.java | 33 +-- .../io/xpipe/app/core/AppLayoutModel.java | 25 ++- .../java/io/xpipe/app/core/AppMainWindow.java | 7 +- .../java/io/xpipe/app/core/AppResources.java | 38 +++- .../io/xpipe/app/core/AppSocketServer.java | 5 +- .../main/java/io/xpipe/app/core/AppTheme.java | 7 + .../java/io/xpipe/app/core/mode/BaseMode.java | 1 + .../java/io/xpipe/app/core/mode/GuiMode.java | 2 - .../io/xpipe/app/core/mode/PlatformMode.java | 1 + .../io/xpipe/app/ext/DataStoreProvider.java | 4 + .../main/java/io/xpipe/app/fxcomps/Comp.java | 18 ++ .../app/fxcomps/impl/DataStoreChoiceComp.java | 27 +-- .../io/xpipe/app/fxcomps/impl/FilterComp.java | 2 +- .../xpipe/app/fxcomps/impl/OptionsComp.java | 1 + .../app/fxcomps/impl/StoreCategoryComp.java | 85 +++----- .../java/io/xpipe/app/prefs/AboutComp.java | 4 +- .../java/io/xpipe/app/prefs/AppPrefs.java | 9 +- .../xpipe/app/prefs/JsonStorageHandler.java | 2 +- .../io/xpipe/app/prefs/VaultCategory.java | 3 +- .../io/xpipe/app/storage/DataStorage.java | 43 ++-- .../io/xpipe/app/storage/DataStoreEntry.java | 39 +++- .../io/xpipe/app/storage/StandardStorage.java | 33 ++- .../app/update/CommercializationAlert.java | 43 ---- .../java/io/xpipe/app/util/Hyperlinks.java | 12 +- .../java/io/xpipe/app/util/JfxHelper.java | 12 +- .../io/xpipe/app/util/JsonConfigHelper.java | 19 +- .../java/io/xpipe/app/util/ScanAlert.java | 182 +++++++--------- .../util/SecretRetrievalStrategyHelper.java | 25 ++- .../io/xpipe/app/util/WindowsRegistry.java | 28 +++ .../resources/lang/dscreation_en.properties | 2 +- .../resources/lang/preferences_en.properties | 5 +- .../resources/lang/translations_en.properties | 5 +- .../app/resources/misc/commercialization.md | 21 -- .../io/xpipe/app/resources/misc/eula.md | 65 ++++++ .../io/xpipe/app/resources/misc/tos.md | 149 ------------- .../io/xpipe/app/resources/style/browser.css | 18 +- .../io/xpipe/app/resources/style/category.css | 12 +- .../xpipe/app/resources/style/color-box.css | 10 + .../xpipe/app/resources/style/header-bars.css | 27 ++- .../resources/style/side-split-pane-comp.css | 10 + .../app/resources/style/sidebar-comp.css | 2 +- .../resources/style/storage-entry-comp.css | 66 ------ .../style/storage-entry-list-comp.css | 18 -- .../style/storage-group-list-comp.css | 68 ------ .../app/resources/style/store-entry-comp.css | 6 +- .../resources/style/store-mini-section.css | 4 +- .../io/xpipe/app/resources/style/style.css | 14 +- .../io/xpipe/core/charsetter/Charsetter.java | 31 +-- .../java/io/xpipe/core/dialog/Dialog.java | 11 +- .../io/xpipe/core/process/CommandControl.java | 15 +- .../io/xpipe/core/process/OsNameState.java | 6 + .../core/process/PropertiesFormatsParser.java | 12 ++ .../xpipe/core/process/ShellStoreState.java | 2 +- .../java/io/xpipe/core/store/FileSystem.java | 3 +- .../java/io/xpipe/core/store/ShellStore.java | 37 +--- dist/changelogs/1.7.4.md | 43 ++++ dist/licenses/commons-codec.license | 177 --------------- dist/licenses/commons-codec.properties | 4 - dist/licenses/commons-collections.license | 177 --------------- dist/licenses/commons-collections.properties | 4 - dist/licenses/commons-exec.license | 177 --------------- dist/licenses/commons-exec.properties | 4 - dist/licenses/curvesapi.license | 28 --- dist/licenses/curvesapi.properties | 4 - dist/licenses/flowless.license | 23 -- dist/licenses/flowless.properties | 4 - dist/licenses/fxtrayicon.license | 21 -- dist/licenses/fxtrayicon.properties | 4 - dist/licenses/gson.license | 202 ------------------ dist/licenses/gson.properties | 4 - dist/licenses/jansi.license | 202 ------------------ dist/licenses/jansi.properties | 4 - dist/licenses/jarchivelib.license | 177 --------------- dist/licenses/jarchivelib.properties | 4 - dist/licenses/jline.license | 35 --- dist/licenses/jline.properties | 4 - dist/licenses/jsch.license | 30 --- dist/licenses/jsch.properties | 4 - dist/licenses/log4j.license | 177 --------------- dist/licenses/log4j.properties | 4 - dist/licenses/mssql.license | 11 - dist/licenses/mssql.properties | 4 - dist/licenses/opencsv.license | 201 ----------------- dist/licenses/opencsv.properties | 4 - dist/licenses/openjdk.properties | 4 +- dist/licenses/openjfx.properties | 2 +- dist/licenses/poi.license | 177 --------------- dist/licenses/poi.properties | 4 - dist/licenses/postgres.license | 23 -- dist/licenses/postgres.properties | 4 - dist/licenses/reactfx.license | 23 -- dist/licenses/reactfx.properties | 4 - dist/licenses/richtextfx.license | 23 -- dist/licenses/richtextfx.properties | 4 - dist/licenses/sparsebitset.license | 177 --------------- dist/licenses/sparsebitset.properties | 4 - dist/licenses/undofx.license | 23 -- dist/licenses/undofx.properties | 4 - dist/licenses/wellbehavedfx.license | 23 -- dist/licenses/wellbehavedfx.properties | 4 - dist/licenses/xmlbeans.license | 177 --------------- dist/licenses/xmlbeans.properties | 4 - dist/licenses/zshi.license | 21 -- dist/licenses/zshi.properties | 4 - .../ext/base/action/EditStoreAction.java | 7 +- .../ext/base/action/RefreshStoreAction.java | 5 - .../base/script/PredefinedScriptGroup.java | 8 +- .../io/xpipe/ext/base/script/ScriptStore.java | 32 ++- .../script/SimpleScriptStoreProvider.java | 15 +- .../ext/base/resources/scripts/clink.bat | 2 +- gradle/gradle_scripts/extension_test.gradle | 4 +- gradle/gradle_scripts/java.gradle | 2 +- version | 2 +- 147 files changed, 1059 insertions(+), 3717 deletions(-) delete mode 100644 PRIVACY.md delete mode 100644 SECURITY.md create mode 100644 app/src/main/java/io/xpipe/app/comp/base/SideSplitPaneComp.java delete mode 100644 app/src/main/java/io/xpipe/app/comp/store/StoreSortComp.java delete mode 100644 app/src/main/java/io/xpipe/app/update/CommercializationAlert.java delete mode 100644 app/src/main/resources/io/xpipe/app/resources/misc/commercialization.md create mode 100644 app/src/main/resources/io/xpipe/app/resources/misc/eula.md delete mode 100644 app/src/main/resources/io/xpipe/app/resources/misc/tos.md create mode 100644 app/src/main/resources/io/xpipe/app/resources/style/side-split-pane-comp.css delete mode 100644 app/src/main/resources/io/xpipe/app/resources/style/storage-entry-comp.css delete mode 100644 app/src/main/resources/io/xpipe/app/resources/style/storage-entry-list-comp.css delete mode 100644 app/src/main/resources/io/xpipe/app/resources/style/storage-group-list-comp.css create mode 100644 core/src/main/java/io/xpipe/core/process/OsNameState.java create mode 100644 dist/changelogs/1.7.4.md delete mode 100644 dist/licenses/commons-codec.license delete mode 100644 dist/licenses/commons-codec.properties delete mode 100644 dist/licenses/commons-collections.license delete mode 100644 dist/licenses/commons-collections.properties delete mode 100644 dist/licenses/commons-exec.license delete mode 100644 dist/licenses/commons-exec.properties delete mode 100644 dist/licenses/curvesapi.license delete mode 100644 dist/licenses/curvesapi.properties delete mode 100644 dist/licenses/flowless.license delete mode 100644 dist/licenses/flowless.properties delete mode 100644 dist/licenses/fxtrayicon.license delete mode 100644 dist/licenses/fxtrayicon.properties delete mode 100644 dist/licenses/gson.license delete mode 100644 dist/licenses/gson.properties delete mode 100644 dist/licenses/jansi.license delete mode 100644 dist/licenses/jansi.properties delete mode 100644 dist/licenses/jarchivelib.license delete mode 100644 dist/licenses/jarchivelib.properties delete mode 100644 dist/licenses/jline.license delete mode 100644 dist/licenses/jline.properties delete mode 100644 dist/licenses/jsch.license delete mode 100644 dist/licenses/jsch.properties delete mode 100644 dist/licenses/log4j.license delete mode 100644 dist/licenses/log4j.properties delete mode 100644 dist/licenses/mssql.license delete mode 100644 dist/licenses/mssql.properties delete mode 100644 dist/licenses/opencsv.license delete mode 100644 dist/licenses/opencsv.properties delete mode 100644 dist/licenses/poi.license delete mode 100644 dist/licenses/poi.properties delete mode 100644 dist/licenses/postgres.license delete mode 100644 dist/licenses/postgres.properties delete mode 100644 dist/licenses/reactfx.license delete mode 100644 dist/licenses/reactfx.properties delete mode 100644 dist/licenses/richtextfx.license delete mode 100644 dist/licenses/richtextfx.properties delete mode 100644 dist/licenses/sparsebitset.license delete mode 100644 dist/licenses/sparsebitset.properties delete mode 100644 dist/licenses/undofx.license delete mode 100644 dist/licenses/undofx.properties delete mode 100644 dist/licenses/wellbehavedfx.license delete mode 100644 dist/licenses/wellbehavedfx.properties delete mode 100644 dist/licenses/xmlbeans.license delete mode 100644 dist/licenses/xmlbeans.properties delete mode 100644 dist/licenses/zshi.license delete mode 100644 dist/licenses/zshi.properties diff --git a/PRIVACY.md b/PRIVACY.md deleted file mode 100644 index 04a9fb4b..00000000 --- a/PRIVACY.md +++ /dev/null @@ -1,21 +0,0 @@ -**PRIVACY NOTICE** - -**Last updated September 17, 2023** - -This privacy notice for XPipe, in which ("**we**," "**us**," or "**our**") refers to XPipe UG (haftungsbeschränkt), describes how -and why we -might collect, store, use, and/or share ("**process**") your information when you use our services ("**Services**"), -such as when you: - -* Download and use our application (XPipe) - -**1\. WHAT INFORMATION DO WE COLLECT?** - -We do not process personal or sensitive information. - -Note that there exist a separate privacy policy in case you choose to submit an issue report through the included issue reporter. -You can find the issue reporter privacy policy [here](/app/src/main/resources/io/xpipe/app/resources/misc/report_privacy_policy.md) in this repository, but it will also be shown within the issue reporter. - -**2\. HOW CAN YOU CONTACT US ABOUT THIS NOTICE?** - -If you have questions or comments, you may contact us by email at hello@xpipe.io. diff --git a/README.md b/README.md index 932b39cd..ba582882 100644 --- a/README.md +++ b/README.md @@ -120,9 +120,9 @@ This mainly concerns the features only available in the professional tier and th You have more questions? Then check out the [FAQ](https://xpipe.io/faq). -For information about the security model of XPipe, see the [security page](/SECURITY.md). +For information about the security model of XPipe, see the [security page](https://docs.xpipe.io/security). -For information about the privacy policy of XPipe, see the [privacy page](/PRIVACY.md). +For information about the privacy policy of XPipe, see the [privacy page](https://docs.xpipe.io/privacy-policy). In case you're interested in development, check out the [contributing page](/CONTRIBUTING.md). diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 2962e5e9..00000000 --- a/SECURITY.md +++ /dev/null @@ -1,163 +0,0 @@ -# Security - -Due to its nature, XPipe has to handle a lot of sensitive information. -This can range from passwords for all kinds of servers, to SSH keys, and more. -Therefore, the security model of XPipe plays a very important role. - -This document summarizes the approach of XPipe when it comes to the security of your sensitive information. -If any of your questions are left unanswered by this document, feel free to file an -issue report so your question can be answered individually and can also potentially be included in this document. - -## Reporting a security vulnerability - -If you believe that you found a security vulnerability in XPipe, -you can make use of -the [private security report feature](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability) -of GitHub. - -## Security assumptions - -The general assumption is that the system on which XPipe runs on is not badly infected. -This refers to your local system on which you installed XPipe, not any remote systems that you then connect to. -If your local system is infected to an extent where malicious programs can modify the -file system and other installed programs like XPipe, -then there is no technical way of preventing malicious programs to also infect XPipe and the connected systems as well. - -## Reliance on other programs - -XPipe essentially delegates any form of connection and shell handling to your existing command-line tools. -It does not come with any remote handling capabilities of its own. -Therefore, any used command-line program should be secure. -If for example your `ssh` command-line program or its connections are susceptible to MITM attacks or -vulnerable in any other way, there is no way for XPipe to guarantee that the sensitive information can be kept secure. -It is your responsibility to use the programs in a secure environment and keep them up to date with security patches and -more. -XPipe can only be as secure as your underlying command-line tools itself. - -XPipe calls these programs almost exactly as you would do manually in your terminal -with some a few additional parameters to automatically pass login information -and adapt the environment to make it work properly. -The called program therefore automatically uses your -system configuration for it, e.g. your system SSH configs. - -XPipe does not perform any validation or version checking for the programs it calls. -For example, when establishing an ssh connection through XPipe, it will straight up call `ssh user@host `. -It is assumed that this `ssh` executable is secure and the one that you actually want to use. - -## Data security and privacy - -The general approach of XPipe can be summarized as follows: - -- Any sensitive information should be kept as secure as possible exclusively on your local machine, - both while XPipe is running and also not running -- When sensitive information is required on another remote system that is connected through XPipe, that information - should be transferred and - remain there as briefly and securely as possible -- No sensitive information should be sent to any other server outside your network of trusted connections - -### Storage of sensitive information - -All XPipe data is exclusively stored on your local machine at `~/.xpipe/storage`. You can choose to change this storage location in the settings menu. - -You have the option to either fetch any sensitive information like passwords from outside sources like prompts or password managers. In that case, XPipe doesn't have to store any of that information itself. - -In case you choose to store passwords within XPipe, all sensitive information is encrypted when it is saved to disk on your local machine using AES with either: - -- A custom master key that can be set by you in the settings menu - (This option is only as secure as the password you choose) -- A somewhat dynamically generated key (This option can be reverse - engineered though, there is no way of perfectly securing your data without any custom key) - - -### Passing of sensitive information - -When any kind of login information is required by a command-line program, it has to be passed to it somehow. If the program runs on your local system, the data does not leave your local system. If login information is required on a remote system, then that data must be transferred to that remote system. - -In case a program accepts password input via stdin, this process is relatively straightforward. Then the passed sensitive information is just written into the stdin of the program and does not show up in any history or file system. - -When a program only accepts password input via an environment variable or an askpass program, a self deleting password supplier script file is generated by XPipe. -This script contains the encrypted password and will supply the password to the target program exactly once when invoked and immediately deletes itself afterward. -This behavior ensures that there is no leftover password script after an operation is performed. -As a secondary measure, for cases in which the calling program crashes and is not able to execute the script and therefore doesn't delete the password script, the generated script directory is also frequently cleaned. -As a result, no sensitive information of yours should show up in any kind of shell history or on any file system. - -### The purpose of shell scripts - -Whenever you open a remote connection in a terminal from XPipe, your terminal sometimes shows the name of a script located in your temp directory in the title bar to indicate that you're currently executing it. -The naming scheme of these scripts is usually something like `exec-.(bat|sh|ps1)`. -This is intended as these scripts contain all commands that are required to realize the functionality of connecting and initializing the shell environment. -These scripts do not contain any sensitive information, you are free to inspect them yourselves in the temp directory. - -In case a script connects to a remote system and passes login information to a program via variables or askpass -programs, it automatically becomes useless after being invoked once (See [above](#passing-of-sensitive-information)). -As the script is run immediately after it is created initially, e.g. when using the `Open in terminal` functionality, it becomes useless pretty much instantly so any attacker doesn't obtain any sensitive information from it. - -### Logging - -By default, XPipe creates log files located in `~/.xpipe/logs`. These log files do not contain any sensitive information. -If you choose to launch XPipe in debug mode, these logs are printed to the console instead and will contain a lot more and finer grained information, some of which might be sensitive. - -### Issue reports - -Whenever an error occurs within XPipe or you choose to open the error reporter dialog, you have the option to automatically send an error report with optional feedback and attachments. -This error report does not contain any sensitive information, unless you explicitly choose to attach log files. - -## Isolation of systems - -Any infected remote system should be isolated enough such that any infection can't spread through XPipe. - -### User isolation - -All relevant files like configuration files and other required temporary files are only accessible by the current user. -Any other user on a system can't read or write them unless they have root/Administrator privileges. - -### Isolation of remote systems - -When you add a remote system as a host within XPipe, it is implicitly assumed that you trust this system. -Any required login information is sent to and handled on that remote host when required, -so it would be possible for malicious program with sufficient privileges to obtain any information sent to that host. -This would require an attacker to be able to access files of the user that is used to log into the remote system. -It should however not be possible for any malicious program on the remote host to obtain -other information stored by XPipe that is not explicitly sent to that host. - -## Antivirus programs - -### Windows Defender - -It may occasionally happen that Windows Defender warns and -even sometimes deletes XPipe due to it identifying the application as malware. -The reason for this is simple: The application is not signed with an EV code signing -certificate as this would require a company for XPipe to be set up and would also cost around 600$+ per year. -If XPipe was signed with such a certificate, as are most Windows applications distributed by companies, all warnings -would go away automatically. -The Windows Defender / Windows SmartScreen system is essentially pay-to-win here. -Just paying the appropriate amount will automatically whitelist your application (even it is unsafe / essentially -malware) -while not paying will often blacklist it, bullying you into buying it. -You can read more about this system in [this StackExchange post](https://security.stackexchange.com/a/139520). -The manual whitelisting process without an EV certificate is purposely made difficult and essentially useless. -The Windows Defender detection rules are garbage and not deterministic, i.e. -an identical application can be flagged on one system but not the other, even though both are connected to the internet -and the Microsoft services. -In summary, don't rely on Windows Defender to be accurate when it comes to false-positives. - -### macOS - -On macOS the application bundle is signed and notarized and will therefore not emit any warnings. -For macOS this process does not require a company to be -set up and also only costs 125$ per year and is therefore much easier to accomplish. - -### Windows antivirus programs - -In some cases, it might occur that your antivirus program flags XPipe as malware. -This is due to the fact that XPipe launches shells and executes various commands in them, -which can be interpreted as malicious activity as some viruses use -the same approach and does lead to some false-positives. - -For this reason, all artifacts of every release are automatically uploaded and analyzed on VirusTotal, -so uploading the release you downloaded to VirusTotal should instantly show analysis results. -From there you should be able to get a more accurate overview over the actual threat level of XPipe. - -If such a detection also happens on your end, you might have to -explicitly whitelist XPipe in order for it to work correctly. -Having access to shells is necessary for XPipe, there is no fallback alternative built in that does not launch shells. diff --git a/app/build.gradle b/app/build.gradle index b8a5b159..c8b30632 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -110,7 +110,8 @@ project.ext { "-Xmx8g", "-Dio.xpipe.app.arch=$rootProject.arch", "-Dfile.encoding=UTF-8", - '-XX:+UseZGC', + // Disable this for now as it requires Windows 10+ + // '-XX:+UseZGC', "-Dvisualvm.display.name=XPipe" ] } @@ -137,7 +138,7 @@ application { run { systemProperty 'io.xpipe.app.useVirtualThreads', 'false' systemProperty 'io.xpipe.app.mode', 'gui' - systemProperty 'io.xpipe.app.dataDir', "$projectDir/local_git3/" + systemProperty 'io.xpipe.app.dataDir', "$projectDir/local_git8/" systemProperty 'io.xpipe.app.writeLogs', "true" systemProperty 'io.xpipe.app.writeSysOut', "true" systemProperty 'io.xpipe.app.developerMode', "true" diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserClipboard.java b/app/src/main/java/io/xpipe/app/browser/BrowserClipboard.java index 19baaafc..e4f032da 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserClipboard.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserClipboard.java @@ -2,6 +2,7 @@ package io.xpipe.app.browser; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.util.ThreadHelper; +import io.xpipe.core.process.ShellDialects; import io.xpipe.core.store.FileSystem; import io.xpipe.core.util.FailableRunnable; import javafx.beans.property.Property; @@ -19,6 +20,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; public class BrowserClipboard { @@ -27,6 +29,11 @@ public class BrowserClipboard { UUID uuid; FileSystem.FileEntry baseDirectory; List entries; + + public String toClipboardString() { + return entries.stream().map(fileEntry -> "\"" + fileEntry.getPath() + "\"").collect( + Collectors.joining(ShellDialects.getPlatformDefault().getNewLine().getNewLineString())); + } } public static final Property currentCopyClipboard = new SimpleObjectProperty<>(); @@ -67,9 +74,9 @@ public class BrowserClipboard { @SneakyThrows public static ClipboardContent startDrag(FileSystem.FileEntry base, List selected) { var content = new ClipboardContent(); - var idea = UUID.randomUUID(); - currentDragClipboard = new Instance(idea, base, new ArrayList<>(selected)); - content.putString(idea.toString()); + var id = UUID.randomUUID(); + currentDragClipboard = new Instance(id, base, new ArrayList<>(selected)); + content.putString(currentDragClipboard.toClipboardString()); return content; } @@ -88,9 +95,13 @@ public class BrowserClipboard { return null; } + if (currentDragClipboard == null) { + return null; + } + try { - var idea = UUID.fromString(dragboard.getString()); - if (idea.equals(currentDragClipboard.uuid)) { + var s = dragboard.getString(); + if (s != null && s.equals(currentDragClipboard.toClipboardString())) { var current = currentDragClipboard; currentDragClipboard = null; return current; diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserComp.java index a9ad1b1e..552f026b 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserComp.java @@ -7,10 +7,13 @@ import io.xpipe.app.browser.icon.DirectoryType; import io.xpipe.app.browser.icon.FileIconManager; import io.xpipe.app.browser.icon.FileType; import io.xpipe.app.comp.base.MultiContentComp; +import io.xpipe.app.comp.base.SideSplitPaneComp; +import io.xpipe.app.core.AppLayoutModel; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.impl.FancyTooltipAugment; import io.xpipe.app.fxcomps.impl.PrettyImageHelper; +import io.xpipe.app.fxcomps.impl.VerticalComp; import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.SimpleChangeListener; @@ -26,12 +29,12 @@ import javafx.collections.ListChangeListener; import javafx.geometry.Insets; import javafx.geometry.Orientation; import javafx.geometry.Pos; -import javafx.scene.Node; import javafx.scene.control.*; import javafx.scene.input.DragEvent; import javafx.scene.layout.*; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -55,42 +58,35 @@ public class BrowserComp extends SimpleComp { FileIconManager.loadIfNecessary(); }); - var bookmarksList = new BrowserBookmarkList(model).createRegion(); - VBox.setVgrow(bookmarksList, Priority.ALWAYS); - var localDownloadStage = new BrowserTransferComp(model.getLocalTransfersStage()) - .hide(PlatformThread.sync(Bindings.createBooleanBinding( - () -> { - if (model.getOpenFileSystems().size() == 0) { - return true; - } + var bookmarksList = new BrowserBookmarkList(model).vgrow(); + var localDownloadStage = new BrowserTransferComp(model.getLocalTransfersStage()).hide( + PlatformThread.sync(Bindings.createBooleanBinding(() -> { + if (model.getOpenFileSystems().size() == 0) { + return true; + } - if (model.getMode().isChooser()) { - return true; - } + if (model.getMode().isChooser()) { + return true; + } - // Also show on local - if (model.getSelected().getValue() != null) { - // return model.getSelected().getValue().isLocal(); - } + // Also show on local + if (model.getSelected().getValue() != null) { + // return model.getSelected().getValue().isLocal(); + } - return false; - }, - model.getOpenFileSystems(), - model.getSelected()))) - .createRegion(); - localDownloadStage.setPrefHeight(200); - localDownloadStage.setMaxHeight(200); - var vertical = new VBox(bookmarksList, localDownloadStage); - vertical.setFillWidth(true); + return false; + }, model.getOpenFileSystems(), model.getSelected()))); + localDownloadStage.prefHeight(200); + localDownloadStage.maxHeight(200); + var vertical = new VerticalComp(List.of(bookmarksList, localDownloadStage)); - var splitPane = new SplitPane(vertical, createTabs()); - splitPane - .widthProperty() - .addListener( - // set sidebar width in pixels depending on split pane width - (obs, old, val) -> splitPane.setDividerPosition(0, 360 / splitPane.getWidth())); - - var r = addBottomBar(splitPane); + var splitPane = new SideSplitPaneComp(vertical, createTabs()).withInitialWidth( + AppLayoutModel.get().getSavedState().getBrowserConnectionsWidth()).withOnDividerChange( + AppLayoutModel.get().getSavedState()::setBrowserConnectionsWidth).apply(struc -> { + struc.getLeft().setMinWidth(200); + struc.getLeft().setMaxWidth(500); + }); + var r = addBottomBar(splitPane.createRegion()); r.getStyleClass().add("browser"); // AppFont.small(r); return r; @@ -108,16 +104,12 @@ public class BrowserComp extends SimpleComp { selected.setSpacing(10); model.getSelection().addListener((ListChangeListener) c -> { PlatformThread.runLaterIfNeeded(() -> { - selected.getChildren() - .setAll(c.getList().stream() - .map(s -> { - var field = - new TextField(s.getRawFileEntry().getPath()); - field.setEditable(false); - field.setPrefWidth(400); - return field; - }) - .toList()); + selected.getChildren().setAll(c.getList().stream().map(s -> { + var field = new TextField(s.getRawFileEntry().getPath()); + field.setEditable(false); + field.setPrefWidth(500); + return field; + }).toList()); }); }); var spacer = new Spacer(Orientation.HORIZONTAL); @@ -135,15 +127,14 @@ public class BrowserComp extends SimpleComp { return layout; } - private Node createTabs() { - var multi = new MultiContentComp(Map., ObservableValue>of( - Comp.of(() -> createTabPane()), + private Comp createTabs() { + var multi = new MultiContentComp(Map., ObservableValue>of(Comp.of(() -> createTabPane()), BindingsHelper.persist(Bindings.isNotEmpty(model.getOpenFileSystems())), new BrowserWelcomeComp(model).apply(struc -> StackPane.setAlignment(struc.get(), Pos.CENTER_LEFT)), Bindings.createBooleanBinding(() -> { return model.getOpenFileSystems().size() == 0 && !model.getMode().isChooser(); }, model.getOpenFileSystems()))); - return multi.createRegion(); + return multi; } private TabPane createTabPane() { @@ -163,8 +154,7 @@ public class BrowserComp extends SimpleComp { map.put(v, t); tabs.getTabs().add(t); }); - tabs.getSelectionModel() - .select(model.getOpenFileSystems().indexOf(model.getSelected().getValue())); + tabs.getSelectionModel().select(model.getOpenFileSystems().indexOf(model.getSelected().getValue())); // Used for ignoring changes by the tabpane when new tabs are added. We want to perform the selections manually! var modifying = new SimpleBooleanProperty(); @@ -180,9 +170,9 @@ public class BrowserComp extends SimpleComp { return; } - var source = map.entrySet().stream() - .filter(openFileSystemModelTabEntry -> - openFileSystemModelTabEntry.getValue().equals(newValue)) + var source = map.entrySet() + .stream() + .filter(openFileSystemModelTabEntry -> openFileSystemModelTabEntry.getValue().equals(newValue)) .findAny() .map(Map.Entry::getKey) .orElse(null); @@ -197,9 +187,9 @@ public class BrowserComp extends SimpleComp { return; } - var toSelect = map.entrySet().stream() - .filter(openFileSystemModelTabEntry -> - openFileSystemModelTabEntry.getKey().equals(newValue)) + var toSelect = map.entrySet() + .stream() + .filter(openFileSystemModelTabEntry -> openFileSystemModelTabEntry.getKey().equals(newValue)) .findAny() .map(Map.Entry::getValue) .orElse(null); @@ -238,9 +228,9 @@ public class BrowserComp extends SimpleComp { tabs.getTabs().addListener((ListChangeListener) c -> { while (c.next()) { for (var r : c.getRemoved()) { - var source = map.entrySet().stream() - .filter(openFileSystemModelTabEntry -> - openFileSystemModelTabEntry.getValue().equals(r)) + var source = map.entrySet() + .stream() + .filter(openFileSystemModelTabEntry -> openFileSystemModelTabEntry.getValue().equals(r)) .findAny() .orElse(null); @@ -263,19 +253,14 @@ public class BrowserComp extends SimpleComp { ring.setMinSize(16, 16); ring.setPrefSize(16, 16); ring.setMaxSize(16, 16); - ring.progressProperty() - .bind(Bindings.createDoubleBinding( - () -> model.getBusy().get() ? -1d : 0, PlatformThread.sync(model.getBusy()))); + ring.progressProperty().bind(Bindings.createDoubleBinding(() -> model.getBusy().get() ? -1d : 0, PlatformThread.sync(model.getBusy()))); var image = model.getEntry().get().getProvider().getDisplayIconFileName(model.getEntry().getStore()); var logo = PrettyImageHelper.ofFixedSquare(image, 16).createRegion(); - tab.graphicProperty() - .bind(Bindings.createObjectBinding( - () -> { - return model.getBusy().get() ? ring : logo; - }, - PlatformThread.sync(model.getBusy()))); + tab.graphicProperty().bind(Bindings.createObjectBinding(() -> { + return model.getBusy().get() ? ring : logo; + }, PlatformThread.sync(model.getBusy()))); tab.setText(model.getName()); tab.setContent(new OpenFileSystemComp(model).createSimple()); @@ -301,9 +286,7 @@ public class BrowserComp extends SimpleComp { c.getStyleClass().add(color.getId()); } new FancyTooltipAugment<>(new SimpleStringProperty(model.getTooltip())).augment(c); - c.addEventHandler( - DragEvent.DRAG_ENTERED, - mouseEvent -> Platform.runLater(() -> tabs.getSelectionModel().select(tab))); + c.addEventHandler(DragEvent.DRAG_ENTERED, mouseEvent -> Platform.runLater(() -> tabs.getSelectionModel().select(tab))); }); } }); diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserFileListModel.java b/app/src/main/java/io/xpipe/app/browser/BrowserFileListModel.java index f82d2741..30a7bd3b 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserFileListModel.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserFileListModel.java @@ -88,9 +88,6 @@ public final class BrowserFileListModel { .toList() : all.getValue(); - Comparator tableComparator = comparatorProperty.getValue(); - var comparator = - tableComparator != null ? FILE_TYPE_COMPARATOR.thenComparing(tableComparator) : FILE_TYPE_COMPARATOR; var listCopy = new ArrayList<>(filtered); sort(listCopy); shown.setValue(listCopy); diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserModel.java b/app/src/main/java/io/xpipe/app/browser/BrowserModel.java index 7cd88c04..19d3d29c 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserModel.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserModel.java @@ -18,7 +18,6 @@ import lombok.Setter; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.function.Consumer; @Getter @@ -38,6 +37,7 @@ public class BrowserModel { selected.addListener((observable, oldValue, newValue) -> { if (newValue == null) { + selection.clear(); return; } @@ -60,11 +60,13 @@ public class BrowserModel { public void reset() { var list = new ArrayList(); - openFileSystems.forEach(model -> { - if (DataStorage.get().getStoreEntries().contains(model.getEntry().get())) { - list.add(new BrowserSavedState.Entry(model.getEntry().get().getUuid(), model.getCurrentPath().get())); - } - }); + synchronized (BrowserModel.this) { + openFileSystems.forEach(model -> { + if (DataStorage.get().getStoreEntries().contains(model.getEntry().get())) { + list.add(new BrowserSavedState.Entry(model.getEntry().get().getUuid(), model.getCurrentPath().get())); + } + }); + } // Don't override state if it is empty if (list.size() == 0) { @@ -86,8 +88,11 @@ public class BrowserModel { } var chosen = new ArrayList<>(selection); - for (OpenFileSystemModel openFileSystem : openFileSystems) { - closeFileSystemAsync(openFileSystem); + + synchronized (BrowserModel.this) { + for (OpenFileSystemModel openFileSystem : openFileSystems) { + closeFileSystemAsync(openFileSystem); + } } if (chosen.size() == 0) { @@ -101,9 +106,6 @@ public class BrowserModel { public void closeFileSystemAsync(OpenFileSystemModel open) { ThreadHelper.runAsync(() -> { - if (Objects.equals(selected.getValue(), open)) { - selected.setValue(null); - } open.closeSync(); synchronized (BrowserModel.this) { openFileSystems.remove(open); @@ -111,33 +113,7 @@ public class BrowserModel { }); } - public void openExistingFileSystemIfPresent(DataStoreEntryRef store) { - var found = openFileSystems.stream().filter(model -> Objects.equals(model.getEntry(), store)).findFirst(); - if (found.isPresent()) { - selected.setValue(found.get()); - } else { - openFileSystemAsync(store, null, null); - } - } - public void openFileSystemAsync(DataStoreEntryRef store, String path, BooleanProperty externalBusy) { - // // Prevent multiple tabs in non browser modes - // if (!mode.equals(Mode.BROWSER)) { - // ThreadHelper.runFailableAsync(() -> { - // var open = openFileSystems.size() > 0 ? openFileSystems.get(0) : null; - // if (open != null) { - // open.closeSync(); - // openFileSystems.remove(open); - // } - // - // var model = new OpenFileSystemModel(this, store); - // openFileSystems.add(model); - // selected.setValue(model); - // model.switchSync(store); - // }); - // return; - // } - if (store == null) { return; } @@ -146,15 +122,15 @@ public class BrowserModel { OpenFileSystemModel model; try (var b = new BooleanScope(externalBusy != null ? externalBusy : new SimpleBooleanProperty()).start()) { + model = new OpenFileSystemModel(this, store); + model.initFileSystem(); + model.initSavedState(); // Prevent multiple calls from interfering with each other synchronized (BrowserModel.this) { - model = new OpenFileSystemModel(this, store); - model.initFileSystem(); - model.initSavedState(); + openFileSystems.add(model); + // The tab pane doesn't automatically select new tabs + selected.setValue(model); } - - openFileSystems.add(model); - selected.setValue(model); } if (path != null) { model.initWithGivenDirectory(path); diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java b/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java index 2f3dcd3d..9991e15b 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java @@ -79,7 +79,7 @@ public class BrowserNavBar extends SimpleComp { struc.get().setPromptText("Overview of " + model.getName()); }) - .shortcut(new KeyCodeCombination(KeyCode.F, KeyCombination.SHORTCUT_DOWN), s -> { + .shortcut(new KeyCodeCombination(KeyCode.P, KeyCombination.SHORTCUT_DOWN), s -> { s.get().requestFocus(); }) .accessibleText("Current path"); diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserOverviewComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserOverviewComp.java index 38546dd3..52b2579e 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserOverviewComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserOverviewComp.java @@ -6,8 +6,10 @@ import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.impl.VerticalComp; import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.process.ShellControl; import io.xpipe.core.store.FileSystem; +import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.scene.layout.Priority; import javafx.scene.layout.Region; @@ -27,22 +29,33 @@ public class BrowserOverviewComp extends SimpleComp { @Override @SneakyThrows protected Region createSimple() { + // The open file system might have already been closed + if (model.getFileSystem() == null) { + return new Region(); + } + ShellControl sc = model.getFileSystem().getShell().orElseThrow(); - // TODO: May be move this into another thread - var common = sc.getOsType().determineInterestingPaths(sc).stream() - .map(s -> FileSystem.FileEntry.ofDirectory(model.getFileSystem(), s)) - .filter(entry -> { - try { - return sc.getShellDialect() - .directoryExists(sc, entry.getPath()) - .executeAndCheck(); - } catch (Exception e) { - ErrorEvent.fromThrowable(e).handle(); - return false; - } - }) - .toList(); - var commonOverview = new BrowserFileOverviewComp(model, FXCollections.observableArrayList(common), false); + + var commonPlatform = FXCollections.observableArrayList(); + ThreadHelper.runFailableAsync(() -> { + var common = sc.getOsType().determineInterestingPaths(sc).stream() + .map(s -> FileSystem.FileEntry.ofDirectory(model.getFileSystem(), s)) + .filter(entry -> { + try { + return sc.getShellDialect() + .directoryExists(sc, entry.getPath()) + .executeAndCheck(); + } catch (Exception e) { + ErrorEvent.fromThrowable(e).handle(); + return false; + } + }) + .toList(); + Platform.runLater(() -> { + commonPlatform.setAll(common); + }); + }); + var commonOverview = new BrowserFileOverviewComp(model, commonPlatform, false); var commonPane = new SimpleTitledPaneComp(AppI18n.observable("common"), commonOverview) .apply(struc -> VBox.setVgrow(struc.get(), Priority.NEVER)); diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserTransferComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserTransferComp.java index cf12eaae..8ad2b828 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserTransferComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserTransferComp.java @@ -73,8 +73,8 @@ public class BrowserTransferComp extends SimpleComp { .apply(struc -> struc.get().setSpacing(10)), button -> { var p = new AnchorPane(button); - AnchorPane.setRightAnchor(button, 20.0); - AnchorPane.setTopAnchor(button, 20.0); + AnchorPane.setRightAnchor(button, 10.0); + AnchorPane.setTopAnchor(button, 10.0); p.setPickOnBounds(false); return p; }); @@ -155,6 +155,6 @@ public class BrowserTransferComp extends SimpleComp { }); }), PlatformThread.sync(stage.getDownloading())); - return stack.createRegion(); + return stack.styleClass("transfer").createRegion(); } } diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserWelcomeComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserWelcomeComp.java index d3102358..cab73f66 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserWelcomeComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserWelcomeComp.java @@ -83,7 +83,7 @@ public class BrowserWelcomeComp extends SimpleComp { ThreadHelper.runAsync(() -> { model.restoreState(e, disable); }); - }).disable(disable).styleClass("color-box").apply(struc -> struc.get().setMaxWidth(2000)).grow(true, false); + }).accessibleText(DataStorage.get().getStoreDisplayName(entry.get())).disable(disable).styleClass("color-box").apply(struc -> struc.get().setMaxWidth(2000)).grow(true, false); }).apply(struc -> { VBox vBox = (VBox) struc.get().getContent(); vBox.setSpacing(10); @@ -102,7 +102,7 @@ public class BrowserWelcomeComp extends SimpleComp { var tile = new TileButtonComp("restore", "restoreAllSessions", "mdmz-restore", actionEvent -> { model.restoreState(state); actionEvent.consume(); - }).grow(true, false); + }).grow(true, false).accessibleTextKey("restoreAllSessions"); layout.getChildren().add(tile.createRegion()); return layout; diff --git a/app/src/main/java/io/xpipe/app/browser/FileSystemHelper.java b/app/src/main/java/io/xpipe/app/browser/FileSystemHelper.java index 34182882..bcbd3144 100644 --- a/app/src/main/java/io/xpipe/app/browser/FileSystemHelper.java +++ b/app/src/main/java/io/xpipe/app/browser/FileSystemHelper.java @@ -1,12 +1,11 @@ package io.xpipe.app.browser; import io.xpipe.app.issue.ErrorEvent; -import io.xpipe.core.store.FileNames; -import io.xpipe.core.store.LocalStore; import io.xpipe.core.process.OsType; -import io.xpipe.core.store.ConnectionFileSystem; import io.xpipe.core.store.FileKind; +import io.xpipe.core.store.FileNames; import io.xpipe.core.store.FileSystem; +import io.xpipe.core.store.LocalStore; import java.nio.file.Files; import java.nio.file.Path; @@ -15,28 +14,6 @@ import java.util.List; public class FileSystemHelper { - public static String getStartDirectory(OpenFileSystemModel model) throws Exception { - // Handle special case when file system creation has failed - if (model.getFileSystem() == null) { - return null; - } - - ConnectionFileSystem fileSystem = (ConnectionFileSystem) model.getFileSystem(); - var current = !model.isLocal() - ? fileSystem - .getShellControl() - .executeSimpleStringCommand( - fileSystem.getShellControl().getShellDialect().getPrintWorkingDirectoryCommand()) - : fileSystem - .getShell() - .get() - .getOsType() - .getHomeDirectory(fileSystem.getShell().get()); - var r = resolveDirectoryPath(model, evaluatePath(model, adjustPath(model, current))); - validateDirectoryPath(model, r); - return r; - } - public static String adjustPath(OpenFileSystemModel model, String path) { if (path == null) { return null; diff --git a/app/src/main/java/io/xpipe/app/browser/icon/FileType.java b/app/src/main/java/io/xpipe/app/browser/icon/FileType.java index 71e803a4..fbb75ffa 100644 --- a/app/src/main/java/io/xpipe/app/browser/icon/FileType.java +++ b/app/src/main/java/io/xpipe/app/browser/icon/FileType.java @@ -9,9 +9,8 @@ import java.io.BufferedReader; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; public interface FileType { @@ -45,10 +44,10 @@ public interface FileType { return "." + r; }) - .toList(); + .collect(Collectors.toSet()); var darkIcon = split[2].trim(); var lightIcon = split.length > 3 ? split[3].trim() : darkIcon; - ALL.add(new FileType.Simple(id, lightIcon, darkIcon, filter.toArray(String[]::new))); + ALL.add(new FileType.Simple(id, lightIcon, darkIcon, filter)); } } }); @@ -59,9 +58,9 @@ public interface FileType { private final String id; private final IconVariant icon; - private final String[] endings; + private final Set endings; - public Simple(String id, String lightIcon, String darkIcon, String... endings) { + public Simple(String id, String lightIcon, String darkIcon, Set endings) { this.icon = new IconVariant(lightIcon, darkIcon); this.id = id; this.endings = endings; @@ -73,8 +72,7 @@ public interface FileType { return false; } - return Arrays.stream(endings) - .anyMatch(ending -> entry.getPath().toLowerCase().endsWith(ending.toLowerCase())); + return endings.contains(entry.getPath().toLowerCase(Locale.ROOT)); } @Override diff --git a/app/src/main/java/io/xpipe/app/comp/base/DropdownComp.java b/app/src/main/java/io/xpipe/app/comp/base/DropdownComp.java index 6dd2cd2b..1ad47764 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/DropdownComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/DropdownComp.java @@ -49,6 +49,7 @@ public class DropdownComp extends Comp> { button.setGraphic(graphic); button.getStyleClass().add("dropdown-comp"); + button.setAccessibleText("Dropdown actions"); return new SimpleCompStructure<>(button); } diff --git a/app/src/main/java/io/xpipe/app/comp/base/ListSelectorComp.java b/app/src/main/java/io/xpipe/app/comp/base/ListSelectorComp.java index 156d2e4b..174a84ce 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/ListSelectorComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/ListSelectorComp.java @@ -35,6 +35,7 @@ public class ListSelectorComp extends SimpleComp { for (var v : values) { var cb = new CheckBox(null); cbs.add(cb); + cb.setAccessibleText(toString.apply(v)); cb.setSelected(selected.contains(v)); cb.selectedProperty().addListener((c, o, n) -> { if (n) { diff --git a/app/src/main/java/io/xpipe/app/comp/base/LoadingOverlayComp.java b/app/src/main/java/io/xpipe/app/comp/base/LoadingOverlayComp.java index 90656ef9..cdebc3f5 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/LoadingOverlayComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/LoadingOverlayComp.java @@ -34,11 +34,6 @@ public class LoadingOverlayComp extends Comp> { var loadingOverlay = new StackPane(loading); loadingOverlay.getStyleClass().add("loading-comp"); - loadingOverlay.getStyleClass().add("modal-pane"); - loadingOverlay.visibleProperty().addListener((observable, oldValue, newValue) -> { - r.setOpacity(newValue ? r.getOpacity() * 0.25 : Math.min(1.0, r.getOpacity() * 4)); - }); - loadingOverlay.setVisible(showLoading.getValue()); var listener = new ChangeListener() { diff --git a/app/src/main/java/io/xpipe/app/comp/base/OsLogoComp.java b/app/src/main/java/io/xpipe/app/comp/base/OsLogoComp.java index 9dba52d1..d57de2c4 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/OsLogoComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/OsLogoComp.java @@ -6,8 +6,8 @@ import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.impl.PrettyImageHelper; import io.xpipe.app.fxcomps.impl.StackComp; import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.core.process.OsNameState; import io.xpipe.core.store.FileNames; -import io.xpipe.core.process.ShellStoreState; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -41,11 +41,11 @@ public class OsLogoComp extends SimpleComp { } var ps = wrapper.getPersistentState().getValue(); - if (!(ps instanceof ShellStoreState sss)) { + if (!(ps instanceof OsNameState ons)) { return null; } - return getImage(sss.getOsName()); + return getImage(ons.getOsName()); }, wrapper.getPersistentState(), state)); var hide = BindingsHelper.map(img, s -> s != null); diff --git a/app/src/main/java/io/xpipe/app/comp/base/SideMenuBarComp.java b/app/src/main/java/io/xpipe/app/comp/base/SideMenuBarComp.java index 90df02c4..b0a30f5d 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/SideMenuBarComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/SideMenuBarComp.java @@ -51,6 +51,7 @@ public class SideMenuBarComp extends Comp> { }); }); }); + b.accessibleText(e.name()); vbox.getChildren().add(b.createRegion()); }); @@ -64,7 +65,7 @@ public class SideMenuBarComp extends Comp> { } UserReportComp.show(event.build()); }) - .apply(new FancyTooltipAugment<>("reportIssue")); + .apply(new FancyTooltipAugment<>("reportIssue")).accessibleTextKey("reportIssue"); b.apply(struc -> { AppFont.setSize(struc.get(), 2); }); @@ -73,7 +74,7 @@ public class SideMenuBarComp extends Comp> { { var b = new IconButtonComp("mdi2g-github", () -> Hyperlinks.open(Hyperlinks.GITHUB)) - .apply(new FancyTooltipAugment<>("visitGithubRepository")); + .apply(new FancyTooltipAugment<>("visitGithubRepository")).accessibleTextKey("visitGithubRepository"); b.apply(struc -> { AppFont.setSize(struc.get(), 2); }); @@ -92,7 +93,7 @@ public class SideMenuBarComp extends Comp> { { var b = new IconButtonComp("mdi2d-discord", () -> Hyperlinks.open(Hyperlinks.DISCORD)) - .apply(new FancyTooltipAugment<>("discord")); + .apply(new FancyTooltipAugment<>("discord")).accessibleTextKey("discord"); b.apply(struc -> { AppFont.setSize(struc.get(), 2); }); @@ -101,7 +102,7 @@ public class SideMenuBarComp extends Comp> { { var b = new IconButtonComp("mdi2u-update", () -> UpdateAvailableAlert.showIfNeeded()) - .apply(new FancyTooltipAugment<>("updateAvailableTooltip")); + .apply(new FancyTooltipAugment<>("updateAvailableTooltip")).accessibleTextKey("updateAvailableTooltip"); b.apply(struc -> { AppFont.setSize(struc.get(), 2); }); diff --git a/app/src/main/java/io/xpipe/app/comp/base/SideSplitPaneComp.java b/app/src/main/java/io/xpipe/app/comp/base/SideSplitPaneComp.java new file mode 100644 index 00000000..5bfb9400 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/comp/base/SideSplitPaneComp.java @@ -0,0 +1,81 @@ +package io.xpipe.app.comp.base; + +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import javafx.scene.control.SplitPane; +import javafx.scene.layout.Region; +import lombok.Value; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + +public class SideSplitPaneComp extends Comp { + + private final Comp left; + private final Comp center; + private Double initialWidth; + private Consumer onDividerChange; + public SideSplitPaneComp(Comp left, Comp center) { + this.left = left; + this.center = center; + } + + @Override + public Structure createBase() { + var c = center.createRegion(); + var sidebar = left.createRegion(); + if (initialWidth != null) { + sidebar.setPrefWidth(initialWidth); + } + var r = new SplitPane(sidebar, c); + + AtomicBoolean setInitial = new AtomicBoolean(false); + r.widthProperty().addListener((observable, oldValue, newValue) -> { + if (newValue.doubleValue() <= 0) { + return; + } + + if (!setInitial.get() && initialWidth != null) { + r.getDividers().get(0).setPosition(initialWidth / newValue.doubleValue()); + setInitial.set(true); + } + }); + + SplitPane.setResizableWithParent(sidebar, false); + r.getDividers().get(0).positionProperty().addListener((observable, oldValue, newValue) -> { + if (r.getWidth() <= 0) { + return; + } + + if (onDividerChange != null) { + onDividerChange.accept(newValue.doubleValue() * r.getWidth()); + } + }); + r.getStyleClass().add("side-split-pane-comp"); + return new Structure(sidebar, c, r, r.getDividers().get(0)); + } + + public SideSplitPaneComp withInitialWidth(double val) { + this.initialWidth = val; + return this; + } + + public SideSplitPaneComp withOnDividerChange(Consumer onDividerChange) { + this.onDividerChange = onDividerChange; + return this; + } + + @Value + public static class Structure implements CompStructure { + + Region left; + Region center; + SplitPane pane; + SplitPane.Divider divider; + + @Override + public SplitPane get() { + return pane; + } + } +} diff --git a/app/src/main/java/io/xpipe/app/comp/store/DsStoreProviderChoiceComp.java b/app/src/main/java/io/xpipe/app/comp/store/DsStoreProviderChoiceComp.java index f680ec51..8993234b 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/DsStoreProviderChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/DsStoreProviderChoiceComp.java @@ -60,6 +60,7 @@ public class DsStoreProviderChoiceComp extends Comp ComboBox cb = comboBox.build(); cb.getStyleClass().add("data-source-type"); cb.getStyleClass().add("choice-comp"); + cb.setAccessibleText("Choose connection type"); return new SimpleCompStructure<>(cb); } } diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationMenu.java b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationMenu.java index 2924140f..132ca495 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationMenu.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationMenu.java @@ -1,6 +1,5 @@ package io.xpipe.app.comp.store; -import io.xpipe.app.comp.store.GuiDsStoreCreator; import io.xpipe.app.core.AppI18n; import io.xpipe.app.ext.DataStoreProvider; import io.xpipe.app.ext.DataStoreProviders; @@ -52,7 +51,7 @@ public class StoreCreationMenu { cmd.setGraphic(new FontIcon("mdi2c-code-greater-than")); cmd.textProperty().bind(AppI18n.observable("addCommand")); cmd.setOnAction(event -> { - GuiDsStoreCreator.showCreation(null, + GuiDsStoreCreator.showCreation(DataStoreProviders.byName("cmd").orElseThrow(), v -> DataStoreProvider.CreationCategory.COMMAND.equals(v.getCreationCategory())); event.consume(); }); @@ -85,7 +84,7 @@ public class StoreCreationMenu { script.setGraphic(new FontIcon("mdi2s-script-text-outline")); script.textProperty().bind(AppI18n.observable("addScript")); script.setOnAction(event -> { - GuiDsStoreCreator.showCreation(null, + GuiDsStoreCreator.showCreation(DataStoreProviders.byName("script").orElseThrow(), v -> DataStoreProvider.CreationCategory.SCRIPT.equals(v.getCreationCategory())); event.consume(); }); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java index c89aa19c..40328f3f 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java @@ -209,6 +209,7 @@ public abstract class StoreEntryComp extends SimpleComp { action.execute(); }); }); + button.accessibleText(actionProvider.getName(wrapper.getEntry().ref()).getValue()); button.apply(new FancyTooltipAugment<>( actionProvider.getName(wrapper.getEntry().ref()))); if (actionProvider.activeType() == ActionProvider.DataStoreCallSite.ActiveType.ONLY_SHOW_IF_ENABLED) { diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListComp.java index dd8fe496..72d5a00f 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListComp.java @@ -22,7 +22,7 @@ public class StoreEntryListComp extends SimpleComp { StoreViewState.get().getCurrentTopLevelSection().getAllChildren(), (StoreSection e) -> { var custom = StoreSection.customSection(e, true).hgrow(); - return new HorizontalComp(List.of(Comp.hspacer(10), custom, Comp.hspacer(10))) + return new HorizontalComp(List.of(Comp.hspacer(8), custom, Comp.hspacer(10))) .styleClass("top"); }) .apply(struc -> ((Region) struc.get().getContent()).setPadding(new Insets(10, 0, 10, 0))); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java index 1b3d4b75..aa86d809 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java @@ -3,12 +3,17 @@ package io.xpipe.app.comp.store; import io.xpipe.app.comp.base.CountComp; import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.SimpleComp; -import io.xpipe.app.fxcomps.augment.GrowAugment; +import io.xpipe.app.fxcomps.impl.FancyTooltipAugment; import io.xpipe.app.fxcomps.impl.FilterComp; +import io.xpipe.app.fxcomps.impl.IconButtonComp; import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import io.xpipe.app.util.ThreadHelper; import javafx.beans.binding.Bindings; +import javafx.beans.property.Property; +import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.geometry.Pos; import javafx.scene.control.Label; @@ -16,11 +21,25 @@ import javafx.scene.control.MenuButton; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCombination; -import javafx.scene.layout.*; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; +import javafx.scene.text.TextAlignment; import org.kordamp.ikonli.javafx.FontIcon; public class StoreEntryListStatusComp extends SimpleComp { + private final Property sortMode; + + public StoreEntryListStatusComp() { + this.sortMode = new SimpleObjectProperty<>(); + SimpleChangeListener.apply(StoreViewState.get().getActiveCategory(), val -> { + sortMode.unbind(); + sortMode.bindBidirectional(val.getSortMode()); + }); + } + private Region createGroupListHeader() { var label = new Label(); label.textProperty().bind(Bindings.createStringBinding(() -> { @@ -44,12 +63,11 @@ public class StoreEntryListStatusComp extends SimpleComp { StoreViewState.get().getFilterString()); var count = new CountComp<>(shownList, all); - var spacer = new Region(); - - var topBar = new HBox(label, spacer, count.createRegion()); - AppFont.setSize(topBar, 1); + var c = count.createRegion(); + var topBar = new HBox(label, c, Comp.hspacer().createRegion(), createDateSortButton().createRegion(), Comp.hspacer(2).createRegion(), createAlphabeticalSortButton().createRegion()); + AppFont.setSize(label, 3); + AppFont.setSize(c, 3); topBar.setAlignment(Pos.CENTER); - HBox.setHgrow(spacer, Priority.ALWAYS); topBar.getStyleClass().add("top"); return topBar; } @@ -65,25 +83,117 @@ public class StoreEntryListStatusComp extends SimpleComp { filter.shortcut(new KeyCodeCombination(KeyCode.F, KeyCombination.SHORTCUT_DOWN), s -> { s.getText().requestFocus(); }); - var r = new StackPane(filter.createRegion()); - r.setAlignment(Pos.CENTER); - r.getStyleClass().add("filter-bar"); - AppFont.medium(r); - return r; + filter.apply(struc -> struc.get().sceneProperty().addListener((observable, oldValue, newValue) -> { + if (newValue != null) { + struc.getText().requestFocus(); + } + })); + + var f = filter.createRegion(); + var hbox = new HBox(createButtons(), f); + hbox.setSpacing(8); + hbox.setAlignment(Pos.CENTER); + HBox.setHgrow(f, Priority.ALWAYS); + f.getStyleClass().add("filter-bar"); + AppFont.medium(hbox); + return hbox; } private Region createButtons() { var menu = new MenuButton(AppI18n.get("addConnections"), new FontIcon("mdi2p-plus-thick")); + menu.setAlignment(Pos.CENTER); + menu.setTextAlignment(TextAlignment.CENTER); AppFont.medium(menu); - GrowAugment.create(true, false).augment(menu); StoreCreationMenu.addButtons(menu); menu.setOpacity(0.85); + menu.setMinWidth(Region.USE_PREF_SIZE); return menu; } + private Comp createAlphabeticalSortButton() { + var icon = Bindings.createStringBinding( + () -> { + if (sortMode.getValue() == StoreSortMode.ALPHABETICAL_ASC) { + return "mdi2s-sort-alphabetical-descending"; + } + if (sortMode.getValue() == StoreSortMode.ALPHABETICAL_DESC) { + return "mdi2s-sort-alphabetical-ascending"; + } + return "mdi2s-sort-alphabetical-descending"; + }, + sortMode); + var alphabetical = new IconButtonComp(icon, () -> { + if (sortMode.getValue() == StoreSortMode.ALPHABETICAL_ASC) { + sortMode.setValue(StoreSortMode.ALPHABETICAL_DESC); + } else if (sortMode.getValue() == StoreSortMode.ALPHABETICAL_DESC) { + sortMode.setValue(StoreSortMode.ALPHABETICAL_ASC); + } else { + sortMode.setValue(StoreSortMode.ALPHABETICAL_ASC); + } + }); + alphabetical.apply(alphabeticalR -> { + alphabeticalR + .get() + .opacityProperty() + .bind(Bindings.createDoubleBinding( + () -> { + if (sortMode.getValue() == StoreSortMode.ALPHABETICAL_ASC + || sortMode.getValue() == StoreSortMode.ALPHABETICAL_DESC) { + return 1.0; + } + return 0.4; + }, + sortMode)); + }); + alphabetical.accessibleTextKey("sortAlphabetical"); + alphabetical.apply(new FancyTooltipAugment<>("sortAlphabetical")); + alphabetical.shortcut(new KeyCodeCombination(KeyCode.P, KeyCombination.SHORTCUT_DOWN)); + return alphabetical; + } + + private Comp createDateSortButton() { + var icon = Bindings.createStringBinding( + () -> { + if (sortMode.getValue() == StoreSortMode.DATE_ASC) { + return "mdi2s-sort-clock-ascending-outline"; + } + if (sortMode.getValue() == StoreSortMode.DATE_DESC) { + return "mdi2s-sort-clock-descending-outline"; + } + return "mdi2s-sort-clock-ascending-outline"; + }, + sortMode); + var date = new IconButtonComp(icon, () -> { + if (sortMode.getValue() == StoreSortMode.DATE_ASC) { + sortMode.setValue(StoreSortMode.DATE_DESC); + } else if (sortMode.getValue() == StoreSortMode.DATE_DESC) { + sortMode.setValue(StoreSortMode.DATE_ASC); + } else { + sortMode.setValue(StoreSortMode.DATE_ASC); + } + }); + date.apply(dateR -> { + dateR.get() + .opacityProperty() + .bind(Bindings.createDoubleBinding( + () -> { + if (sortMode.getValue() == StoreSortMode.DATE_ASC + || sortMode.getValue() == StoreSortMode.DATE_DESC) { + return 1.0; + } + return 0.4; + }, + sortMode)); + }); + date.accessibleTextKey("sortLastUsed"); + date.apply(new FancyTooltipAugment<>("sortLastUsed")); + date.shortcut(new KeyCodeCombination(KeyCode.L, KeyCombination.SHORTCUT_DOWN)); + return date; + } + @Override public Region createSimple() { - var bar = new VBox(createGroupListHeader(), createGroupListFilter(), createButtons()); + var bar = new VBox(createGroupListHeader(), createGroupListFilter()); bar.setFillWidth(true); bar.getStyleClass().add("bar"); bar.getStyleClass().add("store-header-bar"); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java index 4f850b58..13af04c6 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java @@ -190,6 +190,10 @@ public class StoreEntryWrapper { } public void executeDefaultAction() throws Exception { + if (entry.getValidity() == DataStoreEntry.Validity.LOAD_FAILED) { + return; + } + if (getEntry().getValidity() == DataStoreEntry.Validity.INCOMPLETE) { editDialog(); return; diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreLayoutComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreLayoutComp.java index b14cef27..39411d2f 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreLayoutComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreLayoutComp.java @@ -1,12 +1,12 @@ package io.xpipe.app.comp.store; +import io.xpipe.app.comp.base.SideSplitPaneComp; import io.xpipe.app.core.AppActionLinkDetector; +import io.xpipe.app.core.AppLayoutModel; import io.xpipe.app.fxcomps.SimpleComp; -import io.xpipe.app.fxcomps.augment.GrowAugment; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCombination; -import javafx.scene.layout.BorderPane; import javafx.scene.layout.Region; public class StoreLayoutComp extends SimpleComp { @@ -19,14 +19,13 @@ public class StoreLayoutComp extends SimpleComp { @Override protected Region createSimple() { - var listComp = new StoreEntryListComp().apply(GrowAugment.create(false, true)); - var r = new BorderPane(); - - var listR = listComp.createRegion(); - var groupHeader = new StoreSidebarComp().createRegion(); - r.setLeft(groupHeader); - r.setCenter(listR); - r.getStyleClass().add("layout"); - return r; + var struc = new SideSplitPaneComp(new StoreSidebarComp(), new StoreEntryListComp()).withInitialWidth( + AppLayoutModel.get().getSavedState().getSidebarWidth()).withOnDividerChange(aDouble -> { + AppLayoutModel.get().getSavedState().setSidebarWidth(aDouble); + }).createStructure(); + struc.getLeft().setMinWidth(260); + struc.getLeft().setMaxWidth(500); + struc.get().getStyleClass().add("store-layout"); + return struc.get(); } } diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java index cd53e204..a77f1347 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java @@ -53,7 +53,9 @@ public class StoreSectionComp extends Comp> { .apply(struc -> struc.get().setMinWidth(30)) .apply(struc -> struc.get().setPrefWidth(30)) .focusTraversable() - .accessibleText("Expand") + .accessibleText(Bindings.createStringBinding(() -> { + return "Expand " + section.getWrapper().getName().getValue(); + }, section.getWrapper().getName())) .disable(BindingsHelper.persist( Bindings.size(section.getShownChildren()).isEqualTo(0))) .grow(false, true) @@ -85,7 +87,7 @@ public class StoreSectionComp extends Comp> { return new VerticalComp(List.of( new HorizontalComp(topEntryList) .apply(struc -> struc.get().setFillHeight(true)), - Comp.separator().visible(expanded), + Comp.separator().hide(BindingsHelper.persist(expanded.not())), new HorizontalComp(List.of(content)) .styleClass("content") .apply(struc -> struc.get().setFillHeight(true)) diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreSectionMiniComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionMiniComp.java index fd030ad0..8e990500 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreSectionMiniComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionMiniComp.java @@ -74,7 +74,9 @@ public class StoreSectionMiniComp extends Comp> { .apply(struc -> struc.get().setMinWidth(20)) .apply(struc -> struc.get().setPrefWidth(20)) .focusTraversable() - .accessibleText("Expand") + .accessibleText(Bindings.createStringBinding(() -> { + return "Expand " + section.getWrapper().getName().getValue(); + }, section.getWrapper().getName())) .disable(BindingsHelper.persist( Bindings.size(section.getAllChildren()).isEqualTo(0))) .grow(false, true) diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreSidebarComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSidebarComp.java index 61e5cb98..edccd1cf 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreSidebarComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSidebarComp.java @@ -13,11 +13,10 @@ public class StoreSidebarComp extends SimpleComp { @Override protected Region createSimple() { var sideBar = new VerticalComp(List.of( - new StoreEntryListStatusComp(), - new StoreSortComp(), - new StoreCategoryListComp(StoreViewState.get().getAllConnectionsCategory()), - new StoreCategoryListComp(StoreViewState.get().getAllScriptsCategory()), - Comp.of(() -> new Region()).styleClass("bar").styleClass("filler-bar").vgrow())); + new StoreEntryListStatusComp().styleClass("color-box").styleClass("gray"), + new StoreCategoryListComp(StoreViewState.get().getAllConnectionsCategory()).styleClass("color-box").styleClass("gray"), + new StoreCategoryListComp(StoreViewState.get().getAllScriptsCategory()).styleClass("color-box").styleClass("gray"), + Comp.of(() -> new Region()).styleClass("bar").styleClass("color-box").styleClass("gray").styleClass("filler-bar").vgrow())); sideBar.apply(struc -> struc.get().setFillWidth(true)); sideBar.styleClass("sidebar"); sideBar.prefWidth(240); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreSortComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSortComp.java deleted file mode 100644 index 6dee0ed7..00000000 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreSortComp.java +++ /dev/null @@ -1,122 +0,0 @@ -package io.xpipe.app.comp.store; - -import io.xpipe.app.fxcomps.Comp; -import io.xpipe.app.fxcomps.SimpleComp; -import io.xpipe.app.fxcomps.impl.FancyTooltipAugment; -import io.xpipe.app.fxcomps.impl.HorizontalComp; -import io.xpipe.app.fxcomps.impl.IconButtonComp; -import io.xpipe.app.fxcomps.util.SimpleChangeListener; -import javafx.beans.binding.Bindings; -import javafx.beans.property.Property; -import javafx.beans.property.SimpleObjectProperty; -import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyCodeCombination; -import javafx.scene.input.KeyCombination; -import javafx.scene.layout.Region; - -import java.util.List; - -public class StoreSortComp extends SimpleComp { - - private final Property sortMode; - - public StoreSortComp() { - this.sortMode = new SimpleObjectProperty<>(); - SimpleChangeListener.apply(StoreViewState.get().getActiveCategory(), val -> { - sortMode.unbind(); - sortMode.bindBidirectional(val.getSortMode()); - }); - } - - private Comp createAlphabeticalSortButton() { - var icon = Bindings.createStringBinding( - () -> { - if (sortMode.getValue() == StoreSortMode.ALPHABETICAL_ASC) { - return "mdi2s-sort-alphabetical-descending"; - } - if (sortMode.getValue() == StoreSortMode.ALPHABETICAL_DESC) { - return "mdi2s-sort-alphabetical-ascending"; - } - return "mdi2s-sort-alphabetical-descending"; - }, - sortMode); - var alphabetical = new IconButtonComp(icon, () -> { - if (sortMode.getValue() == StoreSortMode.ALPHABETICAL_ASC) { - sortMode.setValue(StoreSortMode.ALPHABETICAL_DESC); - } else if (sortMode.getValue() == StoreSortMode.ALPHABETICAL_DESC) { - sortMode.setValue(StoreSortMode.ALPHABETICAL_ASC); - } else { - sortMode.setValue(StoreSortMode.ALPHABETICAL_ASC); - } - }); - alphabetical.apply(alphabeticalR -> { - alphabeticalR - .get() - .opacityProperty() - .bind(Bindings.createDoubleBinding( - () -> { - if (sortMode.getValue() == StoreSortMode.ALPHABETICAL_ASC - || sortMode.getValue() == StoreSortMode.ALPHABETICAL_DESC) { - return 1.0; - } - return 0.4; - }, - sortMode)); - }); - alphabetical.apply(new FancyTooltipAugment<>("sortAlphabetical")); - alphabetical.shortcut(new KeyCodeCombination(KeyCode.P, KeyCombination.SHORTCUT_DOWN)); - return alphabetical; - } - - private Comp createDateSortButton() { - var icon = Bindings.createStringBinding( - () -> { - if (sortMode.getValue() == StoreSortMode.DATE_ASC) { - return "mdi2s-sort-clock-ascending-outline"; - } - if (sortMode.getValue() == StoreSortMode.DATE_DESC) { - return "mdi2s-sort-clock-descending-outline"; - } - return "mdi2s-sort-clock-ascending-outline"; - }, - sortMode); - var date = new IconButtonComp(icon, () -> { - if (sortMode.getValue() == StoreSortMode.DATE_ASC) { - sortMode.setValue(StoreSortMode.DATE_DESC); - } else if (sortMode.getValue() == StoreSortMode.DATE_DESC) { - sortMode.setValue(StoreSortMode.DATE_ASC); - } else { - sortMode.setValue(StoreSortMode.DATE_ASC); - } - }); - date.apply(dateR -> { - dateR.get() - .opacityProperty() - .bind(Bindings.createDoubleBinding( - () -> { - if (sortMode.getValue() == StoreSortMode.DATE_ASC - || sortMode.getValue() == StoreSortMode.DATE_DESC) { - return 1.0; - } - return 0.4; - }, - sortMode)); - }); - date.apply(new FancyTooltipAugment<>("sortLastUsed")); - date.shortcut(new KeyCodeCombination(KeyCode.L, KeyCombination.SHORTCUT_DOWN)); - return date; - } - - private Comp createSortButtonBar() { - return new HorizontalComp(List.of(createDateSortButton(), createAlphabeticalSortButton())).apply(struc -> { - struc.get().setMinHeight(40); - struc.get().setPrefHeight(40); - struc.get().setMaxHeight(40); - }).styleClass("bar").styleClass("store-sort-bar"); - } - - @Override - protected Region createSimple() { - return createSortButtonBar().createRegion(); - } -} diff --git a/app/src/main/java/io/xpipe/app/core/AppCache.java b/app/src/main/java/io/xpipe/app/core/AppCache.java index d91f30c4..a13f2e15 100644 --- a/app/src/main/java/io/xpipe/app/core/AppCache.java +++ b/app/src/main/java/io/xpipe/app/core/AppCache.java @@ -50,7 +50,7 @@ public class AppCache { var path = getPath(key); if (Files.exists(path)) { try { - var tree = JsonConfigHelper.readConfig(path); + var tree = JsonConfigHelper.readRaw(path); if (tree.isMissingNode()) { return notPresent.get(); } diff --git a/app/src/main/java/io/xpipe/app/core/AppCharsetter.java b/app/src/main/java/io/xpipe/app/core/AppCharsetter.java index ae84aff9..5ce783f6 100644 --- a/app/src/main/java/io/xpipe/app/core/AppCharsetter.java +++ b/app/src/main/java/io/xpipe/app/core/AppCharsetter.java @@ -2,6 +2,8 @@ package io.xpipe.app.core; import io.xpipe.core.charsetter.Charsetter; import io.xpipe.core.charsetter.StreamCharset; +import io.xpipe.core.util.FailableConsumer; +import io.xpipe.core.util.FailableSupplier; import org.apache.commons.io.ByteOrderMark; import org.apache.commons.io.input.BOMInputStream; @@ -17,7 +19,7 @@ public class AppCharsetter extends Charsetter { Charsetter.INSTANCE = new AppCharsetter(); } - public Result read(FailableSupplier in, FailableConsumer con) + public Result read(FailableSupplier in, FailableConsumer con) throws Exception { checkInit(); diff --git a/app/src/main/java/io/xpipe/app/core/AppExtensionManager.java b/app/src/main/java/io/xpipe/app/core/AppExtensionManager.java index d01b0771..db6d615a 100644 --- a/app/src/main/java/io/xpipe/app/core/AppExtensionManager.java +++ b/app/src/main/java/io/xpipe/app/core/AppExtensionManager.java @@ -47,7 +47,7 @@ public class AppExtensionManager { } if (load) { - INSTANCE.addNativeLibrariesToPath(); + // INSTANCE.addNativeLibrariesToPath(); try { XPipeServiceProviders.load(INSTANCE.extendedLayer); MessageExchangeImpls.loadAll(); diff --git a/app/src/main/java/io/xpipe/app/core/AppGreetings.java b/app/src/main/java/io/xpipe/app/core/AppGreetings.java index 7a7d75bd..6fe40ced 100644 --- a/app/src/main/java/io/xpipe/app/core/AppGreetings.java +++ b/app/src/main/java/io/xpipe/app/core/AppGreetings.java @@ -5,18 +5,13 @@ import io.xpipe.app.comp.base.MarkdownComp; import io.xpipe.app.core.mode.OperationMode; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.util.BindingsHelper; -import io.xpipe.app.issue.ErrorEvent; -import io.xpipe.app.util.Hyperlinks; -import io.xpipe.app.util.MarkdownHelper; import javafx.beans.property.SimpleBooleanProperty; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.*; -import javafx.scene.input.MouseEvent; import javafx.scene.layout.BorderPane; import javafx.stage.Modality; -import java.io.IOException; import java.nio.file.Files; import java.util.List; import java.util.function.UnaryOperator; @@ -39,14 +34,14 @@ public class AppGreetings { return tp; } - private static TitledPane createTos() { + private static TitledPane createEula() { var tp = new TitledPane(); tp.setExpanded(false); - tp.setText(AppI18n.get("tos")); + tp.setText(AppI18n.get("eula")); tp.setAlignment(Pos.CENTER_LEFT); AppFont.normal(tp); - AppResources.with(AppResources.XPIPE_MODULE, "misc/tos.md", file -> { + AppResources.with(AppResources.XPIPE_MODULE, "misc/eula.md", file -> { var md = Files.readString(file); var markdown = new MarkdownComp(md, UnaryOperator.identity()).createRegion(); tp.setContent(markdown); @@ -67,7 +62,7 @@ public class AppGreetings { alert.setAlertType(Alert.AlertType.NONE); alert.initModality(Modality.APPLICATION_MODAL); - var content = List.of(createIntroduction(), createTos()); + var content = List.of(createIntroduction(), createEula()); var accordion = new Accordion(content.toArray(TitledPane[]::new)); accordion.setExpandedPane(content.get(0)); accordion.expandedPaneProperty().addListener((observable, oldValue, newValue) -> { @@ -98,26 +93,6 @@ public class AppGreetings { alert.getDialogPane().setContent(layout); - { - var view = new ButtonType(AppI18n.get("print"), ButtonBar.ButtonData.OTHER); - alert.getButtonTypes().add(view); - Button button = (Button) alert.getDialogPane().lookupButton(view); - button.visibleProperty().bind(read); - button.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> { - try { - var temp = Files.createTempFile("tos", ".html"); - AppResources.with(AppResources.XPIPE_MODULE, "misc/tos.md", file -> { - Files.writeString( - temp, - MarkdownHelper.toHtml(Files.readString(file), UnaryOperator.identity())); - }); - Hyperlinks.open(temp.toUri().toString()); - } catch (IOException e) { - ErrorEvent.fromThrowable(e).handle(); - } - event.consume(); - }); - } { var buttonType = new ButtonType(AppI18n.get("confirm"), ButtonBar.ButtonData.OK_DONE); alert.getButtonTypes().add(buttonType); diff --git a/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java b/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java index 2b69c9af..4175b2ac 100644 --- a/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java +++ b/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java @@ -10,7 +10,10 @@ import io.xpipe.app.util.LicenseProvider; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; +import lombok.Builder; +import lombok.Data; import lombok.Getter; +import lombok.extern.jackson.Jacksonized; import java.util.ArrayList; import java.util.List; @@ -18,6 +21,15 @@ import java.util.List; @Getter public class AppLayoutModel { + @Data + @Builder + @Jacksonized + public static class SavedState { + + double sidebarWidth; + double browserConnectionsWidth; + } + private static AppLayoutModel INSTANCE; public static AppLayoutModel get() { @@ -25,13 +37,22 @@ public class AppLayoutModel { } public static void init() { - INSTANCE = new AppLayoutModel(); + var state = AppCache.get("layoutState", SavedState.class, () -> new SavedState(260, 300)); + INSTANCE = new AppLayoutModel(state); } + public static void reset() { + AppCache.update("layoutState", INSTANCE.savedState); + INSTANCE = null; + } + + @Getter + private final SavedState savedState; private final List entries; private final Property selected; - public AppLayoutModel() { + public AppLayoutModel(SavedState savedState) { + this.savedState = savedState; this.entries = createEntryList(); this.selected = new SimpleObjectProperty<>(entries.get(1)); } diff --git a/app/src/main/java/io/xpipe/app/core/AppMainWindow.java b/app/src/main/java/io/xpipe/app/core/AppMainWindow.java index 26562960..58fe6fb4 100644 --- a/app/src/main/java/io/xpipe/app/core/AppMainWindow.java +++ b/app/src/main/java/io/xpipe/app/core/AppMainWindow.java @@ -182,7 +182,7 @@ public class AppMainWindow { } private void saveState() { - if (!AppPrefs.get().saveWindowLocation.get()) { + if (!AppPrefs.get().saveWindowLocation().get()) { return; } @@ -201,7 +201,7 @@ public class AppMainWindow { } private WindowState loadState() { - if (!AppPrefs.get().saveWindowLocation.get()) { + if (!AppPrefs.get().saveWindowLocation().get()) { return null; } @@ -230,6 +230,9 @@ public class AppMainWindow { } public void initialize() { + stage.setMinWidth(550); + stage.setMinHeight(400); + initializeWindow(); setupListeners(); windowActive.set(true); diff --git a/app/src/main/java/io/xpipe/app/core/AppResources.java b/app/src/main/java/io/xpipe/app/core/AppResources.java index b2af2dad..19f0c21e 100644 --- a/app/src/main/java/io/xpipe/app/core/AppResources.java +++ b/app/src/main/java/io/xpipe/app/core/AppResources.java @@ -13,23 +13,49 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; public class AppResources { public static final String XPIPE_MODULE = "io.xpipe.app"; - private static ModuleFileSystem openFileSystem(String module) throws IOException { + private static final Map fileSystems = new ConcurrentHashMap<>(); + + public static void reset() { + fileSystems.forEach((s, moduleFileSystem) -> { + try { + moduleFileSystem.close(); + } catch (IOException e) { + ErrorEvent.fromThrowable(e).handle(); + } + }); + fileSystems.clear(); + } + + private static ModuleFileSystem openFileSystemIfNeeded(String module) throws IOException { var layer = AppExtensionManager.getInstance() != null ? AppExtensionManager.getInstance().getExtendedLayer() : null; + + // Only cache file systems with extended layer + if (layer != null && fileSystems.containsKey(module)) { + return fileSystems.get(module); + } + if (layer == null) { layer = ModuleLayer.boot(); } - return (ModuleFileSystem) FileSystems.newFileSystem(URI.create("module:/" + module), Map.of("layer", layer)); + + var fs = (ModuleFileSystem) FileSystems.newFileSystem(URI.create("module:/" + module), Map.of("layer", layer)); + if (AppExtensionManager.getInstance() != null) { + fileSystems.put(module, fs); + } + return fs; } public static Optional getResourceURL(String module, String file) { - try (var fs = openFileSystem(module)) { + try { + var fs = openFileSystemIfNeeded(module); var f = fs.getPath(module.replace('.', '/') + "/resources/" + file); var url = f.getWrappedPath().toUri().toURL(); return Optional.of(url); @@ -64,7 +90,8 @@ public class AppResources { private static void withResource(String module, String file, FailableConsumer con) { var path = module.startsWith("io.xpipe") ? module.replace('.', '/') + "/resources/" + file : file; - try (var fs = openFileSystem(module)) { + try { + var fs = openFileSystemIfNeeded(module); var f = fs.getPath(path); con.accept(f); } catch (IOException e) { @@ -73,7 +100,8 @@ public class AppResources { } private static boolean withLocalDevResource(String module, String file, FailableConsumer con) { - try (var fs = openFileSystem(module)) { + try { + var fs = openFileSystemIfNeeded(module); var url = fs.getPath("").getWrappedPath().toUri().toURL(); if (!url.getProtocol().equals("jar")) { return false; diff --git a/app/src/main/java/io/xpipe/app/core/AppSocketServer.java b/app/src/main/java/io/xpipe/app/core/AppSocketServer.java index 0f655701..885ea09f 100644 --- a/app/src/main/java/io/xpipe/app/core/AppSocketServer.java +++ b/app/src/main/java/io/xpipe/app/core/AppSocketServer.java @@ -45,8 +45,9 @@ public class AppSocketServer { } public static void init() { + int port = -1; try { - var port = BeaconConfig.getUsedPort(); + port = BeaconConfig.getUsedPort(); INSTANCE = new AppSocketServer(port); INSTANCE.createSocketListener(); @@ -56,7 +57,7 @@ public class AppSocketServer { .handle(); } catch (Exception ex) { // Not terminal! - ErrorEvent.fromThrowable(ex).build().handle(); + ErrorEvent.fromThrowable(ex).description("Unable to start local socket server on port " + port).build().handle(); } } diff --git a/app/src/main/java/io/xpipe/app/core/AppTheme.java b/app/src/main/java/io/xpipe/app/core/AppTheme.java index 5cdc0897..087f4e0f 100644 --- a/app/src/main/java/io/xpipe/app/core/AppTheme.java +++ b/app/src/main/java/io/xpipe/app/core/AppTheme.java @@ -35,6 +35,7 @@ public class AppTheme { private static final PseudoClass DARK = PseudoClass.getPseudoClass("dark"); private static final PseudoClass PRETTY = PseudoClass.getPseudoClass("pretty"); private static final PseudoClass PERFORMANCE = PseudoClass.getPseudoClass("performance"); + private static boolean init; public static void initThemeHandlers(Window stage) { if (AppPrefs.get() == null) { @@ -60,6 +61,10 @@ public class AppTheme { } public static void init() { + if (init) { + return; + } + if (AppPrefs.get() == null) { Theme.getDefaultLightTheme().apply(); return; @@ -97,6 +102,8 @@ public class AppTheme { AppPrefs.get().theme.addListener((c, o, n) -> { changeTheme(n); }); + + init = true; } private static void setDefault(boolean dark) { diff --git a/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java b/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java index 3110b903..aa0063b7 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java @@ -68,6 +68,7 @@ public class BaseMode extends OperationMode { StoreViewState.reset(); DataStorage.reset(); AppPrefs.reset(); + AppResources.reset(); AppExtensionManager.reset(); AppDataLock.unlock(); // Shut down socket server last to keep a non-daemon thread running diff --git a/app/src/main/java/io/xpipe/app/core/mode/GuiMode.java b/app/src/main/java/io/xpipe/app/core/mode/GuiMode.java index 7be07228..25c8120b 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/GuiMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/GuiMode.java @@ -6,7 +6,6 @@ import io.xpipe.app.core.AppMainWindow; import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.TrackEvent; -import io.xpipe.app.update.CommercializationAlert; import io.xpipe.app.update.UpdateChangelogAlert; import io.xpipe.app.util.UnlockAlert; import javafx.stage.Stage; @@ -24,7 +23,6 @@ public class GuiMode extends PlatformMode { UnlockAlert.showIfNeeded(); UpdateChangelogAlert.showIfNeeded(); - CommercializationAlert.showIfNeeded(); AppGreetings.showIfNeeded(); TrackEvent.info("mode", "Waiting for window setup completion ..."); diff --git a/app/src/main/java/io/xpipe/app/core/mode/PlatformMode.java b/app/src/main/java/io/xpipe/app/core/mode/PlatformMode.java index 16f8dd5e..9ad2fba5 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/PlatformMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/PlatformMode.java @@ -62,6 +62,7 @@ public abstract class PlatformMode extends OperationMode { TrackEvent.info("mode", "Shutting down platform components"); onSwitchFrom(); StoreViewState.reset(); + AppLayoutModel.reset(); PlatformState.teardown(); TrackEvent.info("mode", "Platform shutdown finished"); BACKGROUND.finalTeardown(); diff --git a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java index 0c9dbfe4..b7201346 100644 --- a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java @@ -22,6 +22,10 @@ import java.util.List; public interface DataStoreProvider { + default boolean editByDefault() { + return false; + } + default boolean canMoveCategories() { return true; } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/Comp.java b/app/src/main/java/io/xpipe/app/fxcomps/Comp.java index 4f690869..02dd1849 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/Comp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/Comp.java @@ -1,6 +1,7 @@ package io.xpipe.app.fxcomps; import atlantafx.base.controls.Spacer; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.fxcomps.augment.Augment; import io.xpipe.app.fxcomps.augment.GrowAugment; import io.xpipe.app.fxcomps.util.Shortcuts; @@ -83,6 +84,15 @@ public abstract class Comp> { return apply(struc -> struc.get().setPrefHeight(height)); } + + public Comp maxWidth(int width) { + return apply(struc -> struc.get().setMaxWidth(width)); + } + + public Comp maxHeight(int height) { + return apply(struc -> struc.get().setMaxHeight(height)); + } + public Comp hgrow() { return apply(struc -> HBox.setHgrow(struc.get(), Priority.ALWAYS)); } @@ -130,10 +140,18 @@ public abstract class Comp> { return apply(struc -> struc.get().getStyleClass().add(styleClass)); } + public Comp accessibleText(ObservableValue text) { + return apply(struc -> struc.get().accessibleTextProperty().bind(text)); + } + public Comp accessibleText(String text) { return apply(struc -> struc.get().setAccessibleText(text)); } + public Comp accessibleTextKey(String key) { + return apply(struc -> struc.get().accessibleTextProperty().bind(AppI18n.observable(key))); + } + public Comp grow(boolean width, boolean height) { return apply(GrowAugment.create(width, height)); } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreChoiceComp.java index 919059f5..51efee84 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreChoiceComp.java @@ -6,10 +6,8 @@ import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.store.*; import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppI18n; -import io.xpipe.app.ext.DataStoreProviders; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.SimpleComp; -import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.util.DataStoreCategoryChoiceComp; @@ -23,7 +21,6 @@ import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.geometry.Insets; import javafx.geometry.Pos; -import javafx.scene.control.Label; import javafx.scene.control.MenuButton; import javafx.scene.layout.Region; import javafx.scene.layout.StackPane; @@ -32,7 +29,6 @@ import lombok.RequiredArgsConstructor; import org.kordamp.ikonli.javafx.FontIcon; import java.util.List; -import java.util.Optional; import java.util.function.Predicate; @RequiredArgsConstructor @@ -128,6 +124,7 @@ public class DataStoreChoiceComp extends SimpleComp { StoreCreationMenu.addButtons(m); return m; }) + .accessibleTextKey("addConnection") .padding(new Insets(-2)) .styleClass(Styles.RIGHT_PILL) .grow(false, true); @@ -155,26 +152,6 @@ public class DataStoreChoiceComp extends SimpleComp { return popover; } - protected Region createGraphic(T s) { - var provider = DataStoreProviders.byStore(s); - var imgView = PrettyImageHelper.ofFixedSquare(provider.getDisplayIconFileName(s), 16) - .createRegion(); - - var name = DataStorage.get().getUsableStores().stream() - .filter(e -> e.equals(s)) - .findAny() - .flatMap(store -> { - if (mode == Mode.PROXY && ShellStore.isLocal(store.asNeeded())) { - return Optional.of(AppI18n.get("none")); - } - - return DataStorage.get().getStoreDisplayName(store); - }) - .orElse(AppI18n.get("unknown")); - - return new Label(name, imgView); - } - private String toName(DataStoreEntry entry) { if (entry == null) { return null; @@ -226,7 +203,7 @@ public class DataStoreChoiceComp extends SimpleComp { }) .styleClass("choice-comp"); - var r = button.grow(true, false).createRegion(); + var r = button.grow(true, false).accessibleText("Select connection").createRegion(); var icon = new FontIcon("mdal-keyboard_arrow_down"); icon.setDisable(true); icon.setPickOnBounds(false); diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/FilterComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/FilterComp.java index 2ba0095c..20570897 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/FilterComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/FilterComp.java @@ -28,7 +28,7 @@ public class FilterComp extends Comp { @Override public Structure createBase() { var fi = new FontIcon("mdi2m-magnify"); - var bgLabel = new Label("Search ...", fi); + var bgLabel = new Label("Search", fi); bgLabel.getStyleClass().add("filter-background"); var filter = new TextField(); filter.setAccessibleText("Filter"); diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/OptionsComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/OptionsComp.java index f2c5034f..60fca62a 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/OptionsComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/OptionsComp.java @@ -97,6 +97,7 @@ public class OptionsComp extends Comp> { extendedDescription.getStyleClass().add(Styles.ACCENT); extendedDescription.setPadding(new Insets(0, 6, 0, 6)); extendedDescription.getStyleClass().add("long-description"); + extendedDescription.setAccessibleText("Help"); AppFont.header(extendedDescription); extendedDescription.setOnAction(e -> popover.show(extendedDescription)); diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java index 72d2ac20..a251bd49 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java @@ -1,5 +1,6 @@ package io.xpipe.app.fxcomps.impl; +import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.CountComp; import io.xpipe.app.comp.base.LazyTextFieldComp; import io.xpipe.app.comp.base.ListBoxViewComp; @@ -41,68 +42,52 @@ public class StoreCategoryComp extends SimpleComp { @Override protected Region createSimple() { - var i = Bindings.createStringBinding( - () -> { - if (!DataStorage.get().supportsSharing()) { - return "mdal-keyboard_arrow_right"; - } + var i = Bindings.createStringBinding(() -> { + if (!DataStorage.get().supportsSharing()) { + return "mdal-keyboard_arrow_right"; + } - return category.getShare().getValue() ? - "mdi2a-account-convert" : "mdi2a-account-cancel"; - }, - category.getShare()); + return category.getShare().getValue() ? "mdi2a-account-convert" : "mdi2a-account-cancel"; + }, category.getShare()); var icon = new IconButtonComp(i).apply(struc -> AppFont.small(struc.get())).apply(struc -> { struc.get().setAlignment(Pos.CENTER); struc.get().setPadding(new Insets(0, 0, 6, 0)); + struc.get().setFocusTraversable(false); }); - var name = new LazyTextFieldComp(category.nameProperty()) - .apply(struc -> { - struc.get().prefWidthProperty().unbind(); - struc.get().setPrefWidth(150); - struc.getTextField().minWidthProperty().bind(struc.get().widthProperty()); - }) - .styleClass("name") - .createRegion(); + var name = new LazyTextFieldComp(category.nameProperty()).apply(struc -> { + struc.get().prefWidthProperty().unbind(); + struc.get().setPrefWidth(150); + struc.getTextField().minWidthProperty().bind(struc.get().widthProperty()); + }).styleClass("name").createRegion(); var showing = new SimpleBooleanProperty(); - var settings = new IconButtonComp("mdomz-settings") - .styleClass("settings") - .apply(new ContextMenuAugment<>(mouseEvent -> mouseEvent.getButton() == MouseButton.PRIMARY, () -> { + var settings = new IconButtonComp("mdomz-settings").styleClass("settings").apply( + new ContextMenuAugment<>(mouseEvent -> mouseEvent.getButton() == MouseButton.PRIMARY, () -> { var cm = createContextMenu(name); showing.bind(cm.showingProperty()); return cm; })); - var shownList = BindingsHelper.filteredContentBinding( - category.getContainedEntries(), - storeEntryWrapper -> { - return storeEntryWrapper.shouldShow( - StoreViewState.get().getFilterString().getValue()); - }, - StoreViewState.get().getFilterString()); + var shownList = BindingsHelper.filteredContentBinding(category.getContainedEntries(), storeEntryWrapper -> { + return storeEntryWrapper.shouldShow(StoreViewState.get().getFilterString().getValue()); + }, StoreViewState.get().getFilterString()); var count = new CountComp<>(shownList, category.getContainedEntries(), string -> "(" + string + ")"); var hover = new SimpleBooleanProperty(); - var h = new HorizontalComp(List.of( - icon, - Comp.hspacer(4), - Comp.of(() -> name), - Comp.hspacer(), - count.hide(BindingsHelper.persist(hover.or(showing))), - settings.hide(BindingsHelper.persist(hover.not().and(showing.not()))))); - h.apply(struc -> hover.bind(struc.get().hoverProperty())); - h.apply(struc -> struc.get().setOnMouseClicked(event -> { - category.select(); - event.consume(); - })); - h.apply(new ContextMenuAugment<>( - mouseEvent -> mouseEvent.getButton() == MouseButton.SECONDARY, () -> createContextMenu(name))); + var focus = new SimpleBooleanProperty(); + var h = new HorizontalComp( + List.of(icon, Comp.hspacer(4), Comp.of(() -> name), Comp.hspacer(), count.hide(BindingsHelper.persist(hover.or(showing).or(focus))), + settings.hide(BindingsHelper.persist(hover.not().and(showing.not()).and(focus.not()))))); + h.apply(new ContextMenuAugment<>(mouseEvent -> mouseEvent.getButton() == MouseButton.SECONDARY, () -> createContextMenu(name))); h.padding(new Insets(0, 10, 0, (category.getDepth() * 10))); - h.styleClass("category-button"); - var l = category.getChildren() - .sorted(Comparator.comparing( - storeCategoryWrapper -> storeCategoryWrapper.getName().toLowerCase(Locale.ROOT))); + + var categoryButton = new ButtonComp(null, h.createRegion(), category::select).styleClass("category-button").apply( + struc -> hover.bind(struc.get().hoverProperty())).apply(struc -> focus.bind(struc.get().focusedProperty())).accessibleText( + category.nameProperty()).grow(true, false); + + var l = category.getChildren().sorted(Comparator.comparing(storeCategoryWrapper -> storeCategoryWrapper.getName().toLowerCase(Locale.ROOT))); var children = new ListBoxViewComp<>(l, l, storeCategoryWrapper -> new StoreCategoryComp(storeCategoryWrapper)); var emptyBinding = Bindings.isEmpty(category.getChildren()); - var v = new VerticalComp(List.of(h, Comp.separator().hide(emptyBinding), Comp.vspacer(5).hide(emptyBinding), children.hide(emptyBinding))); + var v = new VerticalComp( + List.of(categoryButton, children.hide(emptyBinding))); v.styleClass("category"); v.apply(struc -> { SimpleChangeListener.apply(StoreViewState.get().getActiveCategory(), val -> { @@ -119,9 +104,7 @@ public class StoreCategoryComp extends SimpleComp { var newCategory = new MenuItem(AppI18n.get("newCategory"), new FontIcon("mdi2p-plus-thick")); newCategory.setOnAction(event -> { - DataStorage.get() - .addStoreCategory( - DataStoreCategory.createNew(category.getCategory().getUuid(), "New category")); + DataStorage.get().addStoreCategory(DataStoreCategory.createNew(category.getCategory().getUuid(), "New category")); }); contextMenu.getItems().add(newCategory); @@ -132,14 +115,14 @@ public class StoreCategoryComp extends SimpleComp { } else { return AppI18n.get("share"); } - },category.getShare())); + }, category.getShare())); share.graphicProperty().bind(Bindings.createObjectBinding(() -> { if (category.getShare().getValue()) { return new FontIcon("mdi2b-block-helper"); } else { return new FontIcon("mdi2s-share"); } - },category.getShare())); + }, category.getShare())); share.setOnAction(event -> { category.getShare().setValue(!category.getShare().getValue()); }); diff --git a/app/src/main/java/io/xpipe/app/prefs/AboutComp.java b/app/src/main/java/io/xpipe/app/prefs/AboutComp.java index 26363e0c..ee17d03c 100644 --- a/app/src/main/java/io/xpipe/app/prefs/AboutComp.java +++ b/app/src/main/java/io/xpipe/app/prefs/AboutComp.java @@ -63,8 +63,8 @@ public class AboutComp extends Comp> { .grow(true, false), null) .addComp( - new TileButtonComp("termsOfService", "termsOfServiceDescription", "mdi2c-card-text-outline", e -> { - Hyperlinks.open(Hyperlinks.TOS); + new TileButtonComp("eula", "eulaDescription", "mdi2c-card-text-outline", e -> { + Hyperlinks.open(Hyperlinks.EULA); e.consume(); }) .grow(true, false), diff --git a/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java b/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java index 2fbb5a21..db1b89c2 100644 --- a/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java +++ b/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java @@ -112,8 +112,7 @@ public class AppPrefs { return connectionTimeOut; } - private final BooleanProperty saveWindowLocationInternal = typed(new SimpleBooleanProperty(false), Boolean.class); - public final ReadOnlyBooleanProperty saveWindowLocation = saveWindowLocationInternal; + private final BooleanProperty saveWindowLocation = typed(new SimpleBooleanProperty(true), Boolean.class); // External terminal // ================= @@ -336,6 +335,10 @@ public class AppPrefs { return windowOpacity; } + public ObservableBooleanValue saveWindowLocation() { + return saveWindowLocation; + } + public ObservableBooleanValue developerDisableUpdateVersionCheck() { return developerDisableUpdateVersionCheckEffective; } @@ -591,7 +594,7 @@ public class AppPrefs { Setting.of("useSystemFont", BooleanField.ofBooleanType(useSystemFontInternal).render(() -> new CustomToggleControl()), useSystemFontInternal), Setting.of("tooltipDelay", tooltipDelayInternal, tooltipDelayMin, tooltipDelayMax), Setting.of("language", languageControl, languageInternal)), - Group.of("windowOptions", Setting.of("saveWindowLocation", BooleanField.ofBooleanType(saveWindowLocationInternal).render(() -> new CustomToggleControl()), saveWindowLocationInternal))), + Group.of("windowOptions", Setting.of("saveWindowLocation", BooleanField.ofBooleanType(saveWindowLocation).render(() -> new CustomToggleControl()), saveWindowLocation))), Category.of( "connections", Group.of( diff --git a/app/src/main/java/io/xpipe/app/prefs/JsonStorageHandler.java b/app/src/main/java/io/xpipe/app/prefs/JsonStorageHandler.java index 8514fd84..13cce2a8 100644 --- a/app/src/main/java/io/xpipe/app/prefs/JsonStorageHandler.java +++ b/app/src/main/java/io/xpipe/app/prefs/JsonStorageHandler.java @@ -33,7 +33,7 @@ public class JsonStorageHandler implements StorageHandler { private JsonNode getContent(String key) { if (content == null) { - content = (ObjectNode) JsonConfigHelper.readConfig(file); + content = JsonConfigHelper.readConfigObject(file); } return content.get(key); } diff --git a/app/src/main/java/io/xpipe/app/prefs/VaultCategory.java b/app/src/main/java/io/xpipe/app/prefs/VaultCategory.java index b127ded6..5d5a948a 100644 --- a/app/src/main/java/io/xpipe/app/prefs/VaultCategory.java +++ b/app/src/main/java/io/xpipe/app/prefs/VaultCategory.java @@ -9,7 +9,6 @@ import com.dlsc.preferencesfx.model.Group; import com.dlsc.preferencesfx.model.Setting; import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.core.AppI18n; -import io.xpipe.app.util.LicenseProvider; import io.xpipe.app.util.LockChangeAlert; import io.xpipe.core.util.XPipeInstallation; import javafx.beans.binding.Bindings; @@ -58,7 +57,7 @@ public class VaultCategory extends AppPrefsCategory { @SneakyThrows public Category create() { - var pro = LicenseProvider.get().getFeature("gitVault").isSupported(); + var pro = true; BooleanField enable = BooleanField.ofBooleanType(prefs.enableGitStorage) .editable(pro) .render(() -> { diff --git a/app/src/main/java/io/xpipe/app/storage/DataStorage.java b/app/src/main/java/io/xpipe/app/storage/DataStorage.java index 1b861941..7248dbd9 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStorage.java @@ -33,7 +33,6 @@ public abstract class DataStorage { public static final UUID LOCAL_ID = UUID.fromString("f0ec68aa-63f5-405c-b178-9a4454556d6b"); private static final String PERSIST_PROP = "io.xpipe.storage.persist"; - private static final String IMMUTABLE_PROP = "io.xpipe.storage.immutable"; private static DataStorage INSTANCE; protected final Path dir; @@ -41,8 +40,10 @@ public abstract class DataStorage { @Getter protected final List storeCategories; + protected final Map storeEntries; + @Getter - protected final Set storeEntries; + protected final Set storeEntriesSet; @Getter @Setter @@ -53,7 +54,8 @@ public abstract class DataStorage { public DataStorage() { this.dir = AppPrefs.get().storageDirectory().getValue(); - this.storeEntries = Collections.newSetFromMap(new ConcurrentHashMap<>()); + this.storeEntries = new ConcurrentHashMap<>(); + this.storeEntriesSet = storeEntries.keySet(); this.storeCategories = new CopyOnWriteArrayList<>(); } @@ -138,7 +140,7 @@ public abstract class DataStorage { var changed = new AtomicBoolean(false); do { changed.set(false); - storeEntries.forEach(dataStoreEntry -> { + storeEntries.keySet().forEach(dataStoreEntry -> { if (makeValid ? dataStoreEntry.tryMakeValid() : dataStoreEntry.tryMakeInvalid()) { changed.set(true); } @@ -241,7 +243,7 @@ public abstract class DataStorage { public void deleteChildren(DataStoreEntry e) { var c = getDeepStoreChildren(e); c.forEach(entry -> entry.finalizeEntry()); - this.storeEntries.removeAll(c); + this.storeEntriesSet.removeAll(c); this.listeners.forEach(l -> l.onStoreRemove(c.toArray(DataStoreEntry[]::new))); refreshValidities(false); saveAsync(); @@ -257,7 +259,7 @@ public abstract class DataStorage { .toList(); toDelete.forEach(entry -> entry.finalizeEntry()); - this.storeEntries.removeAll(toDelete); + this.storeEntriesSet.removeAll(toDelete); this.listeners.forEach(l -> l.onStoreRemove(toDelete.toArray(DataStoreEntry[]::new))); refreshValidities(false); saveAsync(); @@ -286,8 +288,9 @@ public abstract class DataStorage { } public DataStoreEntry addStoreEntryIfNotPresent(@NonNull DataStoreEntry e) { - if (storeEntries.contains(e)) { - return e; + var found = storeEntries.get(e); + if (found != null) { + return found; } var byId = getStoreEntryIfPresent(e.getUuid()).orElse(null); @@ -295,6 +298,10 @@ public abstract class DataStorage { return byId; } + if (getStoreCategoryIfPresent(e.getCategoryUuid()).isEmpty()) { + e.setCategoryUuid(DEFAULT_CATEGORY_UUID); + } + var syntheticParent = getSyntheticParent(e); if (syntheticParent.isPresent()) { addStoreEntryIfNotPresent(syntheticParent.get()); @@ -307,7 +314,7 @@ public abstract class DataStorage { } e.setDirectory(getStoresDir().resolve(e.getUuid().toString())); - this.storeEntries.add(e); + this.storeEntries.put(e, e); displayParent.ifPresent(p -> { p.setChildrenCache(null); }); @@ -321,7 +328,7 @@ public abstract class DataStorage { public void addStoreEntriesIfNotPresent(@NonNull DataStoreEntry... es) { for (DataStoreEntry e : es) { - if (storeEntries.contains(e) || getStoreEntryIfPresent(e.getStore()).isPresent()) { + if (storeEntriesSet.contains(e) || getStoreEntryIfPresent(e.getStore()).isPresent()) { return; } @@ -337,7 +344,7 @@ public abstract class DataStorage { } e.setDirectory(getStoresDir().resolve(e.getUuid().toString())); - this.storeEntries.add(e); + this.storeEntries.put(e, e); displayParent.ifPresent(p -> { p.setChildrenCache(null); }); @@ -379,7 +386,7 @@ public abstract class DataStorage { return; } - storeEntries.forEach(entry -> { + storeEntriesSet.forEach(entry -> { if (entry.getCategoryUuid().equals(cat.getUuid())) { entry.setCategoryUuid(DEFAULT_CATEGORY_UUID); } @@ -459,7 +466,7 @@ public abstract class DataStorage { try { var provider = entry.getProvider(); return Optional.ofNullable(provider.getDisplayParent(entry)) - .filter(dataStoreEntry -> storeEntries.contains(dataStoreEntry)); + .filter(dataStoreEntry -> storeEntriesSet.contains(dataStoreEntry)); } catch (Exception ex) { return Optional.empty(); } @@ -559,7 +566,7 @@ public abstract class DataStorage { } public Optional getStoreEntryIfPresent(@NonNull DataStore store) { - return storeEntries.stream() + return storeEntriesSet.stream() .filter(n -> n.getStore() == store || (n.getStore() != null && Objects.equals(store.getClass(), n.getStore().getClass()) @@ -592,7 +599,7 @@ public abstract class DataStorage { } public Optional getStoreEntryIfPresent(@NonNull String name) { - return storeEntries.stream() + return storeEntriesSet.stream() .filter(n -> n.getName().equalsIgnoreCase(name)) .findFirst(); } @@ -614,7 +621,11 @@ public abstract class DataStorage { } public Optional getStoreEntryIfPresent(UUID id) { - return storeEntries.stream().filter(e -> e.getUuid().equals(id)).findAny(); + return storeEntriesSet.stream().filter(e -> e.getUuid().equals(id)).findAny(); + } + + public Set getStoreEntries() { + return storeEntriesSet; } public DataStoreEntry getOrCreateNewSyntheticEntry(DataStoreEntry parent, String name, DataStore store) { diff --git a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java index 0c1444a0..788aa200 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java @@ -99,6 +99,27 @@ public class DataStoreEntry extends StorageElement { this.storePersistentStateNode = storePersistentState; } + private DataStoreEntry( + Path directory, + UUID uuid, + UUID categoryUuid, + String name, + Instant lastUsed, + Instant lastModified, + DataStore store + ) { + super(directory, uuid, name, lastUsed, lastModified, false); + this.categoryUuid = categoryUuid; + this.store = store; + this.storeNode = null; + this.validity = Validity.COMPLETE; + this.configuration = Configuration.defaultConfiguration(); + this.expanded = false; + this.color = null; + this.provider = null; + this.storePersistentStateNode = null; + } + @Override public boolean equals(Object o) { return o == this || (o instanceof DataStoreEntry e && e.getUuid().equals(getUuid())); @@ -114,6 +135,18 @@ public class DataStoreEntry extends StorageElement { return getName(); } + public static DataStoreEntry createTempWrapper(@NonNull DataStore store) { + return new DataStoreEntry( + null, + UUID.randomUUID(), + DataStorage.get().getSelectedCategory().getUuid(), + UUID.randomUUID().toString(), + Instant.now(), + Instant.now(), + store + ); + } + public static DataStoreEntry createNew(@NonNull String name, @NonNull DataStore store) { return createNew(UUID.randomUUID(), DataStorage.get().getSelectedCategory().getUuid(), name, store); } @@ -121,6 +154,8 @@ public class DataStoreEntry extends StorageElement { @SneakyThrows public static DataStoreEntry createNew( @NonNull UUID uuid, @NonNull UUID categoryUuid, @NonNull String name, @NonNull DataStore store) { + var node = DataStorageWriter.storeToNode(store); + var validity = DataStorageParser.storeFromNode(node) == null ? Validity.LOAD_FAILED : store.isComplete() ? Validity.COMPLETE : Validity.INCOMPLETE; var entry = new DataStoreEntry( null, uuid, @@ -128,9 +163,9 @@ public class DataStoreEntry extends StorageElement { name, Instant.now(), Instant.now(), - DataStorageWriter.storeToNode(store), + node, true, - store.isComplete() ? Validity.COMPLETE : Validity.INCOMPLETE, + validity, Configuration.defaultConfiguration(), null, false, null diff --git a/app/src/main/java/io/xpipe/app/storage/StandardStorage.java b/app/src/main/java/io/xpipe/app/storage/StandardStorage.java index 81b1948d..fe892c83 100644 --- a/app/src/main/java/io/xpipe/app/storage/StandardStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/StandardStorage.java @@ -26,6 +26,8 @@ public class StandardStorage extends DataStorage { @Getter private final GitStorageHandler gitStorageHandler; + private boolean loaded; + StandardStorage() { this.gitStorageHandler = LicenseProvider.get().createStorageHandler(); this.gitStorageHandler.init(dir); @@ -109,7 +111,6 @@ public class StandardStorage extends DataStorage { public synchronized void load() { this.gitStorageHandler.prepareForLoad(); - var newSession = isNewSession(); var storesDir = getStoresDir(); var categoriesDir = getCategoriesDir(); @@ -173,6 +174,12 @@ public class StandardStorage extends DataStorage { storeCategories.add(cat); } + if (getStoreCategoryIfPresent(CUSTOM_SCRIPTS_CATEGORY_UUID).isEmpty()) { + var cat = DataStoreCategory.createNew(ALL_SCRIPTS_CATEGORY_UUID, CUSTOM_SCRIPTS_CATEGORY_UUID, "Custom"); + cat.setDirectory(categoriesDir.resolve(CUSTOM_SCRIPTS_CATEGORY_UUID.toString())); + storeCategories.add(cat); + } + if (getStoreCategoryIfPresent(DEFAULT_CATEGORY_UUID).isEmpty()) { storeCategories.add(new DataStoreCategory( categoriesDir.resolve(DEFAULT_CATEGORY_UUID.toString()), @@ -218,7 +225,7 @@ public class StandardStorage extends DataStorage { entry.setCategoryUuid(null); } - storeEntries.add(entry); + storeEntries.put(entry, entry); } catch (IOException ex) { // IO exceptions are not expected exception.set(ex); @@ -241,7 +248,7 @@ public class StandardStorage extends DataStorage { ErrorEvent.fromThrowable(exception.get()).handle(); } - storeEntries.forEach(dataStoreCategory -> { + storeEntriesSet.forEach(dataStoreCategory -> { if (dataStoreCategory.getCategoryUuid() == null || getStoreCategoryIfPresent(dataStoreCategory.getCategoryUuid()) .isEmpty()) { @@ -253,24 +260,24 @@ public class StandardStorage extends DataStorage { ErrorEvent.fromThrowable(ex).terminal(true).build().handle(); } - var hasFixedLocal = storeEntries.stream().anyMatch(dataStoreEntry -> dataStoreEntry.getUuid().equals(LOCAL_ID)); + var hasFixedLocal = storeEntriesSet.stream().anyMatch(dataStoreEntry -> dataStoreEntry.getUuid().equals(LOCAL_ID)); if (!hasFixedLocal) { var e = DataStoreEntry.createNew( LOCAL_ID, DataStorage.DEFAULT_CATEGORY_UUID, "Local Machine", new LocalStore()); e.setDirectory(getStoresDir().resolve(LOCAL_ID.toString())); e.setConfiguration( StorageElement.Configuration.builder().deletable(false).build()); - storeEntries.add(e); + storeEntries.put(e, e); e.validate(); } var local = DataStorage.get().getStoreEntry(LOCAL_ID); - if (storeEntries.stream().noneMatch(entry -> entry.getColor() != null)) { + if (storeEntriesSet.stream().noneMatch(entry -> entry.getColor() != null)) { local.setColor(DataStoreColor.BLUE); } refreshValidities(true); - storeEntries.forEach(entry -> { + storeEntriesSet.forEach(entry -> { var syntheticParent = getSyntheticParent(entry); syntheticParent.ifPresent(entry1 -> { addStoreEntryIfNotPresent(entry1); @@ -280,8 +287,8 @@ public class StandardStorage extends DataStorage { // Save to apply changes if (!hasFixedLocal) { - storeEntries.removeIf(dataStoreEntry -> !dataStoreEntry.getUuid().equals(LOCAL_ID) && dataStoreEntry.getStore() instanceof LocalStore); - storeEntries.stream().filter(entry -> entry.getValidity() != DataStoreEntry.Validity.LOAD_FAILED).forEach(entry -> { + storeEntriesSet.removeIf(dataStoreEntry -> !dataStoreEntry.getUuid().equals(LOCAL_ID) && dataStoreEntry.getStore() instanceof LocalStore); + storeEntriesSet.stream().filter(entry -> entry.getValidity() != DataStoreEntry.Validity.LOAD_FAILED).forEach(entry -> { entry.dirty = true; entry.setStoreNode(DataStorageWriter.storeToNode(entry.getStore())); }); @@ -289,9 +296,15 @@ public class StandardStorage extends DataStorage { } deleteLeftovers(); + + loaded = true; } public synchronized void save() { + if (!loaded) { + return; + } + this.gitStorageHandler.prepareForSave(); try { @@ -322,7 +335,7 @@ public class StandardStorage extends DataStorage { } }); - storeEntries.stream() + storeEntriesSet.stream() .filter(dataStoreEntry -> dataStoreEntry.shouldSave()) .forEach(e -> { try { diff --git a/app/src/main/java/io/xpipe/app/update/CommercializationAlert.java b/app/src/main/java/io/xpipe/app/update/CommercializationAlert.java deleted file mode 100644 index 077c1492..00000000 --- a/app/src/main/java/io/xpipe/app/update/CommercializationAlert.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.xpipe.app.update; - -import io.xpipe.app.comp.base.MarkdownComp; -import io.xpipe.app.core.*; -import javafx.scene.control.Alert; -import javafx.scene.control.ButtonBar; -import javafx.scene.control.ButtonType; -import javafx.stage.Modality; - -import java.nio.file.Files; -import java.util.function.UnaryOperator; - -public class CommercializationAlert { - - public static void showIfNeeded() { - if (AppState.get().isInitialLaunch()) { - AppCache.update("commercializationSeen", true); - return; - } - - boolean set = AppCache.get("commercializationSeen", Boolean.class, () -> false); - if (set) { - return; - } - - AppWindowHelper.showBlockingAlert( - alert -> { - alert.setTitle(AppI18n.get("news")); - alert.setAlertType(Alert.AlertType.NONE); - alert.initModality(Modality.NONE); - - AppResources.with(AppResources.XPIPE_MODULE, "misc/commercialization.md", file -> { - var md = Files.readString(file); - var markdown = new MarkdownComp(md, UnaryOperator.identity()).createRegion(); - alert.getDialogPane().setContent(markdown); - }); - - alert.getButtonTypes().add(new ButtonType(AppI18n.get("gotIt"), ButtonBar.ButtonData.OK_DONE)); - }); - - AppCache.update("commercializationSeen", true); - } -} diff --git a/app/src/main/java/io/xpipe/app/util/Hyperlinks.java b/app/src/main/java/io/xpipe/app/util/Hyperlinks.java index 5855c606..5515bc22 100644 --- a/app/src/main/java/io/xpipe/app/util/Hyperlinks.java +++ b/app/src/main/java/io/xpipe/app/util/Hyperlinks.java @@ -4,17 +4,13 @@ import io.xpipe.app.issue.ErrorEvent; public class Hyperlinks { - public static final String WEBSITE = "https://xpipe.io"; public static final String DOCUMENTATION = "https://docs.xpipe.io"; public static final String GITHUB = "https://github.com/xpipe-io/xpipe"; - public static final String ROADMAP = "https://xpipe.kampsite.co/"; - public static final String PRIVACY = "https://github.com/xpipe-io/xpipe/blob/master/PRIVACY.md"; - public static final String TOS = "https://github.com/xpipe-io/xpipe/blob/master/app/src/main/resources/io/xpipe/app/resources/misc/tos.md"; - public static final String SECURITY = "https://github.com/xpipe-io/xpipe/blob/master/SECURITY.md"; + public static final String PRIVACY = "https://docs.xpipe.io/privacy-policy"; + public static final String EULA = "https://docs.xpipe.io/end-user-license-agreement"; + public static final String SECURITY = "https://docs.xpipe.io/security"; public static final String DISCORD = "https://discord.gg/8y89vS8cRb"; - public static final String SLACK = - "https://join.slack.com/t/XPipe/shared_invite/zt-1awjq0t5j-5i4UjNJfNe1VN4b_auu6Cg"; - public static final String DOCS_PRIVACY = "https://github.com/xpipe-io/xpipe/blob/master/PRIVACY.md"; + public static final String SLACK = "https://join.slack.com/t/XPipe/shared_invite/zt-1awjq0t5j-5i4UjNJfNe1VN4b_auu6Cg"; static final String[] browsers = {"xdg-open", "google-chrome", "firefox", "opera", "konqueror", "mozilla"}; diff --git a/app/src/main/java/io/xpipe/app/util/JfxHelper.java b/app/src/main/java/io/xpipe/app/util/JfxHelper.java index 2a42d3f6..3fbcc9e9 100644 --- a/app/src/main/java/io/xpipe/app/util/JfxHelper.java +++ b/app/src/main/java/io/xpipe/app/util/JfxHelper.java @@ -1,10 +1,10 @@ package io.xpipe.app.util; +import atlantafx.base.controls.Spacer; import io.xpipe.app.core.AppFont; import io.xpipe.app.fxcomps.impl.PrettyImageHelper; import javafx.beans.binding.Bindings; import javafx.geometry.Pos; -import javafx.scene.Node; import javafx.scene.control.Label; import javafx.scene.layout.HBox; import javafx.scene.layout.Region; @@ -14,10 +14,6 @@ import org.kordamp.ikonli.javafx.FontIcon; public class JfxHelper { - public static void fontSize(Node node, double relativeSize) { - node.setStyle(node.getStyle() + "-fx-font-size: " + (relativeSize) + "em;"); - } - public static Region createNamedEntry(String nameString, String descString) { var header = new Label(nameString); AppFont.header(header); @@ -61,18 +57,18 @@ public class JfxHelper { AppFont.header(header); var desc = new Label(descString); AppFont.small(desc); - var text = new VBox(header, desc); - text.setSpacing(2); + var text = new VBox(header, new Spacer(), desc); if (image == null) { return text; } - var size = AppFont.getPixelSize(1) + AppFont.getPixelSize(-2) + 8; + var size = 40; var graphic = PrettyImageHelper.ofFixedSquare(image, (int) size).createRegion(); var hbox = new HBox(graphic, text); hbox.setAlignment(Pos.CENTER_LEFT); + hbox.setFillHeight(true); hbox.setSpacing(10); // graphic.fitWidthProperty().bind(Bindings.createDoubleBinding(() -> header.getHeight() + diff --git a/app/src/main/java/io/xpipe/app/util/JsonConfigHelper.java b/app/src/main/java/io/xpipe/app/util/JsonConfigHelper.java index 8a3d3765..4c07a20d 100644 --- a/app/src/main/java/io/xpipe/app/util/JsonConfigHelper.java +++ b/app/src/main/java/io/xpipe/app/util/JsonConfigHelper.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.util.JacksonMapper; import org.apache.commons.io.FileUtils; @@ -17,17 +18,27 @@ import java.nio.file.Path; public class JsonConfigHelper { - public static JsonNode readConfig(Path in) { - JsonNode node = JsonNodeFactory.instance.objectNode(); + public static JsonNode readRaw(Path in) { try { if (Files.exists(in)) { ObjectMapper o = JacksonMapper.getDefault(); - node = o.readTree(Files.readAllBytes(in)); + var read = o.readTree(Files.readAllBytes(in)); + return read; } } catch (IOException e) { ErrorEvent.fromThrowable(e).build().handle(); } - return node; + return JsonNodeFactory.instance.missingNode(); + } + + public static ObjectNode readConfigObject(Path in) { + var read = readRaw(in); + // Check the results of loading fails + if (read.isObject()) { + return (ObjectNode) read; + } + + return JsonNodeFactory.instance.objectNode(); } public static void writeConfig(Path out, JsonNode node) { diff --git a/app/src/main/java/io/xpipe/app/util/ScanAlert.java b/app/src/main/java/io/xpipe/app/util/ScanAlert.java index 2b8a3733..f890d5a8 100644 --- a/app/src/main/java/io/xpipe/app/util/ScanAlert.java +++ b/app/src/main/java/io/xpipe/app/util/ScanAlert.java @@ -48,9 +48,13 @@ public class ScanAlert { var providers = ScanProvider.getAll(); var applicable = new ArrayList(); for (ScanProvider scanProvider : providers) { - ScanProvider.ScanOperation operation = scanProvider.create(entry, sc); - if (operation != null) { - applicable.add(operation); + try { + ScanProvider.ScanOperation operation = scanProvider.create(entry, sc); + if (operation != null) { + applicable.add(operation); + } + } catch (Exception ex) { + ErrorEvent.fromThrowable(ex).handle(); } } return applicable; @@ -62,125 +66,97 @@ public class ScanAlert { } private static void show( - DataStoreEntry initialStore, Function> applicable) { + DataStoreEntry initialStore, Function> applicable + ) { var entry = new SimpleObjectProperty>(); var selected = new SimpleListProperty(FXCollections.observableArrayList()); var loading = new SimpleBooleanProperty(); Platform.runLater(() -> { - var stage = AppWindowHelper.sideWindow( - AppI18n.get("scanAlertTitle"), - window -> { - return new MultiStepComp() { + var stage = AppWindowHelper.sideWindow(AppI18n.get("scanAlertTitle"), window -> { + return new MultiStepComp() { - private final StackPane stackPane = new StackPane(); + private final StackPane stackPane = new StackPane(); - { - stackPane.getStyleClass().add("scan-list"); - } + { + stackPane.getStyleClass().add("scan-list"); + } + @Override + protected List setup() { + return List.of(new Entry(AppI18n.observable("a"), new Step<>() { @Override - protected List setup() { - return List.of(new Entry(AppI18n.observable("a"), new Step<>() { - @Override - public CompStructure createBase() { - var b = new OptionsBuilder() - .name("scanAlertChoiceHeader") - .description("scanAlertChoiceHeaderDescription") - .addComp(new DataStoreChoiceComp<>( - DataStoreChoiceComp.Mode.OTHER, - null, - entry, - ShellStore.class, - store1 -> true, - StoreViewState.get().getAllConnectionsCategory() - ) - .disable(new SimpleBooleanProperty(initialStore != null))) - .name("scanAlertHeader") - .description("scanAlertHeaderDescription") - .addComp(Comp.of(() -> stackPane).vgrow()) - .buildComp() - .prefWidth(500) - .prefHeight(600) - .styleClass("window-content") - .apply(struc -> { - VBox.setVgrow(struc.get().getChildren().get(1), ALWAYS); - }) - .createStructure() - .get(); + public CompStructure createBase() { + var b = new OptionsBuilder().name("scanAlertChoiceHeader").description("scanAlertChoiceHeaderDescription").addComp( + new DataStoreChoiceComp<>(DataStoreChoiceComp.Mode.OTHER, null, entry, ShellStore.class, store1 -> true, + StoreViewState.get().getAllConnectionsCategory()).disable( + new SimpleBooleanProperty(initialStore != null))).name("scanAlertHeader").description( + "scanAlertHeaderDescription").addComp(Comp.of(() -> stackPane).vgrow()).buildComp().prefWidth(500).prefHeight( + 600).styleClass("window-content").apply(struc -> { + VBox.setVgrow(struc.get().getChildren().get(1), ALWAYS); + }).createStructure().get(); - entry.addListener((observable, oldValue, newValue) -> { - selected.clear(); - stackPane.getChildren().clear(); + entry.addListener((observable, oldValue, newValue) -> { + selected.clear(); + stackPane.getChildren().clear(); - if (newValue == null) { - return; - } - - ThreadHelper.runAsync(() -> { - BooleanScope.execute(loading, () -> { - var a = applicable.apply(entry.get().get()); - - Platform.runLater(() -> { - if (a == null) { - window.close(); - return; - } - - selected.setAll(a.stream() - .filter( - scanOperation -> - scanOperation.isDefaultSelected()) - .toList()); - var r = new ListSelectorComp<>( - a, - scanOperation -> - AppI18n.get(scanOperation.getNameKey()), - selected, - a.size() > 3 - ) - .createRegion(); - stackPane.getChildren().add(r); - }); - }); - }); - }); - - entry.set(initialStore != null ? initialStore.ref() : null); - return new SimpleCompStructure<>(b); - } - })); - } - - @Override - protected void finish() { - ThreadHelper.runAsync(() -> { - if (entry.get() == null) { + if (newValue == null) { return; } + ThreadHelper.runAsync(() -> { + BooleanScope.execute(loading, () -> { + var a = applicable.apply(entry.get().get()); - Platform.runLater(() -> { - window.close(); - }); + Platform.runLater(() -> { + if (a == null) { + window.close(); + return; + } - BooleanScope.execute(loading, () -> { - entry.get().get().setExpanded(true); - - for (var a : selected) { - try { - a.getScanner().run(); - } catch (Exception ex) { - ErrorEvent.fromThrowable(ex).handle(); - } - } + selected.setAll(a.stream().filter(scanOperation -> scanOperation.isDefaultSelected()).toList()); + var r = new ListSelectorComp<>(a, scanOperation -> AppI18n.get(scanOperation.getNameKey()), selected, + a.size() > 3).createRegion(); + stackPane.getChildren().add(r); + }); + }); }); }); + + entry.set(initialStore != null ? initialStore.ref() : null); + return new SimpleCompStructure<>(b); } - }; - }, - false, - loading); + })); + } + + @Override + protected void finish() { + ThreadHelper.runAsync(() -> { + if (entry.get() == null) { + return; + } + + + Platform.runLater(() -> { + window.close(); + }); + + BooleanScope.execute(loading, () -> { + entry.get().get().setExpanded(true); + + var copy = new ArrayList<>(selected); + for (var a : copy) { + try { + a.getScanner().run(); + } catch (Exception ex) { + ErrorEvent.fromThrowable(ex).handle(); + } + } + }); + }); + } + }; + }, false, loading); stage.show(); }); } diff --git a/app/src/main/java/io/xpipe/app/util/SecretRetrievalStrategyHelper.java b/app/src/main/java/io/xpipe/app/util/SecretRetrievalStrategyHelper.java index 3ec3929b..ab59c4ec 100644 --- a/app/src/main/java/io/xpipe/app/util/SecretRetrievalStrategyHelper.java +++ b/app/src/main/java/io/xpipe/app/util/SecretRetrievalStrategyHelper.java @@ -34,7 +34,7 @@ public class SecretRetrievalStrategyHelper { var content = new HorizontalComp(List.of( new TextFieldComp(keyProperty).apply(struc -> struc.get().setPromptText("Password key")).hgrow(), new ButtonComp(null, new FontIcon("mdomz-settings"), () -> { - AppPrefs.get().selectCategory(4); + AppPrefs.get().selectCategory(5); App.getApp().getStage().requestFocus(); }) .grow(false, true))) @@ -63,38 +63,41 @@ public class SecretRetrievalStrategyHelper { p); } - public static OptionsBuilder comp(Property s) { + public static OptionsBuilder comp(Property s, boolean allowNone) { SecretRetrievalStrategy strat = s.getValue(); var inPlace = new SimpleObjectProperty<>(strat instanceof SecretRetrievalStrategy.InPlace i ? i : null); var passwordManager = new SimpleObjectProperty<>(strat instanceof SecretRetrievalStrategy.PasswordManager i ? i : null); var customCommand = new SimpleObjectProperty<>(strat instanceof SecretRetrievalStrategy.CustomCommand i ? i : null); - var command = new SimpleObjectProperty<>(strat instanceof SecretRetrievalStrategy.CustomCommand c ? c : null); var map = new LinkedHashMap(); - map.put("none", new OptionsBuilder()); + if (allowNone) { + map.put("none", new OptionsBuilder()); + } map.put("password", inPlace(inPlace)); map.put("passwordManager", passwordManager(passwordManager)); map.put("customCommand", customCommand(customCommand)); map.put("prompt", new OptionsBuilder()); + + int offset = allowNone ? 0 : -1; var selected = new SimpleIntegerProperty( strat instanceof SecretRetrievalStrategy.None - ? 0 + ? offset : strat instanceof SecretRetrievalStrategy.InPlace - ? 1 + ? offset + 1 : strat instanceof SecretRetrievalStrategy.PasswordManager - ? 2 + ? offset + 2 : strat instanceof SecretRetrievalStrategy.CustomCommand - ? 3 + ? offset + 3 : strat instanceof SecretRetrievalStrategy.Prompt - ? 4 + ? offset + 4 : strat == null ? -1 : 0); return new OptionsBuilder() .choice(selected, map) .bindChoice( () -> { - return switch (selected.get()) { - case 0 -> new SimpleObjectProperty<>(new SecretRetrievalStrategy.None()); + return switch (selected.get() - offset) { + case 0 -> new SimpleObjectProperty<>(allowNone ? new SecretRetrievalStrategy.None() : null); case 1 -> inPlace; case 2 -> passwordManager; case 3 -> customCommand; diff --git a/app/src/main/java/io/xpipe/app/util/WindowsRegistry.java b/app/src/main/java/io/xpipe/app/util/WindowsRegistry.java index f228cfd7..98221d33 100644 --- a/app/src/main/java/io/xpipe/app/util/WindowsRegistry.java +++ b/app/src/main/java/io/xpipe/app/util/WindowsRegistry.java @@ -3,6 +3,8 @@ package io.xpipe.app.util; import com.sun.jna.platform.win32.Advapi32Util; import com.sun.jna.platform.win32.WinReg; import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.core.process.CommandBuilder; +import io.xpipe.core.process.ShellControl; import java.util.Optional; @@ -30,4 +32,30 @@ public class WindowsRegistry { return Optional.empty(); } } + + public static Optional readRemoteString(ShellControl shellControl, int hkey, String key, String valueName) throws Exception { + var command = CommandBuilder.of().add("reg", "query").addQuoted((hkey == HKEY_LOCAL_MACHINE ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER") + "\\" + key).add("/v").addQuoted(valueName); + + String output; + try (var c = shellControl.command(command).start()) { + output = c.readStdoutDiscardErr(); + if (c.getExitCode() != 0) { + return Optional.empty(); + } + } + + // Output has the following format: + // \n\n\n\t\t + if (output.contains("\t")) { + String[] parsed = output.split("\t"); + return Optional.of(parsed[parsed.length - 1]); + } + + if (output.contains(" ")) { + String[] parsed = output.split(" "); + return Optional.of(parsed[parsed.length - 1]); + } + + return Optional.empty(); + } } \ No newline at end of file diff --git a/app/src/main/resources/io/xpipe/app/resources/lang/dscreation_en.properties b/app/src/main/resources/io/xpipe/app/resources/lang/dscreation_en.properties index 60f2b952..6217a4ae 100644 --- a/app/src/main/resources/io/xpipe/app/resources/lang/dscreation_en.properties +++ b/app/src/main/resources/io/xpipe/app/resources/lang/dscreation_en.properties @@ -53,7 +53,7 @@ addAutomatically=Search Automatically ... addOther=Add Other ... addStreamTitle=Add Stream Store addConnection=Add Connection -addConnections=Add Connections ... +addConnections=New selectType=Select Type selectTypeDescription=Select connection type selectDatabaseType=Database Type diff --git a/app/src/main/resources/io/xpipe/app/resources/lang/preferences_en.properties b/app/src/main/resources/io/xpipe/app/resources/lang/preferences_en.properties index de6a863e..ed4aac77 100644 --- a/app/src/main/resources/io/xpipe/app/resources/lang/preferences_en.properties +++ b/app/src/main/resources/io/xpipe/app/resources/lang/preferences_en.properties @@ -18,8 +18,7 @@ selectAll=Select all command=Command advanced=Advanced thirdParty=Open source notices -termsOfService=Terms of service -termsOfServiceDescription=Read the terms of service for the XPipe application +eulaDescription=Read the End User License Agreement for the XPipe application thirdPartyDescription=View the open source licenses of third-party libraries workspaceLock=Master passphrase enableGitStorage=Enable git storage @@ -52,7 +51,7 @@ exit=Quit XPipe continueInBackground=Continue in background minimizeToTray=Minimize to tray closeBehaviourAlertTitle=Set closing behaviour -closeBehaviourAlertTitleHeader=Select what should happen when closing the window. Any active tunnels will be closed when the application is shut down. +closeBehaviourAlertTitleHeader=Select what should happen when closing the window. Any active connections will be closed when the application is shut down. startupBehaviour=Startup behaviour startupBehaviourDescription=Controls the default behavior of the desktop application when XPipe is started. clearCachesAlertTitle=Clean Cache diff --git a/app/src/main/resources/io/xpipe/app/resources/lang/translations_en.properties b/app/src/main/resources/io/xpipe/app/resources/lang/translations_en.properties index f6cf6070..c3ae3c2e 100644 --- a/app/src/main/resources/io/xpipe/app/resources/lang/translations_en.properties +++ b/app/src/main/resources/io/xpipe/app/resources/lang/translations_en.properties @@ -228,7 +228,7 @@ updateAvailableTooltip=Update available visitGithubRepository=Visit GitHub repository updateAvailable=Update available: $VERSION$ downloadUpdate=Download update -legalAccept=I accept the terms of service +legalAccept=I accept the End User License Agreement confirm=Confirm print=Print whatsNew=What's new in version $VERSION$? @@ -236,8 +236,7 @@ antivirusNoticeTitle=A note on Antivirus programs updateChangelogAlertTitle=Changelog greetingsAlertTitle=Welcome to XPipe gotIt=Got It -eula=End-user license agreement -tos=Terms of service +eula=End User License Agreement news=News introduction=Introduction privacyPolicy=Privacy Policy diff --git a/app/src/main/resources/io/xpipe/app/resources/misc/commercialization.md b/app/src/main/resources/io/xpipe/app/resources/misc/commercialization.md deleted file mode 100644 index 041a01cc..00000000 --- a/app/src/main/resources/io/xpipe/app/resources/misc/commercialization.md +++ /dev/null @@ -1,21 +0,0 @@ -# Announcement - -XPipe has been out now for a few months and during that time I received a lot of feedback and a small community formed. -This helped me to get a lot of insight into the users, use cases, and requirements, and I was able to constantly improve XPipe. - -## Going full-time - -The demand for XPipe so far also convinced that there is a market to develop XPipe full-time and finance it by providing commercial and enterprise plans for interested customers. So I decided to go for it! This will improve the development speed and quality as I can now fully focus creating the best possible application. - -I think a lot of software users have been scarred by such announcements of projects going commercial as that usually results in features being paywalled and changing licenses. I can assure you though that this is not the case with XPipe. The scope is fairly small and only involves me, so no investors or other employees. This drastically lowers the break-even value compared to other products and allows me to implement a more lenient commercialization. - -## What does this mean for me? - -Essentially, you can use all current features without any limitation for free, unless you use it for commercial purposes, which now requires a professional license upgrade. Furthermore, most upcoming features will also be included in the free version. The only exception are features purposefully made for team collaboration and tools only used in enterprises. For now, the only professional-exclusive feature is the newly added git repository storage, which allows you to share your XPipe configurations with others via your own git remote repositories. The open source model and license also won't change. Some professional-exclusive features will probably not be included in the repository though. - -So if you intend to use XPipe in commercial contexts, I would like you to ask to buy a professional license for that. You can of course also do that if you want to support the project without any commercial intentions. - -## Outlook - -I hope that everything works out and that I can make this endeavor work. That way I can continuously keep improving XPipe! -There are a lot of cool new features already in the pipeline that will be released relatively soon. \ No newline at end of file diff --git a/app/src/main/resources/io/xpipe/app/resources/misc/eula.md b/app/src/main/resources/io/xpipe/app/resources/misc/eula.md new file mode 100644 index 00000000..d00b7bd1 --- /dev/null +++ b/app/src/main/resources/io/xpipe/app/resources/misc/eula.md @@ -0,0 +1,65 @@ +# End User License Agreement + +## Preamble + +This end user license agreement (hereinafter “**EULA**”) is a license agreement between you as the end user and **XPipe UG (haftungsbeschränkt)**, Reichertshalde 81, 71642 Ludwigsburg, (hereinafter “**XPipe**”) for the use of the products “XPipe”, a server connection and server management software, which was developed by XPipe (hereinafter “**Software**”). + +This document can be viewed and printed out at any time in the XPipe desktop application or at http://docs.xpipe.io/end-user-license-agreement. The customer is independently responsible for saving the text of the contract at the time the contract is concluded. No copies will be provided by XPipe after the fact. + +## § 1 Subject matter and validity of the EULA + +(1) The EULA governs the terms under which you may use the Software. By accepting the EULA or using the Software, you agree to be bound by the terms of the EULA. + +(2) This EULA does not establish a service relationship between XPipe and you in return for payment. The payment of a license fee is solely the subject of the contractual relationship between you and the payment service provider Lemonsqueezy, to whom you pay license fees and in return we grant you a right to use additional software features of the professional plan. “Lemonsqueezy” collectively means Lemon Squeezy, LLC, 222 South Main Street Suite 500, Salt Lake City, Utah. Lemon Squeezy, LLC is a global payment service provider that facilitates online transactions using common online payment methods and acts as the seller of the product. + +## § 2 License + +(1) By entering into the EULA, you receive the non-exclusive, non-transferable and non-sublicensable right, unlimited in time, to run the Software installed on a computer in machine-readable format in accordance with the terms of the EULA (“License”). + +(2) The rights granted with the license include the right to obtain updates of the software provided by XPipe for the period of an active subscription. The use of updates is voluntary. Insofar as new software functions are introduced with an update, this does not justify any claim by you that these will also be maintained with future updates. + +## § 3 Provision of the Software, Activation of the Subscription + +(1) The software is made available by you downloading it from the XPipe website and installing it independently on your device. XPipe itself owes you neither provision nor installation or integration of the software on a computer. + +(2) Any active subscription is checked for validity each time the program is started. For this purpose, an Internet connection is required at least once a week when the program is started. Any circumvention of a subscription activation and any unauthorized use of the software not authorized by XPipe and in violation of this EULA is prohibited. + +(3) Activation of a subscription is done individually for you as an end user, and the activated subscription is verified when the program is started. You may install the software on multiple computers. + +(4) Any circumvention of the aforementioned activation is prohibited. + +## § 4 Rights to the Software + +(1) Subject to the terms of any license granted and except as expressly provided in this EULA or otherwise agreed, you acquire no rights in the Software or Documentation. All Software and Documentation provided by XPipe, all copies, compilations, derivative products, programmatic enhancements, patches, revisions and updates to or relating to the Software, and all patent, utility model, trademark, design and copyright, trade secret, trade name and any other invention, design and information protected by law contained in any of the foregoing are and shall remain the property or ownership of XPipe. + +(2) You are prohibited from asserting the rights set forth in § 5 (1) or claims for the granting of any of the aforementioned rights to the Software or the Documentation and, in particular, from registering or claiming intellectual property rights to the Software against XPipe or third parties. + +(3) With the exception of §§ 69d, 69e UrhG, the customer is prohibited from attempting to reconstruct, decompile or decrypt any source code or underlying ideas or algorithms of any software or to permit a third party to do so. Except as otherwise provided in this EULA, or as otherwise expressly agreed between the parties, you may not modify the Software, make it available for use by third parties against payment, sublet it, or otherwise transfer any rights of use to third parties. Your right to execute the software installed on a specific computer in accordance with this EULA remains unaffected. + +(4) You are obligated to notify XPipe immediately of any violations of these provisions or any other violations of XPipe's rights to the software that are known to you or become known to you in the future. + +## § 5 No warranty + +XPipe does not warrant to you that the software has a certain quality or a certain scope of functions and is free of defects. + +## § 6 Liability + +(1) XPipe shall be liable without limitation in the event of (i) intent and gross negligence, (ii) for injury to life, limb and health, (iii) in accordance with the provisions of the Product Liability Act, from Art. 82 of Regulation 2016/670/EU (DSGVO) or other mandatory statutory liability provisions in accordance with the standards set forth therein, and (iv) to the extent of any warranty assumed. + +(2) XPipe shall further be liable for culpable breach of a material contractual obligation, the fulfillment of which is a prerequisite for proper performance of the contract and compliance with which the contractual partner may regularly rely on (“cardinal obligation”), but in the event of simple (minor) negligence limited to the damage reasonably to be expected and foreseeable at the time of conclusion of the contract. + +(3) XPipe shall have no further liability. + +(4) The above limitation of liability shall also apply to the personal liability of employees, representatives and members of XPipe's governing bodies. + +## § 7 Data protection + +XPipe is obligated to comply with the applicable data protection regulations. Information on data protection and the processing of personal data by XPipe can be found in the privacy policy for the Software: https://docs.xpipe.io/privacy-policy + +## § 8 Final provisions + +(2) Neither party may transfer or assign this EULA in whole or any rights or obligations hereunder without the prior written consent of the other party. Any such transfer or assignment shall be void. Notwithstanding the foregoing, (i) a party may assign this agreement to a third party that assumes all or substantially all of its related business activities as a result of a merger, sale of shares or assets, or similar transaction, and (ii) XPipe may use third parties to perform its obligations under this agreement, provided that XPipe shall remain liable for any breach of such obligations. + +(3) This EULA shall be governed by the laws of the Federal Republic of Germany, excluding the United Nations Convention on Contracts for the International Sale of Goods (CISG) and conflict of law provisions. The place of performance and jurisdiction shall be Stuttgart, Germany. + +(4) If any provision of this EULA is invalid, void or unenforceable under any present or future law, the remainder of this EULA shall continue in full force and effect. To the extent that the invalid, void or unenforceable provision is a material term of the agreement, the parties agree to jointly negotiate a valid alternative provision. diff --git a/app/src/main/resources/io/xpipe/app/resources/misc/tos.md b/app/src/main/resources/io/xpipe/app/resources/misc/tos.md deleted file mode 100644 index 7122dfa7..00000000 --- a/app/src/main/resources/io/xpipe/app/resources/misc/tos.md +++ /dev/null @@ -1,149 +0,0 @@ -## Terms of Service - -XPipe UG (haftungsbeschränkt), located at Reichertshalde 81, 71642 Ludwigsburg, Germany ("XPipe") specializes in server connection and server management solutions and offers the XPipe desktop application software. - -The customer intends to use XPipe's server connection management software for private or business purposes. To enable the customer to use the software, the customer is granted a non-exclusive, non-transferable, time-limited right to use the software in accordance with these terms of service ("Terms of Service"). - -The Terms of Service can be viewed and printed out at any time in the XPipe desktop application or at http://docs.xpipe.io/terms-of-service. The customer is independently responsible for saving the text of the contract at the time the contract is concluded. No copies will be provided by XPipe after the fact. - -## 1. Subject of the agreement - -**1.1** Subject to these Terms of Service and the service description, XPipe grants customer access to the products in accordance with the service description and applicable documentation for the term of this agreement. - -**1.2** The customer shall pay XPipe the agreed remuneration as specified in the online purchase process or in the order form, insofar as the customer receives services that are marked as subject to a charge upon conclusion of the contract. - -## 2. Scope - -**2.1** The XPipe desktop application for server and server connection management ("Software") is an offer of XPipe UG (haftungsbeschränkt) (hereinafter: "XPipe" or "we"). - -**2.2** These Terms of Service shall apply to the contractual relationship between XPipe and the User (hereinafter: "User" or "you") regarding the use of this offer. Deviating Terms of Service or deviating conditions of the User shall not become part of the contract, even if XPipe does not expressly object to them. - -## 3. Conclusion of contract and contractual relationships; Registration requirements; Modifications of the Terms of Service - -**3.1** By clicking on the button "start trial" or "submit order" on the shop page at https://buy.xpipe.io you submit an offer to us to order the paid subscriptions and/or free trial offers selected by you in a legally binding manner and subject to payment. A contract for the services ordered by you comes into effect with our order confirmation, which we send to the e-mail address specified by you in the order immediately after receiving your order. Please check your SPAM folder regularly after placing your order with us in order to avoid that our order confirmation is directed there by your IT systems and remains unnoticed. With the order confirmation, you will also receive the license keys required to activate the subscriptions you ordered. - -**3.2** XPipe shall not store the terms and conditions of the contract for the User, without prejudice to the fulfillment of the statutory information obligations. - -**3.3** The User must have full legal capacity or act with the consent of his legal representative. In any case, the User must be at least 18 years old. - -**3.4** XPipe reserves the right to amend these Terms of Service even after conclusion of the contract with effect for existing contractual relationships, provided that this appears necessary to safeguard the legitimate interests of XPipe, is not unreasonable for the User and the User is not disadvantaged thereby contrary to good faith. XPipe shall consider changes to be reasonable that (i) are exclusively beneficial to the User, (ii) are necessary due to purely technical changes, (iii) are necessary due to a change in the applicable or newly introduced legal situation, (iv) must be made due to a court decision or official order against us, or (v) insofar as we introduce additional services, services or service components that require a service description in the Terms of Service. Explicitly excluded from the foregoing right to make changes are changes that result in a change in the character of the main contractual service owed by us that is disadvantageous to the User. To this end, XPipe shall inform users of the changes in text form at least four weeks before the new terms and conditions come into effect. Users shall have the opportunity to object to the changes. In this case, both parties shall have an extraordinary right of termination. If no objection is made, the changes shall be deemed approved four weeks after receipt of the notification. XPipe shall inform the User of the right to object and the effect of silence in the notification. The User's right of termination pursuant to clause 7 shall remain unaffected. - -## 4. Service description and scope - -**4.1** Insofar as a payment or paid subscription agreement has been concluded, XPipe shall provide the agreed services. Insofar as XPipe also provides content and/or services voluntarily and free of charge, it shall do so without assuming any legal obligation. XPipe shall be entitled to change, expand or limit these services at any time. - -**4.2** XPipe guarantees an availability of 99% or higher, based on the calendar year, for the server for downloading the Software (this currently corresponds to the XPipe website) as well as for the server for registration and/or obtaining licenses. Not included are downtimes caused by necessary maintenance work, force majeure, technical disruptions of the Internet or other reasons for which XPipe is not responsible. - -**4.3** XPipe assumes no obligation to back up data for the User and makes no representations, warranties or guarantees beyond those required by law, unless otherwise agreed in individual cases. - -## 5. Duties and responsibilities of the Users; Improper conduct - -**5.1** The User may use XPipe's offer exclusively for the agreed purpose, whether private or business. In particular, the customer may not use the data, information or services provided to him/her for the following purposes without the express written consent of XPipe and shall not permit third parties to do so: - -- (a) for all illegal activities, especially circumvention of export control laws and regulations. - -- (b) to the production of programs, writings and the like, if thereby rights of third parties are injured; - -- (c) for decompiling and reverse engineering the program code. - -**5.2** The User undertakes to provide truthful and complete information upon registration and to keep this information up to date during the term of the agreement by adjusting it or notifying XPipe. - -**5.3** Only one registration may be maintained per person at any one time. - -**5.4** The User is obliged to keep his access data secret and not to pass it on to third parties. The transfer of a paid subscription to third parties is prohibited. - -**5.5** The User is obliged to observe the statutory copyrights and other rights existing for the contents of the paid subscriptions as well as for the other contents in the XPipe offer. The User may not reproduce, distribute or make publicly available such content or remove technical protective measures or copyright or legal notices unless this is expressly permitted. - -**5.6** The User shall be obliged to provide, at his own expense, hardware and software as well as an Internet connection for retrieving the agreed content and/or services from the XPipe offer. - -## 6. Terms of payment, payment service providers, set-off and right of retention - -**6.1** For secure payment processing, the check-out process on our website is facilitated by Lemonsqueezy, a global payment processor and merchant of record. Lemonsqueezy is a secure and reputable platform that provides payment services to online businesses. By purchasing our software, you agree to Lemonsqueezy’s terms and conditions, https://www.lemonsqueezy.com/buyer-terms. We do not assume any liability or responsibility for Lemonsqueezy’s services or actions. Read more at https://www.lemonsqueezy.com. - -**6.2** The User agrees to pay within the set time for the chosen payment method, unless otherwise agreed. Fees of a subscription plan must be paid at the beginning of the period, unless otherwise agreed. - -**6.3** We may occasionally offer gift cards and vouchers that can be used as a payment method. - -**6.4** The User shall only have a right of set-off if his claim against XPipe has been legally established, is undisputed or has been acknowledged. The User shall only have a right of retention if its counterclaim is based on the same contractual relationship. - -**6.5** If the User unjustifiably fails to meet his or her due payment obligations to XPipe, XPipe may, after prior warning and taking into account other legal and contractual rights, temporarily block the User's access until the payment owed has been received. The temporary blocking shall not affect the term of the contract. User may incur late payment charges and interest. - -**6.6** The User shall, in accordance with law, reimburse XPipe for any damages and necessary expenses incurred as a result of non-payment or late payment by the User or other disruption of payment by the User, unless the User is not responsible therefor. - -## 7. Contract duration, automatic renewal, pause, termination - -**7.1** The paid subscription contract is valid for a certain minimum term. For example, it can be one (1) month. At the end of each subscription period, the subscription will be automatically renewed depending on the term of the subscription period unless terminated by User before the last day of the current subscription period. - -**7.2** The User or XPipe may terminate the subscription contract at any time, with one day's notice before the end of the minimum term. The User may continue to use the XPipe service until the end of the minimum term. If the contract is not properly terminated by the end of the minimum term, it will be automatically renewed and a paid subscription will be activated. - -**7.3** For the effective termination, the user may give notice of termination online via the function provided on the billing page at https://buy.xpipe.io/billing. Users can always contact us at hello@xpipe.io for help with ending their subscription. - -**7.4** The right of both contracting parties to terminate for cause in accordance with the law shall remain unaffected. XPipe shall have an extraordinary reason for termination if the User provides misleading information during registration or ordering or has repeatedly violated the Terms of Service. The prerequisite for this is that XPipe has previously warned the User unsuccessfully in order to demand compliance with the contractual obligations. - -**7.5** If XPipe offers a free trial period for a paid subscription and this is agreed with the User, the agreed contract term of the paid subscription shall be extended accordingly. In this case, the extended period shall apply first (with an ordinary special termination right of the User, if applicable, if agreed) and thereafter the regular term of the paid subscription. - -**7.6** Within a free trial period, User and XPipe are allowed to terminate the contract at any time with immediate effect. - -**7.7** In the event of an act with fraudulent intent, a severe, persisting, imminent or repeated material breach of these Terms of Service, XPipe is entitled to suspend the User's access to the Software immediately and indefinitely. User is informed in writing (email is sufficient). The suspicion of fraudulent intent is sufficient. - -## 8. Liability - -**8.1** XPipe shall in principle only be liable for damages to the User if (1) XPipe, its legal representatives or vicarious agents have caused such damages intentionally or through gross negligence or (2) this is based on a breach of duty by XPipe or one of its legal representatives or vicarious agents that results in injury to the life, body or health of the User. In cases of liability under the German Product Liability Act (Produkthaftungsgesetz, ProdHaftG), the assumption of a guarantee or due to fraudulent misrepresentation, as well as the breach of an obligation the fulfillment of which makes the proper execution of the contract possible in the first place and on the fulfillment of which the User may regularly rely on (so-called cardinal obligation), XPipe shall be liable without limitation in cases (1) and (2) of the preceding sentence. Otherwise, liability shall be limited to the foreseeable damage typical for the contract. - -**8.2** In all other cases not mentioned in (1) and (2) above and except as provided in the following paragraph, XPipe's liability shall be excluded regardless of the legal ground. - -**8.3** The above limitations of liability apply accordingly to all employees and vicarious agents of XPipe and do not affect the statutory burden of proof. Please note that the statutory provisions shall remain valid. - -## 9. Right of revocation - -**9.1** If the customer is a consumer within the meaning of § 13 German Civil Code (Bürgerliches Gesetzbuch, BGB), the following right of revocation shall apply to services subject to a charge: - -**Right of revocation** You have the right to revoke this contract within fourteen days without giving any reason. The revocation period is fourteen days from the day of the conclusion of the contract. To exercise your right of revocation, you must inform us (XPipe UG (haftungsbeschränkt), Reichertshalde 81, 71642 Ludwigsburg, Germany, hello@xpipe.io) of your decision to revoke this contract by means of a clear declaration (e.g. a letter sent by post or an email). For this purpose, you may use the enclosed sample revocation form, which, however, is not mandatory. To comply with the revocation period, it is sufficient that you send the notification of the exercise of the right of revocation before the expiry of the revocation period. - -**Consequences of revocation** If you revoke this contract, we shall reimburse you all payments we have received from you, including delivery costs without undue delay and no later than within fourteen days from the day on which we received the notification of your revocation of this contract. For this repayment, we will use the same means of payment that you used for the original transaction, unless expressly agreed otherwise with you; in no case will you be charged any fees because of this repayment. If you have requested that the services begin during the revocation period, you shall pay us a reasonable amount corresponding to the proportion of the services already provided up to the time you notify us of the exercise of the right of revocation with respect to this contract compared to the total scope of the services provided for in the contract. - -Sample cancellation form -To XPipe UG (haftungsbeschränkt), Reichertshalde 81, 71642 Ludwigsburg, Germany, hello@xpipe.io: - - I/we (*) hereby revoke the contract concluded by me/us (*) for the purchase of the following goods (*)/provision of the following service (*), - Ordered on (*)/received on (*), - Name of the consumer(s), - Address of the consumer(s), - Signature of consumer(s) (only in case of paper communication), - Date. - -(*) Please delete where inapplicable - -**9.2** If the customer is a consumer within the scope of § 13 German Civil Code (Bürgerliches Gesetzbuch, BGB), the customer shall be entitled to the statutory warranty rights. - -**9.3** If the customer is an entrepreneur within the meaning of § 14 of the German Civil Code (BGB), XPipe shall assume warranty for the products in the case of paid subscriptions only to the extent set forth in the following provisions. - -**9.4** If the products XPipe provides are defective, XPipe will provide an improved or new product within a reasonable time after receiving a written complaint from the customer. If the Software is used by a third party licensed by XPipe, publicly available upgrades, updates or patches shall be deemed sufficient. - -**9.5** The customer may reduce the agreed remuneration by a reasonable amount if proper performance of the services owed is not guaranteed within a reasonable period set by the customer for reasons for which XPipe is responsible. The right of reduction shall be limited to that part of the services that is defective in relation to the monthly remuneration. - -**9.6** If the reduction pursuant to Section **9.5** continues for two (2) consecutive months or for two (2) months of a quarter, the customer may terminate the Agreement without notice. - -**9.7** The customer shall inform XPipe immediately in text form (e.g. to hello@xpipe.io) of any defects that occur. - -**9.8** The customer is obligated to support XPipe free of charge in the elimination of defects, in particular by providing all necessary documents, data and other information required to analyze and eliminate the defects. - -**9.9** In the event of the provision of additional services free of charge, XPipe shall only be liable for defects if XPipe has fraudulently concealed the defect. - -## 10. Final provisions - -**10.1** There are no oral or written collateral agreements. - -**10.2** Should individual provisions of these Terms of Service or the concluded contract be or become invalid in whole or in part, the remainder of the contract shall remain valid. The invalid provision shall be replaced by the statutory provision. - -**10.3** German law shall apply to the exclusion of the UN Convention on Contracts for the International Sale of Goods. - -**10.4** The agreed place of jurisdiction for all disputes arising from the contractual relationship between the User and XPipe shall be XPipe's registered office, provided the User is a merchant, a legal entity under public law or a special fund under public law. Notwithstanding the foregoing, XPipe shall also be entitled to sue the User at the user's statutory place of jurisdiction. - -**10.5** In the event of complaints about XPipe, the User may at any time contact the European Platform for Online Dispute Resolution in Consumer Matters: https://ec.europa.eu/consumers/odr. - -**10.6** XPipe is not obligated or willing to participate in dispute resolution proceedings before a consumer arbitration board. - -**10.7** If any provision of this Terms of Service is invalid, void or unenforceable under any present or future law, the remainder of this Terms of Service shall continue in full force and effect. To the extent that the invalid, void or unenforceable provision is a material term of the agreement, the parties agree to jointly negotiate a valid alternative provision. - -As of: 20th September 2023 diff --git a/app/src/main/resources/io/xpipe/app/resources/style/browser.css b/app/src/main/resources/io/xpipe/app/resources/style/browser.css index fabbbd36..a2c50e43 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/browser.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/browser.css @@ -1,7 +1,21 @@ .download-background { + -fx-border-color: -color-border-default; + -fx-border-width: 1px 0 0 0; + -fx-padding: 1em; +} + +.transfer .button { -fx-border-color: -color-border-default; --fx-border-width: 1px 0 0 0; --fx-padding: 1em; +-fx-border-width: 1px; + -fx-background-color: -color-bg-default; + -fx-background-radius: 4; + -fx-border-radius: 4; + -fx-padding: 0.1em 0.2em; +} + +.transfer .button:hover { + -fx-background-color: -color-bg-subtle; + -fx-opacity: 1.0; } .browser .welcome .button { diff --git a/app/src/main/resources/io/xpipe/app/resources/style/category.css b/app/src/main/resources/io/xpipe/app/resources/style/category.css index 760de826..6963da1f 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/category.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/category.css @@ -1,13 +1,17 @@ .category-button { -fx-opacity: 0.8; + -fx-border-width: 0; + -fx-background-color: transparent; + -fx-padding: 0 0 0 2; + -fx-background-insets: 0; } .category-button .settings { -fx-opacity: 1.0; } - .category-button:hover .name * { - -fx-underline: true ; + .category-button:hover, .category-button:focused { + -fx-background-color: -color-bg-default; } .category:selected .category-button { @@ -20,11 +24,13 @@ } .category .separator{ --fx-padding: 0; + -fx-padding: 0 5 0 5; } .category .separator .line { -fx-pref-height: 1; + -fx-background-color: -color-fg-default; + -fx-opacity: 0.5; } diff --git a/app/src/main/resources/io/xpipe/app/resources/style/color-box.css b/app/src/main/resources/io/xpipe/app/resources/style/color-box.css index 3b22b945..2002f803 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/color-box.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/color-box.css @@ -8,6 +8,16 @@ -fx-border-color: derive(-color-border-default, -10%); } +.root:dark .color-box.gray { + -fx-background-color: linear-gradient(from 100% 0% to 0% 100%, derive(-color-bg-default, 13%) 40%, derive(-color-bg-default, 11%) 50%, derive(-color-bg-default, 14%) 100%); + -fx-border-color: -color-border-default; +} + +.root:light .color-box.gray { + -fx-background-color: linear-gradient(from 100% 0% to 0% 100%, derive(-color-bg-default, -5%) 40%, derive(-color-bg-default, -3%) 50%, derive(-color-bg-default, -5%) 100%); + -fx-border-color: derive(-color-border-default, -10%); +} + .color-box > .separator .line { -fx-border-color: -color-border-default; } diff --git a/app/src/main/resources/io/xpipe/app/resources/style/header-bars.css b/app/src/main/resources/io/xpipe/app/resources/style/header-bars.css index 0f8743d0..8309616c 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/header-bars.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/header-bars.css @@ -29,15 +29,19 @@ } .store-header-bar .menu-button { --fx-background-radius: 4px; - -fx-border-radius: 4px; +-fx-background-radius: 3px; + -fx-border-radius: 3px; -fx-border-width: 1px; --fx-padding: 0; --fx-background-color: -color-fg-default; + -fx-padding: -3 0 -3 0; + -fx-background-color: linear-gradient(from 100% 0% to 0% 100% , rgb(208, 220, 252) 40%, rgba(219, 219, 255, 1) 50%, rgb(250, 242, 242) 100%); -fx-border-color: transparent; } -.store-header-bar .menu-button:hover { +.root:light .store-header-bar .menu-button { + -fx-background-color: linear-gradient(from 100% 0% to 0% 100% , rgb(12, 11, 11) 40%, rgb(32, 32, 40) 50%, rgb(35, 29, 29) 100%); +} + +.root:light .store-header-bar .menu-button:hover, .root:dark .store-header-bar .menu-button:hover { -fx-background-color: -color-bg-default; -fx-border-color: -color-fg-default; } @@ -147,24 +151,27 @@ } .bar .name { + -fx-font-weight: BOLD; -fx-text-fill: -color-fg-default; } .bar .count-comp { + -fx-font-weight: BOLD; -fx-padding: 0.0em 0em 0.0em 0.4em; + -fx-text-fill: -color-fg-muted; } .bar .filter-bar .text-field { --fx-padding: 0.35em; -fx-text-fill: -color-fg-default; } .bar .filter-bar { --fx-background-radius: 4px; --fx-background-color: -color-bg-default; + -fx-padding: -3 0 -3 0; +-fx-background-radius: 3px; + -fx-background-color: -color-bg-default; + -fx-border-color: -color-fg-default; -fx-border-width: 0.05em; --fx-border-radius: 4px; --fx-border-color: -color-border-default; +-fx-border-radius: 3px; } diff --git a/app/src/main/resources/io/xpipe/app/resources/style/side-split-pane-comp.css b/app/src/main/resources/io/xpipe/app/resources/style/side-split-pane-comp.css new file mode 100644 index 00000000..6d39fc25 --- /dev/null +++ b/app/src/main/resources/io/xpipe/app/resources/style/side-split-pane-comp.css @@ -0,0 +1,10 @@ +.side-split-pane-comp.split-pane-divider { + -fx-padding: 1; +} + +.side-split-pane-comp .split-pane-divider .horizontal-grabber { + -fx-padding: 0; + -fx-background-color: transparent; + -fx-background-insets: 0; + -fx-shape: " "; +} \ No newline at end of file diff --git a/app/src/main/resources/io/xpipe/app/resources/style/sidebar-comp.css b/app/src/main/resources/io/xpipe/app/resources/style/sidebar-comp.css index 24ad8f46..1502ae6c 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/sidebar-comp.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/sidebar-comp.css @@ -20,7 +20,7 @@ -fx-opacity: 1.0; } -.sidebar-comp .icon-button-comp:hover { +.sidebar-comp .icon-button-comp:hover, .sidebar-comp .icon-button-comp:focused { -fx-border-color: -color-accent-muted; -fx-background-color: -color-neutral-muted; } diff --git a/app/src/main/resources/io/xpipe/app/resources/style/storage-entry-comp.css b/app/src/main/resources/io/xpipe/app/resources/style/storage-entry-comp.css deleted file mode 100644 index 7d4749b8..00000000 --- a/app/src/main/resources/io/xpipe/app/resources/style/storage-entry-comp.css +++ /dev/null @@ -1,66 +0,0 @@ -.storage-entry-comp .jfx-text-field { --fx-padding: 0; -} - -.storage-entry-comp .content { --fx-padding: 0.65em 0 0.65em 0; --fx-background-color: DDD; --fx-background-radius: 2px 0 0 2px; - -fx-border-width: 1px; --fx-border-color: -xp-border-accent; --fx-border-radius: 2px 0 0 2px; -} - -.storage-entry-comp .update { - -fx-border-width: 1px 1px 1px 0; --fx-border-color: -xp-border-accent; --fx-background-color: -xp-base-accent; --fx-background-radius: 0; --fx-border-radius: 0; --fx-text-fill: -xp-text-accent-base; --fx-font-size: 1.15em; -} - -.storage-entry-comp .retrieve { - -fx-border-width: 1px 1px 1px 0; --fx-border-color: -xp-border-accent; --fx-background-color: -xp-base-accent; --fx-background-radius: 0; --fx-border-radius: 0; --fx-text-fill: -xp-text-accent-base; --fx-font-size: 1.15em; -} - -.storage-entry-comp .settings { - -fx-border-width: 1px 1px 1px 0; --fx-border-color: -xp-border-accent; --fx-text-fill: -xp-text-base; --fx-font-size: 1.15em; --fx-background-color: DDD; --fx-background-radius: 0 2px 2px 0; --fx-border-radius: 0 2px 2px 0; -} - -.storage-entry-comp .text-field { --fx-padding: 0; -} - -.storage-entry-comp .input-line { --fx-opacity: 0.2; -} - -.storage-entry-comp .data-store-type-comp .ikonli-font-icon { --fx-icon-color: #222; -} - -.storage-entry-comp .readable-instant-comp, .storage-entry-comp .size { --fx-text-fill: -xp-text-light; -} - -.storage-entry-comp .information, .storage-entry-comp .summary, .storage-entry-comp .date { --fx-text-fill: -xp-text-light; -} - -.storage-entry-comp .description, .storage-entry-comp .readable-instant-comp { --fx-padding: 0 0 0 0.1em; -} \ No newline at end of file diff --git a/app/src/main/resources/io/xpipe/app/resources/style/storage-entry-list-comp.css b/app/src/main/resources/io/xpipe/app/resources/style/storage-entry-list-comp.css deleted file mode 100644 index 04b5ae5d..00000000 --- a/app/src/main/resources/io/xpipe/app/resources/style/storage-entry-list-comp.css +++ /dev/null @@ -1,18 +0,0 @@ -.storage-entry-list-comp .content { -} - -.list-mode.columns .column-name { --fx-text-fill: grey; -} - -.list-mode.columns { --fx-padding: 0 0.2em 0.0em 0; -} - -.storage-entry-list-comp .content-pane { - -fx-padding: 0.0em 0.1em 0.2em 0.2em; -} - -.storage-entry-list-comp { - -fx-padding: 0 0.2em 0 0.2em; -} \ No newline at end of file diff --git a/app/src/main/resources/io/xpipe/app/resources/style/storage-group-list-comp.css b/app/src/main/resources/io/xpipe/app/resources/style/storage-group-list-comp.css deleted file mode 100644 index a3eb1123..00000000 --- a/app/src/main/resources/io/xpipe/app/resources/style/storage-group-list-comp.css +++ /dev/null @@ -1,68 +0,0 @@ - -.bar.storage-group-list-comp { --fx-pref-width: 17em; --fx-background-radius: 0 3px 3px 0; - -fx-border-width: 2px 2px 2px 0; --fx-border-color: -xp-border-accent; --fx-border-radius: 0 3px 3px 0; --fx-padding: 0; -} - -.storage-group-list-comp .text-field { --fx-padding: 0.05em 0 0.1em 0; --fx-text-fill: -xp-text-accent-base; -} - -.storage-group-list-comp .icon-button-comp { --fx-text-fill: -xp-text-accent-base; -} - -/* Temp collection */ -.storage-group-list-comp .temp.label { --fx-padding: 0.05em 0 0.1em 0; --fx-text-fill: -xp-text-accent-base; -} -.storage-group-list-comp .temp .ikonli-font-icon { --fx-icon-color: -xp-text-accent-base; -} - -.storage-group-list-comp .date { --fx-text-fill: -xp-text-accent-light; -} - -.storage-group-list-comp .count-comp { --fx-text-fill: -xp-text-accent-light; -} - -.storage-group-entry { --fx-padding: 0.1em 0 0.1em 0; -} - -.storage-group-entry .icon { --fx-padding: 0.25em 0.4em 0.25em 0.25em; -} - -.storage-group-list-comp .list-cell:filled { --fx-background-radius: 0 3px 3px 0; - -fx-border-width: 0 0 1px 0; --fx-border-color: #FFF5; --fx-border-insets: 8 18 5 15; --fx-border-radius: 10; -} - -.storage-group-list-comp .list-cell:filled:selected { --fx-background-color: #59c8ec77; -} - -.list-cell:empty { --fx-opacity: 0; -} - -.storage-group-list-comp .list-cell { --fx-padding: 0; --fx-focus-color: transparent; -} - -.store-list-comp .list-cell { --fx-padding: 0; -} diff --git a/app/src/main/resources/io/xpipe/app/resources/style/store-entry-comp.css b/app/src/main/resources/io/xpipe/app/resources/style/store-entry-comp.css index 33462004..5ae43f28 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/store-entry-comp.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/store-entry-comp.css @@ -70,7 +70,7 @@ -fx-background-color: derive(-color-neutral-muted, 25%); } -.store-entry-comp:hover { +.store-entry-comp:hover, .store-entry-comp:focused { -fx-background-color: -color-neutral-muted; } @@ -82,7 +82,7 @@ -fx-opacity: 1.0; } -.expand-button:hover { +.expand-button:hover,.expand-button:focused { -fx-background-color: -color-neutral-muted; } @@ -101,7 +101,7 @@ /* Section */ .store-entry-section-comp .separator { --fx-padding: 0 0.75em 0 0.75em; +-fx-padding: 0 12px 0 35px; -fx-border-insets: 0px; } diff --git a/app/src/main/resources/io/xpipe/app/resources/style/store-mini-section.css b/app/src/main/resources/io/xpipe/app/resources/style/store-mini-section.css index af4a54f2..b643fc05 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/store-mini-section.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/store-mini-section.css @@ -22,7 +22,7 @@ -fx-background-color: transparent; } -.store-section-mini-comp .item:hover { +.store-section-mini-comp .item:hover, .store-section-mini-comp .item:focused { -fx-background-color: -color-accent-subtle; } @@ -36,7 +36,7 @@ -fx-border-color: -color-border-subtle; } -.store-section-mini-comp .expand-button:hover { +.store-section-mini-comp .expand-button:hover, .store-section-mini-comp .expand-button:focused { -fx-background-color: -color-neutral-muted; } diff --git a/app/src/main/resources/io/xpipe/app/resources/style/style.css b/app/src/main/resources/io/xpipe/app/resources/style/style.css index 4ed1be1c..8e39cded 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/style.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/style.css @@ -13,8 +13,8 @@ -fx-padding: 1.2em; } -.layout { - +.store-layout .split-pane-divider { + -fx-background-color: transparent; } .root:dark.background { @@ -34,7 +34,7 @@ -fx-border-color: -color-neutral-emphasis; } -.edit-button.icon-button-comp:hover { +.edit-button.icon-button-comp:hover, .edit-button.icon-button-comp:focused { -fx-background-color: -color-accent-muted; } @@ -68,3 +68,11 @@ -fx-padding: 0; } +.root:light .loading-comp { + -fx-background-color: rgba(100,100,100,0.5); +} + +.root:dark .loading-comp { + -fx-background-color: rgba(0,0,0,0.5); +} + diff --git a/core/src/main/java/io/xpipe/core/charsetter/Charsetter.java b/core/src/main/java/io/xpipe/core/charsetter/Charsetter.java index 76c91da4..0dbf9b47 100644 --- a/core/src/main/java/io/xpipe/core/charsetter/Charsetter.java +++ b/core/src/main/java/io/xpipe/core/charsetter/Charsetter.java @@ -1,8 +1,8 @@ package io.xpipe.core.charsetter; -import io.xpipe.core.store.FileStore; -import io.xpipe.core.store.ShellStore; import io.xpipe.core.store.StreamDataStore; +import io.xpipe.core.util.FailableConsumer; +import io.xpipe.core.util.FailableSupplier; import lombok.Value; import java.io.BufferedReader; @@ -76,7 +76,7 @@ public abstract class Charsetter { } public abstract Result read( - FailableSupplier in, FailableConsumer con) + FailableSupplier in, FailableConsumer con) throws Exception; public Result detect(StreamDataStore store) throws Exception { @@ -107,13 +107,13 @@ public abstract class Charsetter { } } - if (store instanceof FileStore fileStore && fileStore.getFileSystem() instanceof ShellStore m) { - if (result.getNewLine() == null) { - result = new Result( - result.getCharset(), - m.getShellType() != null ? m.getShellType().getNewLine() : null); - } - } +// if (store instanceof FileStore fileStore && fileStore.getFileSystem() instanceof ShellStore m) { +// if (result.getNewLine() == null) { +// result = new Result( +// result.getCharset(), +// m.getShellType() != null ? m.getShellType().getNewLine() : null); +// } +// } if (result.getCharset() == null) { result = new Result(StreamCharset.UTF8, result.getNewLine()); @@ -167,17 +167,6 @@ public abstract class Charsetter { return StandardCharsets.UTF_8; } - @FunctionalInterface - public interface FailableSupplier { - R get() throws E; - } - - @FunctionalInterface - public interface FailableConsumer { - - void accept(T var1) throws E; - } - @Value public static class Result { StreamCharset charset; diff --git a/core/src/main/java/io/xpipe/core/dialog/Dialog.java b/core/src/main/java/io/xpipe/core/dialog/Dialog.java index b84df98b..5299dce7 100644 --- a/core/src/main/java/io/xpipe/core/dialog/Dialog.java +++ b/core/src/main/java/io/xpipe/core/dialog/Dialog.java @@ -1,6 +1,7 @@ package io.xpipe.core.dialog; import io.xpipe.core.charsetter.Charsetter; +import io.xpipe.core.util.FailableConsumer; import io.xpipe.core.util.FailableSupplier; import io.xpipe.core.util.SecretValue; @@ -27,7 +28,7 @@ import java.util.function.Supplier; */ public abstract class Dialog { - private final List> completion = new ArrayList<>(); + private final List> completion = new ArrayList<>(); protected Object eval; private Supplier evaluation; @@ -416,7 +417,7 @@ public abstract class Dialog { return this; } - public Dialog onCompletion(Charsetter.FailableConsumer s) { + public Dialog onCompletion(FailableConsumer s) { completion.add(s); return this; } @@ -426,7 +427,7 @@ public abstract class Dialog { return this; } - public Dialog onCompletion(List> s) { + public Dialog onCompletion(List> s) { completion.addAll(s); return this; } @@ -440,8 +441,8 @@ public abstract class Dialog { public void complete() throws Exception { if (evaluation != null) { eval = evaluation.get(); - for (Charsetter.FailableConsumer c : completion) { - Charsetter.FailableConsumer ct = (Charsetter.FailableConsumer) c; + for (FailableConsumer c : completion) { + FailableConsumer ct = (FailableConsumer) c; ct.accept((T) eval); } } diff --git a/core/src/main/java/io/xpipe/core/process/CommandControl.java b/core/src/main/java/io/xpipe/core/process/CommandControl.java index e393553b..ed4d70fd 100644 --- a/core/src/main/java/io/xpipe/core/process/CommandControl.java +++ b/core/src/main/java/io/xpipe/core/process/CommandControl.java @@ -1,6 +1,6 @@ package io.xpipe.core.process; -import io.xpipe.core.charsetter.Charsetter; +import io.xpipe.core.util.FailableConsumer; import io.xpipe.core.util.FailableFunction; import java.io.InputStream; @@ -12,10 +12,11 @@ import java.util.function.Function; public interface CommandControl extends ProcessControl { - int UNASSIGNED_EXIT_CODE = -1; - int EXIT_TIMEOUT_EXIT_CODE = -2; - int START_FAILED_EXIT_CODE = -3; - int INTERNAL_ERROR_EXIT_CODE = -4; + // Keep these out of a normal exit code range + int UNASSIGNED_EXIT_CODE = -80001; + int EXIT_TIMEOUT_EXIT_CODE = -80002; + int START_FAILED_EXIT_CODE = -80003; + int INTERNAL_ERROR_EXIT_CODE = -80004; enum TerminalExitMode { KEEP_OPEN, @@ -71,7 +72,7 @@ public interface CommandControl extends ProcessControl { CommandControl exitTimeout(Integer timeout); - void withStdoutOrThrow(Charsetter.FailableConsumer c); + void withStdoutOrThrow(FailableConsumer c); String readStdoutDiscardErr() throws Exception; @@ -85,6 +86,8 @@ public interface CommandControl extends ProcessControl { String readStdoutOrThrow() throws Exception; + String readStdoutAndWait() throws Exception; + default boolean discardAndCheckExit() throws ProcessOutputException { try { discardOrThrow(); diff --git a/core/src/main/java/io/xpipe/core/process/OsNameState.java b/core/src/main/java/io/xpipe/core/process/OsNameState.java new file mode 100644 index 00000000..8180da8d --- /dev/null +++ b/core/src/main/java/io/xpipe/core/process/OsNameState.java @@ -0,0 +1,6 @@ +package io.xpipe.core.process; + +public interface OsNameState { + + String getOsName(); +} diff --git a/core/src/main/java/io/xpipe/core/process/PropertiesFormatsParser.java b/core/src/main/java/io/xpipe/core/process/PropertiesFormatsParser.java index 5b83f897..6203514b 100644 --- a/core/src/main/java/io/xpipe/core/process/PropertiesFormatsParser.java +++ b/core/src/main/java/io/xpipe/core/process/PropertiesFormatsParser.java @@ -6,9 +6,21 @@ import java.io.BufferedReader; import java.io.StringReader; import java.util.LinkedHashMap; import java.util.Map; +import java.util.regex.Pattern; public class PropertiesFormatsParser { + @SneakyThrows + public static Map parseLine(String line, String split, String quotes) { + var map = new LinkedHashMap(); + var pattern = Pattern.compile("(\\w+?)\\s*" + split + "\\s*" + quotes + "(.+?)" + quotes); + var matcher = pattern.matcher(line); + while (matcher.find()) { + map.put(matcher.group(1), matcher.group(2)); + } + return map; + } + @SneakyThrows public static Map parse(String text, String split) { var map = new LinkedHashMap(); diff --git a/core/src/main/java/io/xpipe/core/process/ShellStoreState.java b/core/src/main/java/io/xpipe/core/process/ShellStoreState.java index 92b55441..ab512f02 100644 --- a/core/src/main/java/io/xpipe/core/process/ShellStoreState.java +++ b/core/src/main/java/io/xpipe/core/process/ShellStoreState.java @@ -13,7 +13,7 @@ import lombok.extern.jackson.Jacksonized; @Getter @Jacksonized @SuperBuilder -public class ShellStoreState extends DataStoreState { +public class ShellStoreState extends DataStoreState implements OsNameState { OsType osType; String osName; diff --git a/core/src/main/java/io/xpipe/core/store/FileSystem.java b/core/src/main/java/io/xpipe/core/store/FileSystem.java index 31db4d3e..79f21826 100644 --- a/core/src/main/java/io/xpipe/core/store/FileSystem.java +++ b/core/src/main/java/io/xpipe/core/store/FileSystem.java @@ -21,7 +21,6 @@ public interface FileSystem extends Closeable, AutoCloseable { @Value @NonFinal class FileEntry { - @NonNull FileSystem fileSystem; @NonNull @@ -39,7 +38,7 @@ public interface FileSystem extends Closeable, AutoCloseable { FileKind kind; public FileEntry( - @NonNull FileSystem fileSystem, + FileSystem fileSystem, @NonNull String path, Instant date, boolean hidden, diff --git a/core/src/main/java/io/xpipe/core/store/ShellStore.java b/core/src/main/java/io/xpipe/core/store/ShellStore.java index 3be00520..97a25e4b 100644 --- a/core/src/main/java/io/xpipe/core/store/ShellStore.java +++ b/core/src/main/java/io/xpipe/core/store/ShellStore.java @@ -1,13 +1,9 @@ package io.xpipe.core.store; -import io.xpipe.core.process.OsType; import io.xpipe.core.process.ProcessControl; import io.xpipe.core.process.ShellControl; -import io.xpipe.core.process.ShellDialect; -import java.nio.charset.Charset; - -public interface ShellStore extends DataStore, InternalCacheDataStore, LaunchableStore, FileSystemStore, ValidatableStore { +public interface ShellStore extends DataStore, LaunchableStore, FileSystemStore, ValidatableStore { static boolean isLocal(ShellStore s) { return s instanceof LocalStore; @@ -23,32 +19,8 @@ public interface ShellStore extends DataStore, InternalCacheDataStore, Launchabl return control(); } - default ShellDialect getShellType() { - return getCache("type", ShellDialect.class, null); - } - - default OsType getOsType() { - return getOrCompute("os", OsType.class, () -> { - try (var sc = control().start()) { - return sc.getOsType(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - }); - } - - default Charset getCharset() { - return getCache("charset", Charset.class, null); - } - ShellControl control(); - default ShellDialect determineType() throws Exception { - try (var pc = control().start()) { - return pc.getShellDialect(); - } - } - @Override default void validate() throws Exception { var c = control(); @@ -58,11 +30,4 @@ public interface ShellStore extends DataStore, InternalCacheDataStore, Launchabl try (ShellControl pc = c.start()) {} } - - default String queryMachineName() throws Exception { - try (var pc = control().start()) { - var operatingSystem = pc.getOsType(); - return operatingSystem.determineOperatingSystemName(pc); - } - } } diff --git a/dist/changelogs/1.7.4.md b/dist/changelogs/1.7.4.md new file mode 100644 index 00000000..d1272e11 --- /dev/null +++ b/dist/changelogs/1.7.4.md @@ -0,0 +1,43 @@ +## Changes in 1.7.4 + +### VMware support for desktop hypervisors + +This update introduces an experimental implementation to support VMware virtual machines in VMware Player, Workstation, and Fusion installations. +The support includes actions like listing, starting, stopping, and pausing VMs plus opening a shell session or file browser session via SSH. + +Note that the initial connection to a VM, which runs some setup, can take a long time. +It seems like the VMware CLI it is very slow in that regard, maybe I can find some improvements. + +If everything works out well with this first attempt at VM support, it can be expanded to other hypervisors. + +### Git storage for everyone + +Up until now, the git storage functionality has only been available with a professional license. +However, due to the complex nature of git repositories, this feature had some inevitable rough edges +and did not live up to the robustness of a professional product. + +As a result, I am moving this feature into the community edition. + +### UI rework + +Some parts of the UI have been reworked to achieve a more consistent appearance. +Furthermore, it has also been improved in regard to accessibility and its interaction with screen readers. + +### Other changes + +- The left sidebars in the connection overview and browser can now be persistently resized +- Implement various performance improvements +- When dragging files straight out of the browser, they now can also resolve to text output. + You can therefore now drag files into a terminal to quickly paste their file names for example. +- Rework connection creation to automatically preselect most commonly used type +- Fix browser exit race conditions +- Fix application not starting up when settings file was corrupted +- Fix connection getting stuck when shell did not support stderr. It will now just stop after a few seconds +- Fix application not starting up on Windows systems older than Windows 10 +- Fix negative process exit codes being interpreted as internal errors and not shown + +## Previous changes in 1.7 + +- [1.7.3](https://github.com/xpipe-io/xpipe/releases/tag/1.7.3) +- [1.7.2](https://github.com/xpipe-io/xpipe/releases/tag/1.7.2) +- [1.7.1](https://github.com/xpipe-io/xpipe/releases/tag/1.7.1) diff --git a/dist/licenses/commons-codec.license b/dist/licenses/commons-codec.license deleted file mode 100644 index f433b1a5..00000000 --- a/dist/licenses/commons-codec.license +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/dist/licenses/commons-codec.properties b/dist/licenses/commons-codec.properties deleted file mode 100644 index 6c2d4551..00000000 --- a/dist/licenses/commons-codec.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=Commons Codec -version=1.15 -license=Apache License 2.0 -link=https://commons.apache.org/proper/commons-code/ \ No newline at end of file diff --git a/dist/licenses/commons-collections.license b/dist/licenses/commons-collections.license deleted file mode 100644 index f433b1a5..00000000 --- a/dist/licenses/commons-collections.license +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/dist/licenses/commons-collections.properties b/dist/licenses/commons-collections.properties deleted file mode 100644 index cb6f6017..00000000 --- a/dist/licenses/commons-collections.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=Commons Collections -version=4.4 -license=Apache License 2.0 -link=https://commons.apache.org/proper/commons-collections/ \ No newline at end of file diff --git a/dist/licenses/commons-exec.license b/dist/licenses/commons-exec.license deleted file mode 100644 index f433b1a5..00000000 --- a/dist/licenses/commons-exec.license +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/dist/licenses/commons-exec.properties b/dist/licenses/commons-exec.properties deleted file mode 100644 index 76fe22b4..00000000 --- a/dist/licenses/commons-exec.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=Commons Exec -version=1.3 -license=Apache License 2.0 -link=https://commons.apache.org/proper/commons-exec/ \ No newline at end of file diff --git a/dist/licenses/curvesapi.license b/dist/licenses/curvesapi.license deleted file mode 100644 index e30f0152..00000000 --- a/dist/licenses/curvesapi.license +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2005, Graph Builder -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - --Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - --Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - --Neither the name of Graph Builder nor the names of its contributors may be -used to endorse or promote products derived from this software without -specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/licenses/curvesapi.properties b/dist/licenses/curvesapi.properties deleted file mode 100644 index dd3fc802..00000000 --- a/dist/licenses/curvesapi.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=curvesapi -version=1.07 -license=BSD 3-Clause -link=https://github.com/virtuald/curvesapi \ No newline at end of file diff --git a/dist/licenses/flowless.license b/dist/licenses/flowless.license deleted file mode 100644 index 21be4ebc..00000000 --- a/dist/licenses/flowless.license +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2014, TomasMikula -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/licenses/flowless.properties b/dist/licenses/flowless.properties deleted file mode 100644 index 48d79af4..00000000 --- a/dist/licenses/flowless.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=Flowless -version=0.6.6 -license=BSD 2-Clause -link=https://github.com/FXMisc/Flowless \ No newline at end of file diff --git a/dist/licenses/fxtrayicon.license b/dist/licenses/fxtrayicon.license deleted file mode 100644 index 3287acb9..00000000 --- a/dist/licenses/fxtrayicon.license +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Dustin K. Redmond - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/dist/licenses/fxtrayicon.properties b/dist/licenses/fxtrayicon.properties deleted file mode 100644 index 4b060668..00000000 --- a/dist/licenses/fxtrayicon.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=FXTrayIcon -version=3.1.2 -license=MIT License -link=https://github.com/dustinkredmond/FXTrayIcon \ No newline at end of file diff --git a/dist/licenses/gson.license b/dist/licenses/gson.license deleted file mode 100644 index d6456956..00000000 --- a/dist/licenses/gson.license +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/dist/licenses/gson.properties b/dist/licenses/gson.properties deleted file mode 100644 index edd56d56..00000000 --- a/dist/licenses/gson.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=Gson -version=2.8.9 -license=Apache License 2.0 -link=https://github.com/google/gson \ No newline at end of file diff --git a/dist/licenses/jansi.license b/dist/licenses/jansi.license deleted file mode 100644 index d6456956..00000000 --- a/dist/licenses/jansi.license +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/dist/licenses/jansi.properties b/dist/licenses/jansi.properties deleted file mode 100644 index dc8c8eaf..00000000 --- a/dist/licenses/jansi.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=Jansi -version=2.4.0 -license=Apache License 2.0 -link=https://github.com/fusesource/jansi \ No newline at end of file diff --git a/dist/licenses/jarchivelib.license b/dist/licenses/jarchivelib.license deleted file mode 100644 index f433b1a5..00000000 --- a/dist/licenses/jarchivelib.license +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/dist/licenses/jarchivelib.properties b/dist/licenses/jarchivelib.properties deleted file mode 100644 index 1d3bd4dc..00000000 --- a/dist/licenses/jarchivelib.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=jarchivelib -version=1.2.0 -license=Apache License 2.0 -link=https://github.com/thrau/jarchivelib \ No newline at end of file diff --git a/dist/licenses/jline.license b/dist/licenses/jline.license deleted file mode 100644 index 7e11b67f..00000000 --- a/dist/licenses/jline.license +++ /dev/null @@ -1,35 +0,0 @@ -Copyright (c) 2002-2018, the original author or authors. -All rights reserved. - -https://opensource.org/licenses/BSD-3-Clause - -Redistribution and use in source and binary forms, with or -without modification, are permitted provided that the following -conditions are met: - -Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with -the distribution. - -Neither the name of JLine nor the names of its contributors -may be used to endorse or promote products derived from this -software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/dist/licenses/jline.properties b/dist/licenses/jline.properties deleted file mode 100644 index 6ad5e1d1..00000000 --- a/dist/licenses/jline.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=jline -version=3.21.0 -license=BSD 3-Clause -link=https://github.com/jline/jline3 \ No newline at end of file diff --git a/dist/licenses/jsch.license b/dist/licenses/jsch.license deleted file mode 100644 index edd491df..00000000 --- a/dist/licenses/jsch.license +++ /dev/null @@ -1,30 +0,0 @@ -JSch 0.0.* was released under the GNU LGPL license. Later, we have switched -over to a BSD-style license. - ------------------------------------------------------------------------------- -Copyright (c) 2002-2015 Atsuhiko Yamanaka, JCraft,Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/licenses/jsch.properties b/dist/licenses/jsch.properties deleted file mode 100644 index 0e2cac20..00000000 --- a/dist/licenses/jsch.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=jsch -version=0.2.6 -license=BSD 3-Clause -link=https://github.com/mwiede/jsch \ No newline at end of file diff --git a/dist/licenses/log4j.license b/dist/licenses/log4j.license deleted file mode 100644 index f433b1a5..00000000 --- a/dist/licenses/log4j.license +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/dist/licenses/log4j.properties b/dist/licenses/log4j.properties deleted file mode 100644 index 61a80669..00000000 --- a/dist/licenses/log4j.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=Log4J -version=2.18.0 -license=Apache License 2.0 -link=https://logging.apache.org/log4j/2.x/ \ No newline at end of file diff --git a/dist/licenses/mssql.license b/dist/licenses/mssql.license deleted file mode 100644 index 4caf07ad..00000000 --- a/dist/licenses/mssql.license +++ /dev/null @@ -1,11 +0,0 @@ -MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), -to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. diff --git a/dist/licenses/mssql.properties b/dist/licenses/mssql.properties deleted file mode 100644 index ba5d9f25..00000000 --- a/dist/licenses/mssql.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=mssql-jdbc -version=11.2.0 -license=MIT -link=https://github.com/microsoft/mssql-jdbc \ No newline at end of file diff --git a/dist/licenses/opencsv.license b/dist/licenses/opencsv.license deleted file mode 100644 index 8dada3ed..00000000 --- a/dist/licenses/opencsv.license +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/dist/licenses/opencsv.properties b/dist/licenses/opencsv.properties deleted file mode 100644 index 478f76c3..00000000 --- a/dist/licenses/opencsv.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=OpenCSV -version=5.5.2 -license=Apache 2.0 License -link=http://opencsv.sourceforge.net/ \ No newline at end of file diff --git a/dist/licenses/openjdk.properties b/dist/licenses/openjdk.properties index 2e4eae5e..013cbb21 100644 --- a/dist/licenses/openjdk.properties +++ b/dist/licenses/openjdk.properties @@ -1,4 +1,4 @@ name=OpenJDK -version=17.0.1 +version=21.0.1 license=GPL2 with the Classpath Exception -link=https://jdk.java.net/17/ \ No newline at end of file +link=https://jdk.java.net/21/ \ No newline at end of file diff --git a/dist/licenses/openjfx.properties b/dist/licenses/openjfx.properties index 622d391a..e915f84b 100644 --- a/dist/licenses/openjfx.properties +++ b/dist/licenses/openjfx.properties @@ -1,4 +1,4 @@ name=OpenJFX -version=18-ea+4 +version=21.0.1 license=GPL2 with the Classpath Exception link=https://github.com/openjdk/jfx \ No newline at end of file diff --git a/dist/licenses/poi.license b/dist/licenses/poi.license deleted file mode 100644 index f433b1a5..00000000 --- a/dist/licenses/poi.license +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/dist/licenses/poi.properties b/dist/licenses/poi.properties deleted file mode 100644 index 389a6cb2..00000000 --- a/dist/licenses/poi.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=POI -version=5.2.3 -license=Apache License 2.0 -link=https://poi.apache.org/ \ No newline at end of file diff --git a/dist/licenses/postgres.license b/dist/licenses/postgres.license deleted file mode 100644 index 5d3a0018..00000000 --- a/dist/licenses/postgres.license +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 1997, PostgreSQL Global Development Group -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/licenses/postgres.properties b/dist/licenses/postgres.properties deleted file mode 100644 index 441dc24c..00000000 --- a/dist/licenses/postgres.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=pgjdbc -version=42.4.0 -license=BSD 2-Clause -link=https://github.com/pgjdbc/pgjdbc \ No newline at end of file diff --git a/dist/licenses/reactfx.license b/dist/licenses/reactfx.license deleted file mode 100644 index 21be4ebc..00000000 --- a/dist/licenses/reactfx.license +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2014, TomasMikula -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/licenses/reactfx.properties b/dist/licenses/reactfx.properties deleted file mode 100644 index 7d004c0e..00000000 --- a/dist/licenses/reactfx.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=ReactFX -version=2.0-M5 -license=BSD 2-Clause -link=https://github.com/TomasMikula/ReactFX \ No newline at end of file diff --git a/dist/licenses/richtextfx.license b/dist/licenses/richtextfx.license deleted file mode 100644 index 21be4ebc..00000000 --- a/dist/licenses/richtextfx.license +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2014, TomasMikula -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/licenses/richtextfx.properties b/dist/licenses/richtextfx.properties deleted file mode 100644 index 75ebfa56..00000000 --- a/dist/licenses/richtextfx.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=RichTextFX -version=0.10.6 -license=BSD 2-Clause -link=https://github.com/FXMisc/RichTextFX \ No newline at end of file diff --git a/dist/licenses/sparsebitset.license b/dist/licenses/sparsebitset.license deleted file mode 100644 index f433b1a5..00000000 --- a/dist/licenses/sparsebitset.license +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/dist/licenses/sparsebitset.properties b/dist/licenses/sparsebitset.properties deleted file mode 100644 index 92806915..00000000 --- a/dist/licenses/sparsebitset.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=SparseBitSet -version=1.2 -license=Apache License 2.0 -link=https://github.com/brettwooldridge/SparseBitSet \ No newline at end of file diff --git a/dist/licenses/undofx.license b/dist/licenses/undofx.license deleted file mode 100644 index 21be4ebc..00000000 --- a/dist/licenses/undofx.license +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2014, TomasMikula -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/licenses/undofx.properties b/dist/licenses/undofx.properties deleted file mode 100644 index 9a2d1a92..00000000 --- a/dist/licenses/undofx.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=UndoFX -version=2.1.1 -license=BSD 2-Clause -link=https://github.com/FXMisc/UndoFX \ No newline at end of file diff --git a/dist/licenses/wellbehavedfx.license b/dist/licenses/wellbehavedfx.license deleted file mode 100644 index 21be4ebc..00000000 --- a/dist/licenses/wellbehavedfx.license +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2014, TomasMikula -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/licenses/wellbehavedfx.properties b/dist/licenses/wellbehavedfx.properties deleted file mode 100644 index 80bbba02..00000000 --- a/dist/licenses/wellbehavedfx.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=WellBehavedFX -version=0.3.3 -license=BSD 2-Clause -link=https://github.com/FXMisc/UndoFX \ No newline at end of file diff --git a/dist/licenses/xmlbeans.license b/dist/licenses/xmlbeans.license deleted file mode 100644 index f433b1a5..00000000 --- a/dist/licenses/xmlbeans.license +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/dist/licenses/xmlbeans.properties b/dist/licenses/xmlbeans.properties deleted file mode 100644 index c1ad9098..00000000 --- a/dist/licenses/xmlbeans.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=XMLBeans -version=5.1.1 -license=Apache License 2.0 -link=https://xmlbeans.apache.org/ \ No newline at end of file diff --git a/dist/licenses/zshi.license b/dist/licenses/zshi.license deleted file mode 100644 index 84b8367b..00000000 --- a/dist/licenses/zshi.license +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Roman Perepelitsa - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/dist/licenses/zshi.properties b/dist/licenses/zshi.properties deleted file mode 100644 index 8f950cab..00000000 --- a/dist/licenses/zshi.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=zshi -version=1.0 -license=MIT License -link=https://github.com/romkatv/zshi \ No newline at end of file diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/EditStoreAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/EditStoreAction.java index 7046f30f..a758eed4 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/EditStoreAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/EditStoreAction.java @@ -32,9 +32,14 @@ public class EditStoreAction implements ActionProvider { return new DefaultDataStoreCallSite<>() { @Override public boolean isApplicable(DataStoreEntryRef o) { + if (o.get() + .getValidity() == DataStoreEntry.Validity.LOAD_FAILED) { + return false; + } + return o.get() .getValidity() - .equals(DataStoreEntry.Validity.INCOMPLETE); + .equals(DataStoreEntry.Validity.INCOMPLETE) || o.get().getProvider().editByDefault(); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/RefreshStoreAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/RefreshStoreAction.java index 8849aca5..47711ec9 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/RefreshStoreAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/RefreshStoreAction.java @@ -57,11 +57,6 @@ public class RefreshStoreAction implements ActionProvider { return true; } - @Override - public ActiveType activeType() { - return ActiveType.ALWAYS_ENABLE; - } - @Override public ActionProvider.Action createAction(DataStoreEntryRef store) { return new Action(store.get()); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptGroup.java b/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptGroup.java index b69545f5..ca29a718 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptGroup.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptGroup.java @@ -6,17 +6,19 @@ import lombok.Setter; @Getter public enum PredefinedScriptGroup { - CLINK("Clink", null), - STARSHIP("Starship", "Sets up and enables the starship shell prompt"); + CLINK("Clink", null, false), + STARSHIP("Starship", "Sets up and enables the starship shell prompt", true); private final String name; private final String description; + private final boolean expanded; @Setter private DataStoreEntryRef entry; - PredefinedScriptGroup(String name, String description) { + PredefinedScriptGroup(String name, String description, boolean expanded) { this.name = name; this.description = description; + this.expanded = expanded; } } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java index 5891cad0..b8a25766 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java @@ -19,9 +19,7 @@ import lombok.experimental.FieldDefaults; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; +import java.util.*; @SuperBuilder @Getter @@ -132,7 +130,27 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore, var seen = new LinkedHashSet(); scripts.forEach(scriptStoreDataStoreEntryRef -> scriptStoreDataStoreEntryRef.getStore().queryFlattenedScripts(seen)); - return seen.stream().toList(); + + var dependencies = new HashMap>(); + seen.forEach(simpleScriptStore -> { + var f = new HashSet<>(simpleScriptStore.queryFlattenedScripts()); + f.remove(simpleScriptStore); + dependencies.put(simpleScriptStore, f); + }); + + var sorted = new ArrayList<>(seen); + sorted.sort((o1, o2) -> { + if (dependencies.get(o1).contains(o2)) { + return 1; + } + + if (dependencies.get(o2).contains(o1)) { + return -1; + } + + return 0; + }); + return sorted; } protected final DataStoreEntryRef group; @@ -170,6 +188,12 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore, // } } + SequencedCollection queryFlattenedScripts() { + var seen = new LinkedHashSet(); + queryFlattenedScripts(seen); + return seen; + } + protected abstract void queryFlattenedScripts(LinkedHashSet all); public abstract List> getEffectiveScripts(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java index e7e4ea12..490ff497 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java @@ -16,14 +16,16 @@ import io.xpipe.app.fxcomps.impl.DataStoreChoiceComp; import io.xpipe.app.fxcomps.impl.DataStoreListChoiceComp; import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.storage.DataStorage; -import io.xpipe.app.storage.DataStoreCategory; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.OptionsBuilder; import io.xpipe.core.process.ShellDialect; import io.xpipe.core.store.DataStore; import io.xpipe.core.util.Identifiers; import javafx.beans.binding.Bindings; -import javafx.beans.property.*; +import javafx.beans.property.Property; +import javafx.beans.property.SimpleListProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import lombok.SneakyThrows; @@ -198,6 +200,11 @@ public class SimpleScriptStoreProvider implements DataStoreProvider { .buildDialog(); } + @Override + public boolean editByDefault() { + return true; + } + @Override public boolean canMoveCategories() { return false; @@ -219,9 +226,6 @@ public class SimpleScriptStoreProvider implements DataStoreProvider { @Override public void storageInit() throws Exception { - var cat = DataStorage.get() - .addStoreCategoryIfNotPresent(DataStoreCategory.createNew( - DataStorage.ALL_SCRIPTS_CATEGORY_UUID, DataStorage.CUSTOM_SCRIPTS_CATEGORY_UUID, "My scripts")); DataStorage.get() .addStoreEntryIfNotPresent(DataStoreEntry.createNew( UUID.fromString("a9945ad2-db61-4304-97d7-5dc4330691a7"), @@ -240,6 +244,7 @@ public class SimpleScriptStoreProvider implements DataStoreProvider { value.getName(), store)); e.setStoreInternal(store, false); + e.setExpanded(value.isExpanded()); value.setEntry(e.ref()); } diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/clink.bat b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/clink.bat index 41b1f824..33add306 100644 --- a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/clink.bat +++ b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/clink.bat @@ -15,5 +15,5 @@ $defaultCreds = [System.Net.CredentialCache]::DefaultCredentials;^ if ($defaultCreds) {^ $downloader.Credentials = $defaultCreds^ }^ -$downloader.DownloadFile("https://github.com/chrisant996/clink/releases/download/v1.5.7/clink.1.5.7.36d0c6.zip", "$env:TEMP\clink.zip");^ +$downloader.DownloadFile("https://github.com/chrisant996/clink/releases/download/v1.5.13/clink.1.5.13.290610.zip", "$env:TEMP\clink.zip");^ Expand-Archive -Force -LiteralPath "$env:TEMP\clink.zip" -DestinationPath "$env:USERPROFILE\.xpipe\scriptdata\clink"; | powershell -NoLogo >NUL diff --git a/gradle/gradle_scripts/extension_test.gradle b/gradle/gradle_scripts/extension_test.gradle index cc7abbec..a69e936c 100644 --- a/gradle/gradle_scripts/extension_test.gradle +++ b/gradle/gradle_scripts/extension_test.gradle @@ -18,7 +18,7 @@ def daemonCommand = attachDebugger ? ':app:runAttachedDebugger' : ':app:run' test { workingDir = rootDir - jvmArgs += ["--enable-preview", "-Xmx2g"] + jvmArgs += ["-Xmx2g"] // Daemon properties systemProperty "io.xpipe.beacon.daemonArgs", @@ -51,7 +51,7 @@ task productionTest(type: Test) { useJUnitPlatform() workingDir = rootDir - jvmArgs += ["--enable-preview", "-Xmx2g"] + jvmArgs += ["-Xmx2g"] // Daemon properties systemProperty "io.xpipe.beacon.daemonArgs", diff --git a/gradle/gradle_scripts/java.gradle b/gradle/gradle_scripts/java.gradle index 910ecb25..ee14af1d 100644 --- a/gradle/gradle_scripts/java.gradle +++ b/gradle/gradle_scripts/java.gradle @@ -4,7 +4,7 @@ tasks.withType(JavaCompile).configureEach { modularity.inferModulePath = true options.encoding = 'UTF-8' options.compilerArgs << "-Xlint:unchecked" - options.compilerArgs << "--enable-preview" + // options.compilerArgs << "--enable-preview" // These settings are explicitly specified as they can cause problems with annotation processors options.compilerArgs << "-implicit:none" diff --git a/version b/version index bbf649f6..3511591d 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.7.3 \ No newline at end of file +1.7.4 \ No newline at end of file