diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..f9dc4729 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,11 @@ +The following modules are licensed under the MIT license: +- api +- beacon +- core +- extension + +Everything else is licensed under GPL3. +As a special exception to GPL3 license, Christopher Schnick (the +author of X-Pipe) is granted permanent and irrevocable +permission to use this code for any purpose, and to modify, +distribute and sublicense it under any terms of his/her choosing. \ No newline at end of file diff --git a/README.md b/README.md index 0cd333b5..fa6fd7a0 100644 --- a/README.md +++ b/README.md @@ -160,3 +160,12 @@ You are also able to properly debug the built production application through two Note that when any unit test is run using a debugger, the X-Pipe daemon process that is started will also attempt to connect to that debugger through [AttachMe](https://plugins.jetbrains.com/plugin/13263-attachme) as well. +### Development FAQ + +##### Why are there no GitHub actions workflows or other continuous integration pipelines set up for this repository? + +There are several test workflows run in a private environment as they use private test connections +such as remote server connections and database connections. +Other private workflows are responsible for packaging, signing, and distributing the releases. +So you can assume that the code is tested! + diff --git a/gradle/gradle_scripts/LICENSE b/api/LICENSE.md similarity index 100% rename from gradle/gradle_scripts/LICENSE rename to api/LICENSE.md diff --git a/app/build.gradle b/app/build.gradle index a69b5e6b..4daf1db3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,8 +47,8 @@ dependencies { implementation group: 'org.kordamp.ikonli', name: 'ikonli-materialdesign2-pack', version: "12.2.0" implementation group: 'org.kordamp.ikonli', name: 'ikonli-javafx', version: "12.2.0" implementation group: 'org.kordamp.ikonli', name: 'ikonli-material-pack', version: "12.2.0" - implementation name: 'preferencesfx-core-lazy-11.11.0' - implementation name: 'formsfx-core-lazy-11.5.0' + implementation group: 'com.dlsc.preferencesfx', name: 'preferencesfx-core', version: '11.15.0' + implementation group: 'com.dlsc.formsfx', name: 'formsfx-core', version: '11.6.0' implementation group: 'org.slf4j', name: 'slf4j-api', version: '2.0.0' implementation 'io.xpipe:modulefs:0.1.4' implementation 'com.jfoenix:jfoenix:9.0.10' diff --git a/app/src/main/java/io/xpipe/app/comp/AppLayoutComp.java b/app/src/main/java/io/xpipe/app/comp/AppLayoutComp.java index 66f6861f..1f6a73ba 100644 --- a/app/src/main/java/io/xpipe/app/comp/AppLayoutComp.java +++ b/app/src/main/java/io/xpipe/app/comp/AppLayoutComp.java @@ -4,7 +4,7 @@ import io.xpipe.app.comp.about.AboutTabComp; import io.xpipe.app.comp.base.SideMenuBarComp; import io.xpipe.app.comp.storage.collection.SourceCollectionLayoutComp; import io.xpipe.app.comp.storage.store.StoreLayoutComp; -import io.xpipe.app.core.AppActionDetector; +import io.xpipe.app.core.AppActionLinkDetector; import io.xpipe.app.core.AppCache; import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppProperties; @@ -36,7 +36,7 @@ public class AppLayoutComp extends Comp> { selected = new SimpleObjectProperty<>(entries.get(0)); shortcut(new KeyCodeCombination(KeyCode.V, KeyCombination.SHORTCUT_DOWN), structure -> { - AppActionDetector.detectOnPaste(); + AppActionLinkDetector.detectOnPaste(); }); } diff --git a/app/src/main/java/io/xpipe/app/core/App.java b/app/src/main/java/io/xpipe/app/core/App.java index 38a91ab6..17bc174e 100644 --- a/app/src/main/java/io/xpipe/app/core/App.java +++ b/app/src/main/java/io/xpipe/app/core/App.java @@ -66,7 +66,7 @@ public class App extends Application { var content = new AppLayoutComp(); content.apply(struc -> { struc.get().addEventFilter(MouseEvent.MOUSE_CLICKED, event -> { - AppActionDetector.detectOnFocus(); + AppActionLinkDetector.detectOnFocus(); }); }); var title = String.format("X-Pipe Desktop (%s)", AppProperties.get().getVersion()); diff --git a/app/src/main/java/io/xpipe/app/core/AppActionDetector.java b/app/src/main/java/io/xpipe/app/core/AppActionLinkDetector.java similarity index 93% rename from app/src/main/java/io/xpipe/app/core/AppActionDetector.java rename to app/src/main/java/io/xpipe/app/core/AppActionLinkDetector.java index c54e91c9..2e0bf3ea 100644 --- a/app/src/main/java/io/xpipe/app/core/AppActionDetector.java +++ b/app/src/main/java/io/xpipe/app/core/AppActionLinkDetector.java @@ -8,7 +8,7 @@ import javafx.scene.input.DataFormat; import java.util.List; -public class AppActionDetector { +public class AppActionLinkDetector { private static String lastDetectedAction; @@ -34,6 +34,10 @@ public class AppActionDetector { LauncherInput.handle(List.of(content)); } + public static void setLastDetectedAction(String s) { + lastDetectedAction = s; + } + public static void detectOnFocus() { var content = getClipboardAction(); if (content == null) { diff --git a/app/src/main/java/io/xpipe/app/issue/ErrorHandlerComp.java b/app/src/main/java/io/xpipe/app/issue/ErrorHandlerComp.java index e793ee08..14f2c554 100644 --- a/app/src/main/java/io/xpipe/app/issue/ErrorHandlerComp.java +++ b/app/src/main/java/io/xpipe/app/issue/ErrorHandlerComp.java @@ -83,7 +83,8 @@ public class ErrorHandlerComp extends SimpleComp { if (desc == null) { desc = I18n.get("errorNoDetail"); } - var top = JfxHelper.createNamedEntry(I18n.get(headerId), desc, graphic); + var limitedDescription = desc.substring(0, Math.min(1000, desc.length())); + var top = JfxHelper.createNamedEntry(I18n.get(headerId), limitedDescription, graphic); var content = new VBox(top, new Separator(Orientation.HORIZONTAL)); if (event.isReportable()) { 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 7d2b6619..167e916b 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,6 @@ public class AppPrefs { private final BooleanField automaticallyUpdateField = BooleanField.ofBooleanType(automaticallyUpdate) .editable(AppDistributionType.get().supportsUpdate()) .render(() -> new ToggleControl()); - private final BooleanProperty sendAnonymousErrorReports = typed(new SimpleBooleanProperty(true), Boolean.class); - private final BooleanProperty sendUsageStatistics = typed(new SimpleBooleanProperty(true), Boolean.class); private final BooleanProperty updateToPrereleases = typed(new SimpleBooleanProperty(true), Boolean.class); private final BooleanProperty confirmDeletions = typed(new SimpleBooleanProperty(true), Boolean.class); @@ -282,14 +280,6 @@ public class AppPrefs { // Developer mode // ============== - public ReadOnlyBooleanProperty sendAnonymousErrorReports() { - return sendAnonymousErrorReports; - } - - public ReadOnlyBooleanProperty sendUsageStatistics() { - return sendUsageStatistics; - } - public ReadOnlyBooleanProperty updateToPrereleases() { return updateToPrereleases; } @@ -386,8 +376,6 @@ public class AppPrefs { externalStartupBehaviour), Setting.of("closeBehaviour", closeBehaviourControl, closeBehaviour), Setting.of("automaticallyUpdate", automaticallyUpdateField, automaticallyUpdate), - Setting.of("sendAnonymousErrorReports", sendAnonymousErrorReports), - Setting.of("sendUsageStatistics", sendUsageStatistics), Setting.of("storageDirectory", storageDirectoryControl, internalStorageDirectory), Setting.of("logLevel", logLevelField, internalLogLevel))), Category.of( diff --git a/app/src/main/java/io/xpipe/app/util/ProxyManagerProviderImpl.java b/app/src/main/java/io/xpipe/app/util/ProxyManagerProviderImpl.java index 87877dc7..a14ac913 100644 --- a/app/src/main/java/io/xpipe/app/util/ProxyManagerProviderImpl.java +++ b/app/src/main/java/io/xpipe/app/util/ProxyManagerProviderImpl.java @@ -21,7 +21,7 @@ public class ProxyManagerProviderImpl extends ProxyManagerProvider { alert.setAlertType(Alert.AlertType.CONFIRMATION); alert.setTitle(I18n.get("connectorInstallationTitle")); alert.setHeaderText(I18n.get("connectorInstallationHeader")); - alert.setContentText(I18n.get("connectorInstallationContent")); + alert.getDialogPane().setContent(AppWindowHelper.alertContentText(I18n.get("connectorInstallationContent"))); }) .filter(buttonType -> buttonType.getButtonData().isDefaultButton()) .isPresent(); 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 27d344f8..577e7622 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 @@ -1,6 +1,6 @@ connectorInstallationTitle=X-Pipe Connector connectorInstallationHeader=Would you like to install the X-Pipe connector on that host? -connectorInstallationContent=Some operations require the X-Pipe connector to be installed on the host.\nNote that this operation may take some time. +connectorInstallationContent=Some operations require the X-Pipe connector to be installed on the host. Note that this operation may take some time. errorOccured=An error occured terminalErrorOccured=A terminal error occured errorTypeOccured=An exception of type $TYPE$ was thrown diff --git a/beacon/LICENSE.md b/beacon/LICENSE.md new file mode 100644 index 00000000..4fe3f425 --- /dev/null +++ b/beacon/LICENSE.md @@ -0,0 +1,7 @@ +Copyright 2022 Christopher Schnick + +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. \ No newline at end of file diff --git a/core/LICENSE.md b/core/LICENSE.md new file mode 100644 index 00000000..4fe3f425 --- /dev/null +++ b/core/LICENSE.md @@ -0,0 +1,7 @@ +Copyright 2022 Christopher Schnick + +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. \ No newline at end of file diff --git a/core/src/main/java/io/xpipe/core/process/CommandProcessControl.java b/core/src/main/java/io/xpipe/core/process/CommandProcessControl.java index 68b92e18..97a748b4 100644 --- a/core/src/main/java/io/xpipe/core/process/CommandProcessControl.java +++ b/core/src/main/java/io/xpipe/core/process/CommandProcessControl.java @@ -7,6 +7,8 @@ import java.util.function.Consumer; public interface CommandProcessControl extends ProcessControl { + public CommandProcessControl doesNotObeyReturnValueConvention(); + @Override public CommandProcessControl sensitive(); CommandProcessControl complex(); diff --git a/dist/version b/dist/version index d9aecbd8..b1714db3 100644 --- a/dist/version +++ b/dist/version @@ -1 +1 @@ -0.4.21 \ No newline at end of file +0.4.22 \ No newline at end of file diff --git a/ext/base/src/main/java/io/xpipe/ext/base/actions/ShareStoreAction.java b/ext/base/src/main/java/io/xpipe/ext/base/actions/ShareStoreAction.java index a851505b..d5c610a7 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/actions/ShareStoreAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/actions/ShareStoreAction.java @@ -1,15 +1,16 @@ package io.xpipe.ext.base.actions; +import io.xpipe.app.core.AppActionLinkDetector; import io.xpipe.core.store.DataStore; import io.xpipe.core.util.SecretValue; import io.xpipe.extension.DataStoreActionProvider; import io.xpipe.extension.DataStoreProviders; import io.xpipe.extension.I18n; import javafx.beans.value.ObservableValue; -import javafx.scene.input.Clipboard; -import javafx.scene.input.DataFormat; -import java.util.Map; +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; public class ShareStoreAction implements DataStoreActionProvider { @@ -45,6 +46,9 @@ public class ShareStoreAction implements DataStoreActionProvider { @Override public void execute(DataStore store) throws Exception { var string = create(store); - Clipboard.getSystemClipboard().setContent(Map.of(DataFormat.PLAIN_TEXT, string, DataFormat.URL, string)); + var selection = new StringSelection(string); + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + AppActionLinkDetector.setLastDetectedAction(string); + clipboard.setContents(selection, selection); } } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/apps/SaveSourceTarget.java b/ext/base/src/main/java/io/xpipe/ext/base/apps/SaveSourceTarget.java index 42db6137..b80b1e21 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/apps/SaveSourceTarget.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/apps/SaveSourceTarget.java @@ -34,6 +34,12 @@ public class SaveSourceTarget implements DataSourceTarget { var storageGroup = new SimpleObjectProperty(); var dataSourceEntry = new SimpleObjectProperty(); SimpleChangeListener.apply(id, val -> { + if (val == null) { + storageGroup.set(null); + dataSourceEntry.set(null); + return; + } + storageGroup.set( SourceCollectionViewState.get().getSelectedGroup() != null ? SourceCollectionViewState.get().getSelectedGroup().getCollection() diff --git a/ext/base/src/main/java/module-info.java b/ext/base/src/main/java/module-info.java index 73ccf984..f51ebd36 100644 --- a/ext/base/src/main/java/module-info.java +++ b/ext/base/src/main/java/module-info.java @@ -9,19 +9,12 @@ import io.xpipe.extension.DataStoreActionProvider; import io.xpipe.extension.DataStoreProvider; import io.xpipe.extension.DataSourceTarget; -module io.xpipe.ext.base { +open module io.xpipe.ext.base { exports io.xpipe.ext.base; - - opens io.xpipe.ext.base; - exports io.xpipe.ext.base.apps; - - opens io.xpipe.ext.base.apps; - exports io.xpipe.ext.base.actions; - opens io.xpipe.ext.base.actions; - + requires java.desktop; requires io.xpipe.core; requires io.xpipe.extension; requires com.fasterxml.jackson.databind; diff --git a/extension/LICENSE.md b/extension/LICENSE.md new file mode 100644 index 00000000..4fe3f425 --- /dev/null +++ b/extension/LICENSE.md @@ -0,0 +1,7 @@ +Copyright 2022 Christopher Schnick + +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. \ No newline at end of file diff --git a/extension/build.gradle b/extension/build.gradle index cfe8c768..8b624cb2 100644 --- a/extension/build.gradle +++ b/extension/build.gradle @@ -35,8 +35,8 @@ dependencies { compileOnly 'com.jfoenix:jfoenix:9.0.10' compileOnly 'org.controlsfx:controlsfx:11.1.2' compileOnly 'org.apache.commons:commons-lang3:3.12.0' - compileOnly name: 'preferencesfx-core-lazy-11.11.0' - compileOnly name: 'formsfx-core-lazy-11.5.0' + compileOnly group: 'com.dlsc.preferencesfx', name: 'preferencesfx-core', version: '11.15.0' + compileOnly group: 'com.dlsc.formsfx', name: 'formsfx-core', version: '11.6.0' } task dist(type: Copy) { diff --git a/gradle/gradle_scripts/formsfx-core-lazy-11.5.0.jar b/gradle/gradle_scripts/formsfx-core-lazy-11.5.0.jar deleted file mode 100644 index 5d9da374..00000000 Binary files a/gradle/gradle_scripts/formsfx-core-lazy-11.5.0.jar and /dev/null differ diff --git a/gradle/gradle_scripts/preferencesfx-core-lazy-11.11.0.jar b/gradle/gradle_scripts/preferencesfx-core-lazy-11.11.0.jar deleted file mode 100644 index ff344335..00000000 Binary files a/gradle/gradle_scripts/preferencesfx-core-lazy-11.11.0.jar and /dev/null differ