From 211b516b7ba1f1bc754bbb2b68896a61f43be835 Mon Sep 17 00:00:00 2001 From: crschnick Date: Sun, 19 Feb 2023 17:44:47 +0000 Subject: [PATCH] Merge branch 'browser' --- app/build.gradle | 23 +- .../java/io/xpipe/app/browser/Bookmark.java | 8 + .../io/xpipe/app/browser/BookmarkList.java | 40 ++ .../xpipe/app/browser/BrowserClipboard.java | 61 +++ .../io/xpipe/app/browser/BrowserComp.java | 186 ++++++++++ .../io/xpipe/app/browser/BrowserModel.java | 56 +++ .../io/xpipe/app/browser/FileContextMenu.java | 66 ++++ .../io/xpipe/app/browser/FileListComp.java | 346 ++++++++++++++++++ .../io/xpipe/app/browser/FileListModel.java | 81 ++++ .../xpipe/app/browser/FileSystemHelper.java | 135 +++++++ .../xpipe/app/browser/NavigationHistory.java | 62 ++++ .../xpipe/app/browser/OpenFileSystemComp.java | 124 +++++++ .../app/browser/OpenFileSystemModel.java | 224 ++++++++++++ .../main/java/io/xpipe/app/browser/Utils.java | 57 +++ .../java/io/xpipe/app/comp/AppLayoutComp.java | 33 +- .../io/xpipe/app/comp/DeveloperTabComp.java | 16 +- .../java/io/xpipe/app/comp/PrefsComp.java | 12 +- .../io/xpipe/app/comp/about/AboutTabComp.java | 22 +- .../app/comp/about/BrowseDirectoryComp.java | 20 +- .../xpipe/app/comp/about/PropertiesComp.java | 20 +- .../about/ThirdPartyDependencyListComp.java | 6 +- .../xpipe/app/comp/about/UpdateCheckComp.java | 21 +- .../app/comp/base/BackgroundImageComp.java | 6 +- .../io/xpipe/app/comp/base/BigIconButton.java | 2 +- .../io/xpipe/app/comp/base/ButtonComp.java | 8 +- .../io/xpipe/app/comp/base/CountComp.java | 8 +- .../app/comp/base/FileDropOverlayComp.java | 6 +- .../app/comp/base/InstallExtensionComp.java | 16 +- .../app/comp/base/IntegratedTextAreaComp.java | 8 +- .../app/comp/base/LazyTextFieldComp.java | 8 +- .../xpipe/app/comp/base/ListBoxViewComp.java | 10 +- .../xpipe/app/comp/base/ListSelectorComp.java | 2 +- .../io/xpipe/app/comp/base/ListViewComp.java | 12 +- .../app/comp/base/LoadingOverlayComp.java | 10 +- .../io/xpipe/app/comp/base/MarkdownComp.java | 8 +- .../io/xpipe/app/comp/base/MessageComp.java | 8 +- .../xpipe/app/comp/base/MultiContentComp.java | 8 +- .../io/xpipe/app/comp/base/MultiStepComp.java | 16 +- .../xpipe/app/comp/base/SideMenuBarComp.java | 8 +- .../xpipe/app/comp/base/TitledPaneComp.java | 6 +- .../source/DataSourceTargetChoiceComp.java | 20 +- .../app/comp/source/DsCollectionComp.java | 12 +- .../app/comp/source/DsDataTransferComp.java | 26 +- .../app/comp/source/DsProviderChoiceComp.java | 24 +- .../io/xpipe/app/comp/source/DsRawComp.java | 10 +- .../comp/source/DsStorageGroupSelector.java | 4 +- .../app/comp/source/DsStorageTargetComp.java | 6 +- .../app/comp/source/DsStructureComp.java | 6 +- .../io/xpipe/app/comp/source/DsTableComp.java | 10 +- .../app/comp/source/DsTableMappingComp.java | 12 +- .../io/xpipe/app/comp/source/DsTextComp.java | 6 +- .../app/comp/source/DsTypeChoiceComp.java | 14 +- .../app/comp/source/GuiDsConfigStep.java | 18 +- .../comp/source/GuiDsCreatorMultiStep.java | 26 +- .../app/comp/source/GuiDsCreatorSaveStep.java | 10 +- .../comp/source/GuiDsCreatorTransferStep.java | 8 +- .../app/comp/source/GuiDsStoreSelectStep.java | 20 +- .../source/GuiDsTableMappingConfirmation.java | 20 +- .../comp/source/NamedSourceChoiceComp.java | 30 +- .../source/store/DataStoreSelectorComp.java | 16 +- .../source/store/DsDbStoreChooserComp.java | 12 +- .../comp/source/store/DsFileHistoryComp.java | 8 +- .../store/DsLocalDirectoryBrowseComp.java | 16 +- .../source/store/DsLocalFileBrowseComp.java | 22 +- .../source/store/DsRemoteFileChoiceComp.java | 13 +- .../store/DsStoreProviderChoiceComp.java | 16 +- .../source/store/DsStreamStoreChoiceComp.java | 40 +- .../comp/source/store/GuiDsStoreCreator.java | 42 +-- .../source/store/NamedStoreChoiceComp.java | 30 +- .../app/comp/storage/DataSourceTypeComp.java | 2 +- .../app/comp/storage/DataStoreTypeComp.java | 2 +- .../xpipe/app/comp/storage/StorageFilter.java | 2 +- .../collection/SourceCollectionComp.java | 19 +- .../SourceCollectionContextMenu.java | 30 +- .../SourceCollectionEmptyIntroComp.java | 18 +- .../SourceCollectionFilterBarComp.java | 8 +- .../SourceCollectionLayoutComp.java | 18 +- .../collection/SourceCollectionViewState.java | 8 +- .../collection/SourceCollectionWrapper.java | 2 +- .../comp/storage/source/SourceEntryComp.java | 18 +- .../source/SourceEntryContextMenu.java | 22 +- .../storage/source/SourceEntryListComp.java | 4 +- .../source/SourceEntryListHeaderComp.java | 24 +- .../storage/source/SourceEntryWrapper.java | 12 +- .../source/SourceStorageEmptyIntroComp.java | 14 +- .../storage/store/StoreCreationBarComp.java | 18 +- .../comp/storage/store/StoreEntryComp.java | 33 +- .../storage/store/StoreEntryListComp.java | 9 +- .../store/StoreEntryListHeaderComp.java | 6 +- .../comp/storage/store/StoreEntrySection.java | 10 +- .../comp/storage/store/StoreEntryWrapper.java | 6 +- .../comp/storage/store/StoreLayoutComp.java | 4 +- .../comp/storage/store/StoreNotFoundComp.java | 2 +- .../comp/storage/store/StoreSidebarComp.java | 6 +- .../store/StoreStorageEmptyIntroComp.java | 16 +- .../comp/storage/store/StoreViewState.java | 4 +- app/src/main/java/io/xpipe/app/core/App.java | 6 +- .../xpipe/app/core/AppActionLinkDetector.java | 7 +- .../main/java/io/xpipe/app/core/AppCache.java | 12 +- .../java/io/xpipe/app/core/AppChecks.java | 2 +- .../xpipe/app/core/AppExtensionManager.java | 208 ++++++----- .../main/java/io/xpipe/app/core/AppFont.java | 2 +- .../java/io/xpipe/app/core/AppGreetings.java | 15 +- .../main/java/io/xpipe/app/core/AppI18n.java | 42 ++- .../java/io/xpipe/app/core/AppImages.java | 33 +- .../main/java/io/xpipe/app/core/AppLock.java | 2 +- .../main/java/io/xpipe/app/core/AppLogs.java | 4 +- .../java/io/xpipe/app/core/AppMainWindow.java | 6 +- .../java/io/xpipe/app/core/AppProperties.java | 33 +- .../java/io/xpipe/app/core/AppResources.java | 2 +- .../io/xpipe/app/core/AppSocketServer.java | 4 +- .../main/java/io/xpipe/app/core/AppStyle.java | 9 +- .../main/java/io/xpipe/app/core/AppTray.java | 13 +- .../io/xpipe/app/core/AppWindowHelper.java | 8 +- .../io/xpipe/app/core/FileWatchManager.java | 6 +- .../java/io/xpipe/app/core/mode/BaseMode.java | 2 +- .../java/io/xpipe/app/core/mode/GuiMode.java | 4 +- .../io/xpipe/app/core/mode/OperationMode.java | 6 +- .../io/xpipe/app/core/mode/PlatformMode.java | 4 +- .../java/io/xpipe/app/core/mode/TrayMode.java | 2 +- .../app/exchange/ConvertExchangeImpl.java | 4 +- .../app/exchange/DialogExchangeImpl.java | 2 +- .../app/exchange/MessageExchangeImpl.java | 4 +- .../xpipe/app/exchange/ReadExchangeImpl.java | 4 +- .../WritePreparationExchangeImpl.java | 4 +- .../exchange/cli/ReadDrainExchangeImpl.java | 2 +- .../cli/SourceProviderListExchangeImpl.java | 2 +- .../app/exchange/cli/StopExchangeImpl.java | 2 +- .../exchange/cli/StoreAddExchangeImpl.java | 6 +- .../cli/StoreProviderListExchangeImpl.java | 4 +- .../io/xpipe/app/ext}/ActionProvider.java | 5 +- .../io/xpipe/app/ext}/DataSourceProvider.java | 10 +- .../xpipe/app/ext}/DataSourceProviders.java | 19 +- .../io/xpipe/app/ext}/DataSourceTarget.java | 6 +- .../io/xpipe/app/ext}/DataStoreProvider.java | 14 +- .../io/xpipe/app/ext}/DataStoreProviders.java | 4 +- .../xpipe/app/ext}/DownloadModuleInstall.java | 2 +- .../io/xpipe/app/ext}/ExtensionException.java | 2 +- .../java/io/xpipe/app/ext}/GuiDialog.java | 8 +- .../java/io/xpipe/app/ext}/ModuleInstall.java | 2 +- .../io/xpipe/app/ext}/PrefsChoiceValue.java | 8 +- .../java/io/xpipe/app/ext}/PrefsHandler.java | 2 +- .../java/io/xpipe/app/ext}/PrefsProvider.java | 4 +- .../xpipe/app/ext}/XPipeServiceProviders.java | 8 +- .../main/java/io/xpipe/app}/fxcomps/Comp.java | 12 +- .../io/xpipe/app}/fxcomps/CompStructure.java | 2 +- .../main/java/io/xpipe/app}/fxcomps/README.md | 0 .../io/xpipe/app}/fxcomps/SimpleComp.java | 2 +- .../app}/fxcomps/SimpleCompStructure.java | 2 +- .../io/xpipe/app/fxcomps/augment/Augment.java | 8 + .../app}/fxcomps/augment/GrowAugment.java | 4 +- .../fxcomps/augment/PopupMenuAugment.java | 4 +- .../app}/fxcomps/impl/CharChoiceComp.java | 8 +- .../io/xpipe/app}/fxcomps/impl/CharComp.java | 10 +- .../app}/fxcomps/impl/CharsetChoiceComp.java | 14 +- .../xpipe/app}/fxcomps/impl/ChoiceComp.java | 18 +- .../app}/fxcomps/impl/ChoicePaneComp.java | 16 +- .../xpipe/app}/fxcomps/impl/CodeSnippet.java | 2 +- .../app}/fxcomps/impl/CodeSnippetComp.java | 10 +- .../fxcomps/impl/DataStoreFlowChoiceComp.java | 18 +- .../app}/fxcomps/impl/DynamicOptionsComp.java | 10 +- .../fxcomps/impl/FancyTooltipAugment.java | 14 +- .../fxcomps/impl/FileStoreChoiceComp.java | 14 +- .../impl/FileSystemStoreChoiceComp.java | 10 +- .../xpipe/app}/fxcomps/impl/FilterComp.java | 10 +- .../xpipe/app}/fxcomps/impl/GrowPaneComp.java | 8 +- .../app}/fxcomps/impl/HorizontalComp.java | 8 +- .../app}/fxcomps/impl/IconButtonComp.java | 10 +- .../xpipe/app}/fxcomps/impl/IntFieldComp.java | 10 +- .../io/xpipe/app}/fxcomps/impl/LabelComp.java | 10 +- .../io/xpipe/app}/fxcomps/impl/PaneComp.java | 8 +- .../app/fxcomps/impl/PrettyImageComp.java | 140 +++++++ .../app}/fxcomps/impl/SecretFieldComp.java | 10 +- .../fxcomps/impl/ShellStoreChoiceComp.java | 18 +- .../io/xpipe/app}/fxcomps/impl/StackComp.java | 8 +- .../io/xpipe/app}/fxcomps/impl/SvgComp.java | 21 +- .../xpipe/app}/fxcomps/impl/TabPaneComp.java | 10 +- .../xpipe/app}/fxcomps/impl/TextAreaComp.java | 8 +- .../app}/fxcomps/impl/TextFieldComp.java | 12 +- .../app}/fxcomps/impl/ToggleGroupComp.java | 12 +- .../xpipe/app}/fxcomps/impl/VerticalComp.java | 10 +- .../xpipe/app}/fxcomps/impl/WrapperComp.java | 6 +- .../fxcomps/impl/WriteModeChoiceComp.java | 20 +- .../app}/fxcomps/util/BindingsHelper.java | 4 +- .../app}/fxcomps/util/PlatformThread.java | 2 +- .../io/xpipe/app}/fxcomps/util/Shortcuts.java | 2 +- .../fxcomps/util/SimpleChangeListener.java | 2 +- .../io/xpipe/app/issue/BasicErrorHandler.java | 2 - .../java/io/xpipe/app/issue/ErrorAction.java | 11 +- .../io/xpipe/app/issue/ErrorDetailsComp.java | 13 +- .../java/io/xpipe/app/issue}/ErrorEvent.java | 2 +- .../java/io/xpipe/app/issue/ErrorHandler.java | 2 - .../io/xpipe/app/issue/ErrorHandlerComp.java | 21 +- .../io/xpipe/app/issue}/EventHandler.java | 2 +- .../io/xpipe/app/issue/EventHandlerImpl.java | 3 - .../xpipe/app/issue/ExceptionConverter.java | 32 ++ .../xpipe/app/issue/SentryErrorHandler.java | 4 +- .../xpipe/app/issue/TerminalErrorHandler.java | 12 +- .../java/io/xpipe/app/issue}/TrackEvent.java | 2 +- .../io/xpipe/app/issue/UserReportComp.java | 19 +- .../xpipe/app/launcher/LauncherCommand.java | 6 +- .../io/xpipe/app/launcher/LauncherInput.java | 8 +- .../java/io/xpipe/app/prefs/AppPrefs.java | 48 ++- .../io/xpipe/app/prefs/ClearCacheAlert.java | 8 +- .../io/xpipe/app/prefs/CloseBehaviour.java | 2 +- .../xpipe/app/prefs/CloseBehaviourAlert.java | 8 +- .../xpipe/app/prefs/CustomFormRenderer.java | 5 +- .../app/prefs/ExternalApplicationType.java | 4 +- .../xpipe/app/prefs/ExternalEditorType.java | 6 +- .../app/prefs/ExternalStartupBehaviour.java | 2 +- .../xpipe/app/prefs/ExternalTerminalType.java | 290 +++++++++++++++ .../xpipe/app/prefs/JsonStorageHandler.java | 10 +- .../java/io/xpipe/app/prefs/PrefFields.java | 4 +- .../app/prefs/QuietResourceBundleService.java | 4 +- .../io/xpipe/app/prefs/SupportedLocale.java | 2 +- .../prefs/TranslatableComboBoxControl.java | 2 +- .../io/xpipe/app/storage/DataSourceEntry.java | 6 +- .../io/xpipe/app/storage/DataStorage.java | 20 +- .../xpipe/app/storage/DataStorageParser.java | 4 +- .../io/xpipe/app/storage/DataStoreEntry.java | 6 +- .../app/storage/ImpersistentStorage.java | 4 +- .../io/xpipe/app/storage/StandardStorage.java | 4 +- .../xpipe/app}/test/DaemonExtensionTest.java | 4 +- .../io/xpipe/app}/test/ExtensionTest.java | 2 +- .../xpipe/app}/test/LocalExtensionTest.java | 4 +- .../java/io/xpipe/app}/test/TestModule.java | 2 +- .../io/xpipe/app/update/AppDownloads.java | 6 +- .../io/xpipe/app/update/AppInstaller.java | 12 +- .../java/io/xpipe/app/update/AppUpdater.java | 12 +- .../app/update/UpdateAvailableAlert.java | 8 +- .../app/update/UpdateChangelogAlert.java | 8 +- .../xpipe/app/update/XPipeInstanceHelper.java | 2 +- .../io/xpipe/app}/util/ApplicationHelper.java | 4 +- .../java/io/xpipe/app}/util/BusyProperty.java | 9 +- .../io/xpipe/app}/util/ChainedValidator.java | 2 +- .../java/io/xpipe/app/util/Containers.java | 64 ++++ .../main/java/io/xpipe/app/util/Controls.java | 73 ++++ .../app}/util/CustomComboBoxBuilder.java | 6 +- .../xpipe/app}/util/DataStoreFormatter.java | 4 +- .../io/xpipe/app}/util/DataTypeParser.java | 2 +- .../app}/util/DataTypeParserInternal.java | 2 +- .../io/xpipe/app}/util/DesktopHelper.java | 4 +- .../io/xpipe/app}/util/DesktopShortcuts.java | 2 +- .../java/io/xpipe/app}/util/DialogHelper.java | 6 +- .../app}/util/DynamicOptionsBuilder.java | 34 +- .../xpipe/app}/util/ExclusiveValidator.java | 2 +- .../io/xpipe/app/util/ExternalEditor.java | 25 +- .../java/io/xpipe/app}/util/HostHelper.java | 2 +- .../java/io/xpipe/app}/util/HttpHelper.java | 2 +- .../xpipe/app/util/HumanReadableFormat.java | 63 ++++ .../java/io/xpipe/app/util/Hyperlinks.java | 2 +- .../java/io/xpipe/app/util/JfxHelper.java | 2 +- .../io/xpipe/app/util/JsonConfigHelper.java | 2 +- .../io/xpipe/app/util/MacOsPermissions.java | 9 +- .../io/xpipe/app}/util/ModuleLayerLoader.java | 5 +- .../io/xpipe/app}/util/NamedCharacter.java | 2 +- .../io/xpipe/app}/util/PrettyListView.java | 2 +- .../app/util/ProxyManagerProviderImpl.java | 14 +- .../java/io/xpipe/app}/util/ScriptHelper.java | 4 +- .../io/xpipe/app}/util/SimpleValidator.java | 2 +- .../io/xpipe/app/util/TerminalHelper.java | 15 + .../io/xpipe/app/util/TerminalProvider.java | 41 --- .../java/io/xpipe/app}/util/ThreadHelper.java | 4 +- .../java/io/xpipe/app/util}/Translatable.java | 2 +- .../io/xpipe/app}/util/TypeConverter.java | 2 +- .../app}/util/UniformDataSourceProvider.java | 4 +- .../java/io/xpipe/app}/util/Validatable.java | 2 +- .../java/io/xpipe/app}/util/Validator.java | 9 +- .../java/io/xpipe/app}/util/Validators.java | 19 +- .../io/xpipe/app}/util/WindowsRegistry.java | 2 +- .../java/io/xpipe/app}/util/XPipeDaemon.java | 8 +- .../xpipe/app/util/XPipeDaemonProvider.java | 8 +- .../app}/util/XPipeDistributionType.java | 4 +- app/src/main/java/module-info.java | 45 ++- .../resources/lang/preferences_en.properties | 15 + .../resources/lang/translations_en.properties | 33 +- .../style/{simple-alert.css => alert.css} | 14 +- .../io/xpipe/app/resources/style/browser.css | 32 ++ .../app}/resources/style/code-snippet.css | 0 .../resources/style/error-handler-comp.css | 2 +- .../xpipe/app/resources/style/header-bars.css | 10 +- .../resources/style/lazy-text-field-comp.css | 4 +- .../app/resources/style/multi-step-comp.css | 10 +- .../app/resources/style/sidebar-comp.css | 4 +- .../style/storage-group-list-comp.css | 13 - .../io/xpipe/app/resources/style/tab-pane.css | 2 +- app/src/test/java/test/DataSourceTest.java | 4 +- .../test/java/test/TestSourcesDatabase.java | 2 +- .../java/io/xpipe/core/impl/FileNames.java | 7 +- .../java/io/xpipe/core/impl/FileStore.java | 8 +- .../java/io/xpipe/core/impl/LocalStore.java | 98 +++-- .../core/process/CommandProcessControl.java | 20 +- .../core/process/ShellProcessControl.java | 2 + .../java/io/xpipe/core/process/ShellType.java | 16 + .../core/source/CollectionDataSource.java | 18 +- .../core/source/CollectionReadConnection.java | 3 +- .../core/store/ConnectionFileSystem.java | 115 ++++++ .../java/io/xpipe/core/store/FileSystem.java | 61 +++ .../io/xpipe/core/store/FileSystemStore.java | 11 +- .../io/xpipe/core/store/MachineStore.java | 35 +- .../java/io/xpipe/core/store/ShellStore.java | 7 +- .../io/xpipe/core/util/CoreJacksonModule.java | 3 +- .../io/xpipe/core/util/XPipeInstallation.java | 11 +- dist/jpackage.gradle | 1 + dist/licenses/atlantafx.license | 21 ++ dist/licenses/atlantafx.properties | 4 + .../xpipe/ext/base/BinarySourceProvider.java | 2 +- .../io/xpipe/ext/base/FileStoreProvider.java | 12 +- .../java/io/xpipe/ext/base/HttpStore.java | 2 +- .../io/xpipe/ext/base/HttpStoreProvider.java | 22 +- .../xpipe/ext/base/InMemoryStoreProvider.java | 14 +- .../ext/base/InternalStreamProvider.java | 4 +- .../io/xpipe/ext/base/LocalStoreProvider.java | 4 +- .../xpipe/ext/base/MachineRootContainer.java | 18 + .../ext/base/ReadOnlyCollectionSource.java | 16 + .../ext/base/SimpleCollectionSource.java | 28 ++ .../base/SimpleFileDataSourceProvider.java | 8 +- .../ext/base/SinkDrainStoreProvider.java | 24 +- .../io/xpipe/ext/base/TextSourceProvider.java | 4 +- .../java/io/xpipe/ext/base/XpbsProvider.java | 2 +- .../java/io/xpipe/ext/base/XpbtProvider.java | 2 +- .../ext/base/actions/AddStoreAction.java | 2 +- .../ext/base/actions/EditStoreAction.java | 6 +- .../ext/base/actions/FileBrowseAction.java | 8 +- .../ext/base/actions/FileEditAction.java | 6 +- .../ext/base/actions/ShareStoreAction.java | 8 +- .../ext/base/actions/StreamExportAction.java | 16 +- .../ext/base/apps/CommandLineTarget.java | 14 +- .../ext/base/apps/DataSourceOutputTarget.java | 22 +- .../xpipe/ext/base/apps/FileOutputTarget.java | 28 +- .../io/xpipe/ext/base/apps/JavaTarget.java | 10 +- .../ext/base/apps/RawFileOutputTarget.java | 14 +- .../xpipe/ext/base/apps/SaveSourceTarget.java | 12 +- ext/base/src/main/java/module-info.java | 10 +- ext/collections/build.gradle | 1 + .../collections/ArchiveEntryDataStore.java | 6 +- .../ext/collections/ArchiveEntryStore.java | 3 +- .../collections/ArchiveReadConnection.java | 14 +- .../ext/collections/DirectoryProvider.java | 12 +- .../src/main/java/module-info.java | 4 +- ext/csv/build.gradle | 4 + .../java/io/xpipe/ext/csv/CsvDelimiter.java | 4 +- .../java/io/xpipe/ext/csv/CsvDetector.java | 2 +- .../java/io/xpipe/ext/csv/CsvQuoteChar.java | 2 +- .../main/java/io/xpipe/ext/csv/CsvSource.java | 2 +- .../io/xpipe/ext/csv/CsvSourceProvider.java | 24 +- ext/csv/src/main/java/module-info.java | 4 +- ext/jackson/build.gradle | 1 + .../xpipe/ext/jackson/json/JsonProvider.java | 6 +- .../jackson/json_table/JsonTableProvider.java | 8 +- .../io/xpipe/ext/jackson/xml/XmlProvider.java | 4 +- .../jackson/xml_table/XmlTableProvider.java | 8 +- ext/jackson/src/main/java/module-info.java | 4 +- ext/pdx/build.gradle | 4 + .../io/xpipe/ext/pdx/Eu4FileProvider.java | 2 +- .../io/xpipe/ext/pdx/PdxFileProvider.java | 5 +- .../io/xpipe/ext/pdx/PdxTextFileProvider.java | 4 +- ext/pdx/src/main/java/module-info.java | 4 +- extension/LICENSE.md | 7 - extension/README.md | 7 - extension/build.gradle | 48 --- extension/publish.gradle | 33 -- .../main/java/io/xpipe/extension/Cache.java | 27 -- .../main/java/io/xpipe/extension/I18n.java | 32 -- .../extension/event/ExceptionConverter.java | 32 -- .../extension/fxcomps/augment/Augment.java | 8 - .../fxcomps/impl/PrettyImageComp.java | 96 ----- extension/src/main/java/module-info.java | 61 --- .../com.fasterxml.jackson.databind.Module | 1 - .../resources/lang/translations_de.properties | 3 - .../resources/lang/translations_en.properties | 31 -- gradle/gradle_scripts/extension.gradle | 39 +- gradle/gradle_scripts/extension_test.gradle | 1 - settings.gradle | 1 - 374 files changed, 4228 insertions(+), 2058 deletions(-) create mode 100644 app/src/main/java/io/xpipe/app/browser/Bookmark.java create mode 100644 app/src/main/java/io/xpipe/app/browser/BookmarkList.java create mode 100644 app/src/main/java/io/xpipe/app/browser/BrowserClipboard.java create mode 100644 app/src/main/java/io/xpipe/app/browser/BrowserComp.java create mode 100644 app/src/main/java/io/xpipe/app/browser/BrowserModel.java create mode 100644 app/src/main/java/io/xpipe/app/browser/FileContextMenu.java create mode 100644 app/src/main/java/io/xpipe/app/browser/FileListComp.java create mode 100644 app/src/main/java/io/xpipe/app/browser/FileListModel.java create mode 100644 app/src/main/java/io/xpipe/app/browser/FileSystemHelper.java create mode 100644 app/src/main/java/io/xpipe/app/browser/NavigationHistory.java create mode 100644 app/src/main/java/io/xpipe/app/browser/OpenFileSystemComp.java create mode 100644 app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java create mode 100644 app/src/main/java/io/xpipe/app/browser/Utils.java rename {extension/src/main/java/io/xpipe/extension/util => app/src/main/java/io/xpipe/app/ext}/ActionProvider.java (96%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app/ext}/DataSourceProvider.java (93%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app/ext}/DataSourceProviders.java (91%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app/ext}/DataSourceTarget.java (94%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app/ext}/DataStoreProvider.java (88%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app/ext}/DataStoreProviders.java (97%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app/ext}/DownloadModuleInstall.java (95%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app/ext}/ExtensionException.java (95%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app/ext}/GuiDialog.java (63%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app/ext}/ModuleInstall.java (94%) rename {extension/src/main/java/io/xpipe/extension/prefs => app/src/main/java/io/xpipe/app/ext}/PrefsChoiceValue.java (91%) rename {extension/src/main/java/io/xpipe/extension/prefs => app/src/main/java/io/xpipe/app/ext}/PrefsHandler.java (85%) rename {extension/src/main/java/io/xpipe/extension/prefs => app/src/main/java/io/xpipe/app/ext}/PrefsProvider.java (94%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app/ext}/XPipeServiceProviders.java (90%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/Comp.java (91%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/CompStructure.java (74%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/README.md (100%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/SimpleComp.java (88%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/SimpleCompStructure.java (88%) create mode 100644 app/src/main/java/io/xpipe/app/fxcomps/augment/Augment.java rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/augment/GrowAugment.java (95%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/augment/PopupMenuAugment.java (90%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/CharChoiceComp.java (88%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/CharComp.java (79%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/CharsetChoiceComp.java (77%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/ChoiceComp.java (84%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/ChoicePaneComp.java (85%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/CodeSnippet.java (98%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/CodeSnippetComp.java (95%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/DataStoreFlowChoiceComp.java (63%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/DynamicOptionsComp.java (95%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/FancyTooltipAugment.java (96%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/FileStoreChoiceComp.java (87%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/FileSystemStoreChoiceComp.java (87%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/FilterComp.java (88%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/GrowPaneComp.java (75%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/HorizontalComp.java (76%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/IconButtonComp.java (87%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/IntFieldComp.java (91%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/LabelComp.java (74%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/PaneComp.java (74%) create mode 100644 app/src/main/java/io/xpipe/app/fxcomps/impl/PrettyImageComp.java rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/SecretFieldComp.java (80%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/ShellStoreChoiceComp.java (87%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/StackComp.java (76%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/SvgComp.java (90%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/TabPaneComp.java (89%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/TextAreaComp.java (92%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/TextFieldComp.java (87%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/ToggleGroupComp.java (89%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/VerticalComp.java (80%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/WrapperComp.java (73%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/impl/WriteModeChoiceComp.java (79%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/util/BindingsHelper.java (98%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/util/PlatformThread.java (99%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/util/Shortcuts.java (97%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/fxcomps/util/SimpleChangeListener.java (91%) rename {extension/src/main/java/io/xpipe/extension/event => app/src/main/java/io/xpipe/app/issue}/ErrorEvent.java (97%) rename {extension/src/main/java/io/xpipe/extension/event => app/src/main/java/io/xpipe/app/issue}/EventHandler.java (98%) create mode 100644 app/src/main/java/io/xpipe/app/issue/ExceptionConverter.java rename {extension/src/main/java/io/xpipe/extension/event => app/src/main/java/io/xpipe/app/issue}/TrackEvent.java (99%) create mode 100644 app/src/main/java/io/xpipe/app/prefs/ExternalTerminalType.java rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/test/DaemonExtensionTest.java (93%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/test/ExtensionTest.java (97%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/test/LocalExtensionTest.java (84%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/test/TestModule.java (98%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/ApplicationHelper.java (95%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/BusyProperty.java (53%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/ChainedValidator.java (99%) create mode 100644 app/src/main/java/io/xpipe/app/util/Containers.java create mode 100644 app/src/main/java/io/xpipe/app/util/Controls.java rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/CustomComboBoxBuilder.java (97%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/DataStoreFormatter.java (97%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/DataTypeParser.java (97%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/DataTypeParserInternal.java (99%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/DesktopHelper.java (94%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/DesktopShortcuts.java (99%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/DialogHelper.java (97%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/DynamicOptionsBuilder.java (87%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/ExclusiveValidator.java (98%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/HostHelper.java (90%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/HttpHelper.java (98%) create mode 100644 app/src/main/java/io/xpipe/app/util/HumanReadableFormat.java rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/ModuleLayerLoader.java (91%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/NamedCharacter.java (98%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/PrettyListView.java (99%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/ScriptHelper.java (98%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/SimpleValidator.java (99%) create mode 100644 app/src/main/java/io/xpipe/app/util/TerminalHelper.java delete mode 100644 app/src/main/java/io/xpipe/app/util/TerminalProvider.java rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/ThreadHelper.java (92%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app/util}/Translatable.java (98%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/TypeConverter.java (99%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/UniformDataSourceProvider.java (79%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/Validatable.java (66%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/Validator.java (93%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/Validators.java (55%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/WindowsRegistry.java (96%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/XPipeDaemon.java (92%) rename {extension/src/main/java/io/xpipe/extension => app/src/main/java/io/xpipe/app}/util/XPipeDistributionType.java (96%) rename app/src/main/resources/io/xpipe/app/resources/style/{simple-alert.css => alert.css} (76%) create mode 100644 app/src/main/resources/io/xpipe/app/resources/style/browser.css rename {extension/src/main/resources/io/xpipe/extension => app/src/main/resources/io/xpipe/app}/resources/style/code-snippet.css (100%) create mode 100644 core/src/main/java/io/xpipe/core/store/ConnectionFileSystem.java create mode 100644 core/src/main/java/io/xpipe/core/store/FileSystem.java create mode 100644 dist/licenses/atlantafx.license create mode 100644 dist/licenses/atlantafx.properties create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/MachineRootContainer.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/ReadOnlyCollectionSource.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/SimpleCollectionSource.java rename core/src/main/java/io/xpipe/core/impl/CollectionEntryDataStore.java => ext/collections/src/main/java/io/xpipe/ext/collections/ArchiveEntryDataStore.java (76%) delete mode 100644 extension/LICENSE.md delete mode 100644 extension/README.md delete mode 100644 extension/build.gradle delete mode 100644 extension/publish.gradle delete mode 100644 extension/src/main/java/io/xpipe/extension/Cache.java delete mode 100644 extension/src/main/java/io/xpipe/extension/I18n.java delete mode 100644 extension/src/main/java/io/xpipe/extension/event/ExceptionConverter.java delete mode 100644 extension/src/main/java/io/xpipe/extension/fxcomps/augment/Augment.java delete mode 100644 extension/src/main/java/io/xpipe/extension/fxcomps/impl/PrettyImageComp.java delete mode 100644 extension/src/main/java/module-info.java delete mode 100644 extension/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module delete mode 100644 extension/src/main/resources/io/xpipe/extension/resources/lang/translations_de.properties delete mode 100644 extension/src/main/resources/io/xpipe/extension/resources/lang/translations_en.properties diff --git a/app/build.gradle b/app/build.gradle index b6f6ad448..95ca73cf6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,3 @@ -import java.util.stream.Collectors - plugins { id 'application' id "org.moditect.gradleplugin" version "1.0.0-rc3" @@ -32,10 +30,14 @@ configurations { } dependencies { + compileOnly project(':api') implementation project(':core') - implementation project(':extension') implementation project(':beacon') + compileOnly 'org.hamcrest:hamcrest:2.2' + compileOnly 'org.junit.jupiter:junit-jupiter-api:5.9.0' + compileOnly 'org.junit.jupiter:junit-jupiter-params:5.9.0' + implementation 'net.java.dev.jna:jna-jpms:5.12.1' implementation 'net.java.dev.jna:jna-platform-jpms:5.12.1' implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "2.13.0" @@ -46,6 +48,7 @@ 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 group: 'org.kordamp.ikonli', name: 'ikonli-feather-pack', version: "12.2.0" implementation name: 'preferencesfx-core-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' @@ -67,7 +70,6 @@ sourceSets { dependencies { testImplementation project(':api') testImplementation project(':core') - testImplementation project(':extension') } Arrays.stream(file("$rootDir/ext").list()) @@ -87,12 +89,12 @@ List jvmRunArgs = [ "--add-exports", "javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix", "--add-exports", "javafx.graphics/com.sun.javafx.scene.traversal=org.controlsfx.controls", "--add-exports", "javafx.graphics/com.sun.javafx.scene=org.controlsfx.controls", - "--add-exports", "org.apache.commons.lang3/org.apache.commons.lang3.math=io.xpipe.extension", + "--add-exports", "org.apache.commons.lang3/org.apache.commons.lang3.math=io.xpipe.app", "--add-opens", "java.base/java.lang.reflect=com.jfoenix", "--add-opens", "java.base/java.lang.reflect=com.jfoenix", "--add-opens", "java.base/java.lang=io.xpipe.core", "--add-opens", "com.dustinredmond.fxtrayicon/com.dustinredmond.fxtrayicon=io.xpipe.app", - "--add-opens", "net.synedra.validatorfx/net.synedra.validatorfx=io.xpipe.extension", + "--add-opens", "net.synedra.validatorfx/net.synedra.validatorfx=io.xpipe.app", "--add-opens", 'com.dlsc.preferencesfx/com.dlsc.preferencesfx.view=io.xpipe.app', "-Xmx8g", "--enable-preview", @@ -102,9 +104,6 @@ List jvmRunArgs = [ ] -def extensionDirList = Arrays.stream(file("$rootDir/ext").list()) - .map(l -> project(":$l").buildDir.toString() + "/libs_dev").filter {file(it).exists()}.collect(Collectors.joining(File.pathSeparator)); - test { jvmArgs += jvmRunArgs systemProperty 'io.xpipe.app.mode', 'background' @@ -113,8 +112,8 @@ test { systemProperty 'io.xpipe.app.writeSysOut', "true" systemProperty 'io.xpipe.app.developerMode', "true" systemProperty 'io.xpipe.app.logLevel', "trace" + systemProperty 'io.xpipe.app.fullVersion', rootProject.fullVersion //systemProperty "io.xpipe.beacon.port", "21722" - systemProperty "io.xpipe.app.extensions", extensionDirList } @@ -133,14 +132,14 @@ application { run { systemProperty 'io.xpipe.app.mode', 'gui' - systemProperty 'io.xpipe.app.dataDir', "$projectDir/local6/" + systemProperty 'io.xpipe.app.dataDir', "$projectDir/local_stage/" systemProperty 'io.xpipe.app.writeLogs', "true" systemProperty 'io.xpipe.app.writeSysOut', "true" systemProperty 'io.xpipe.app.developerMode', "true" systemProperty 'io.xpipe.app.logLevel', "trace" + systemProperty 'io.xpipe.app.fullVersion', rootProject.fullVersion // systemProperty "io.xpipe.beacon.port", "21724" // systemProperty "io.xpipe.beacon.printMessages", "true" - systemProperty "io.xpipe.app.extensions", extensionDirList // systemProperty 'io.xpipe.app.debugPlatform', "true" // systemProperty "io.xpipe.beacon.localProxy", "true" diff --git a/app/src/main/java/io/xpipe/app/browser/Bookmark.java b/app/src/main/java/io/xpipe/app/browser/Bookmark.java new file mode 100644 index 000000000..e08a39120 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/Bookmark.java @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: MIT */ + +package io.xpipe.app.browser; + +import io.xpipe.app.storage.DataStoreEntry; + +record Bookmark(DataStoreEntry entry) { +} diff --git a/app/src/main/java/io/xpipe/app/browser/BookmarkList.java b/app/src/main/java/io/xpipe/app/browser/BookmarkList.java new file mode 100644 index 000000000..72afff0dc --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/BookmarkList.java @@ -0,0 +1,40 @@ +package io.xpipe.app.browser; + +import com.jfoenix.controls.JFXButton; +import io.xpipe.app.comp.base.ListBoxViewComp; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.PrettyImageComp; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.core.store.ShellStore; +import javafx.beans.property.SimpleStringProperty; +import javafx.collections.FXCollections; +import javafx.geometry.Pos; +import javafx.scene.layout.Region; + +final class BookmarkList extends SimpleComp { + + private final BrowserModel model; + + BookmarkList(BrowserModel model) { + this.model = model; + } + + @Override + protected Region createSimple() { + var list = DataStorage.get().getStores().stream().filter(entry -> entry.getStore() instanceof ShellStore).map(entry -> new Bookmark(entry)).toList(); + return new ListBoxViewComp<>(FXCollections.observableList(list), FXCollections.observableList(list), bookmark -> { + var imgView = + new PrettyImageComp(new SimpleStringProperty(bookmark.entry().getProvider().getDisplayIconFileName()), 16, 16).createRegion(); + var button = new JFXButton(bookmark.entry().getName(), imgView); + button.setOnAction(event -> { + event.consume(); + + var fileSystem = ((ShellStore) bookmark.entry().getStore()); + model.openFileSystem(fileSystem); + }); + button.setAlignment(Pos.CENTER_LEFT); + return Comp.of(() -> button).grow(true, false); + }).createRegion(); + } +} diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserClipboard.java b/app/src/main/java/io/xpipe/app/browser/BrowserClipboard.java new file mode 100644 index 000000000..d0f81e4d5 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/BrowserClipboard.java @@ -0,0 +1,61 @@ +package io.xpipe.app.browser; + +import io.xpipe.core.store.FileSystem; +import io.xpipe.core.util.XPipeTempDirectory; +import javafx.scene.input.ClipboardContent; +import javafx.scene.input.Dragboard; +import lombok.SneakyThrows; +import lombok.Value; + +import java.nio.file.Files; +import java.util.*; + +public class BrowserClipboard { + + @Value + public static class Instance { + UUID uuid; + List entries; + } + + public static Map> CLIPBOARD = new HashMap<>(); + public static Instance currentCopyClipboard; + public static Instance currentDragClipboard; + + @SneakyThrows + public static ClipboardContent startDrag(List selected) { + var content = new ClipboardContent(); + var idea = UUID.randomUUID(); + var file = XPipeTempDirectory.getLocal().resolve(idea.toString()); + Files.createFile(file); + currentDragClipboard = new Instance(idea, selected); + content.putFiles(List.of(file.toFile())); + return content; + } + + @SneakyThrows + public static void startCopy(List selected) { + var idea = UUID.randomUUID(); + currentCopyClipboard = new Instance(idea, new ArrayList<>(selected)); + } + + public static Instance retrieveCopy() { + var current = currentCopyClipboard; + return current; + } + + public static Instance retrieveDrag(Dragboard dragboard) { + if (dragboard.getFiles().size() != 1) { + return null; + } + + var idea = UUID.fromString(dragboard.getFiles().get(0).toPath().getFileName().toString()); + if (idea.equals(currentDragClipboard.uuid)) { + var current = currentDragClipboard; + currentDragClipboard = null; + return current; + } + + return null; + } +} diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserComp.java new file mode 100644 index 000000000..7277b54cc --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/BrowserComp.java @@ -0,0 +1,186 @@ +package io.xpipe.app.browser; + +import atlantafx.base.controls.RingProgressIndicator; +import atlantafx.base.theme.Styles; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.PrettyImageComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.storage.DataStorage; +import javafx.beans.binding.Bindings; +import javafx.collections.ListChangeListener; +import javafx.event.EventHandler; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.control.SplitPane; +import javafx.scene.control.Tab; +import javafx.scene.control.TabPane; +import javafx.scene.input.DragEvent; +import javafx.scene.layout.Region; +import javafx.scene.layout.StackPane; + +import java.util.HashMap; + +import static atlantafx.base.theme.Styles.DENSE; +import static atlantafx.base.theme.Styles.toggleStyleClass; +import static javafx.scene.control.TabPane.TabClosingPolicy.ALL_TABS; + +public class BrowserComp extends SimpleComp { + + private static final double TAB_MIN_HEIGHT = 60; + + private final BrowserModel model; + + public BrowserComp(BrowserModel model) { + this.model = model; + } + + @Override + protected Region createSimple() { + var bookmarksList = new BookmarkList(model).createRegion(); + var splitPane = new SplitPane(bookmarksList, createTabs()); + splitPane + .widthProperty() + .addListener( + // set sidebar width in pixels depending on split pane width + (obs, old, val) -> splitPane.setDividerPosition(0, 230 / splitPane.getWidth())); + + return splitPane; + } + + private Node createTabs() { + var stack = new StackPane(); + var tabs = createTabPane(); + stack.getChildren().add(tabs); + + var map = new HashMap(); + + tabs.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> { + if (newValue.intValue() == -1) { + model.getSelected().setValue(null); + return; + } + + model.getSelected().setValue(model.getOpenFileSystems().get(newValue.intValue())); + }); + + model.getOpenFileSystems().forEach(v -> { + var t = createTab(tabs, v); + map.put(v, t); + tabs.getTabs().add(t); + }); + if (model.getOpenFileSystems().size() > 0) { + tabs.getSelectionModel().select(0); + } + + model.getOpenFileSystems().addListener((ListChangeListener) c -> { + PlatformThread.runLaterBlocking(() -> { + while (c.next()) { + for (var r : c.getRemoved()) { + var t = map.remove(r); + tabs.getTabs().remove(t); + } + + for (var a : c.getAddedSubList()) { + var t = createTab(tabs, a); + map.put(a, t); + tabs.getTabs().add(t); + } + } + }); + }); + + model.getSelected().addListener((observable, oldValue, newValue) -> { + tabs.getSelectionModel().select(model.getOpenFileSystems().indexOf(newValue)); + }); + + tabs.getTabs().addListener((ListChangeListener) c -> { + while (c.next()) { + for (var r : c.getRemoved()) { + var source = map.entrySet().stream() + .filter(openFileSystemModelTabEntry -> + openFileSystemModelTabEntry.getValue().equals(r)) + .findAny() + .orElseThrow(); + model.closeFileSystem(source.getKey()); + } + } + }); + + stack.getStyleClass().add("browser"); + return stack; + } + + private Node createSingular() { + var stack = + new StackPane(new OpenFileSystemComp(model.getOpenFileSystems().get(0)).createSimple()); + return stack; + } + + private TabPane createTabPane() { + var tabs = new TabPane(); + tabs.setTabDragPolicy(TabPane.TabDragPolicy.REORDER); + tabs.setTabClosingPolicy(ALL_TABS); + Styles.toggleStyleClass(tabs, TabPane.STYLE_CLASS_FLOATING); + // tabs.setStyle("-fx-open-tab-animation:none;-fx-close-tab-animation:none;"); + toggleStyleClass(tabs, DENSE); + tabs.setMinHeight(TAB_MIN_HEIGHT); + tabs.setTabMinWidth(Region.USE_COMPUTED_SIZE); + + return tabs; + } + + private Tab createTab(TabPane tabs, OpenFileSystemModel model) { + var tab = new Tab(); + + var ring = new RingProgressIndicator(0, false); + ring.setMinSize(14, 14); + ring.setPrefSize(14, 14); + ring.setMaxSize(14, 14); + ring.progressProperty() + .bind(Bindings.createDoubleBinding( + () -> model.getBusy().get() ? -1d : 0, PlatformThread.sync(model.getBusy()))); + + var name = Bindings.createStringBinding( + () -> { + return model.getStore().getValue() != null + ? DataStorage.get() + .getEntryByStore(model.getStore().getValue()) + .orElseThrow() + .getName() + : null; + }, + model.getStore()); + var image = Bindings.createStringBinding( + () -> { + return model.getStore().getValue() != null + ? DataStorage.get() + .getEntryByStore(model.getStore().getValue()) + .orElseThrow() + .getProvider() + .getDisplayIconFileName() + : null; + }, + model.getStore()); + var logo = new PrettyImageComp(image, 20, 20).createRegion(); + + var label = new Label(); + label.textProperty().bind(name); + label.addEventHandler(DragEvent.DRAG_ENTERED, new EventHandler() { + @Override + public void handle(DragEvent mouseEvent) { + tabs.getSelectionModel().select(tab); + } + }); + + label.graphicProperty() + .bind(Bindings.createObjectBinding( + () -> { + return model.getBusy().get() ? ring : logo; + }, + PlatformThread.sync(model.getBusy()))); + + tab.setGraphic(label); + tab.setContent(new OpenFileSystemComp(model).createSimple()); + return tab; + } +} diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserModel.java b/app/src/main/java/io/xpipe/app/browser/BrowserModel.java new file mode 100644 index 000000000..852791b7e --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/BrowserModel.java @@ -0,0 +1,56 @@ +package io.xpipe.app.browser; + +import io.xpipe.app.util.ThreadHelper; +import io.xpipe.core.store.DataStore; +import io.xpipe.core.store.FileSystem; +import io.xpipe.core.store.ShellStore; +import javafx.beans.property.Property; +import javafx.beans.property.SimpleObjectProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import lombok.Getter; + +@Getter +public class BrowserModel { + + public static final BrowserModel DEFAULT = new BrowserModel(); + + private final ObservableList openFileSystems = FXCollections.observableArrayList(); + private final Property selected = new SimpleObjectProperty<>(); + + public OpenFileSystemModel getOpenModelFor(DataStore store) { + return openFileSystems.stream() + .filter(model -> model.getStore().equals(store)) + .findFirst() + .orElseThrow(); + } + + public OpenFileSystemModel getOpenModelFor(FileSystem fileSystem) { + return openFileSystems.stream() + .filter(model -> model.getFileSystem().equals(fileSystem)) + .findFirst() + .orElseThrow(); + } + + public void closeFileSystem(OpenFileSystemModel open) { + ThreadHelper.runAsync(() -> { + open.closeSync(); + openFileSystems.remove(open); + }); + } + + public void openFileSystem(ShellStore store) { + var found = openFileSystems.stream() + .filter(fileSystemModel -> fileSystemModel.getStore().equals(store)) + .findFirst(); + if (found.isPresent()) { + selected.setValue(found.get()); + return; + } + + var model = new OpenFileSystemModel(); + openFileSystems.add(model); + selected.setValue(model); + model.switchAsync(store); + } +} diff --git a/app/src/main/java/io/xpipe/app/browser/FileContextMenu.java b/app/src/main/java/io/xpipe/app/browser/FileContextMenu.java new file mode 100644 index 000000000..e5707e1c6 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/FileContextMenu.java @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: MIT */ + +package io.xpipe.app.browser; + +import io.xpipe.app.util.ExternalEditor; +import javafx.beans.property.Property; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.MenuItem; +import javafx.scene.control.SeparatorMenuItem; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyCodeCombination; + +final class FileContextMenu extends ContextMenu { + + private final OpenFileSystemModel model; + private final String path; + private final boolean directory; + private final Property editing; + + public FileContextMenu(OpenFileSystemModel model, String path, boolean directory, Property editing) { + super(); + this.model = model; + this.path = path; + this.directory = directory; + this.editing = editing; + createMenu(); + } + + private void createMenu() { + var cut = new MenuItem("Delete"); + cut.setOnAction(event -> { + event.consume(); + model.deleteAsync(path); + }); + cut.setAccelerator(new KeyCodeCombination(KeyCode.DELETE)); + + var rename = new MenuItem("Rename"); + rename.setOnAction(event -> { + event.consume(); + editing.setValue(path); + }); + rename.setAccelerator(new KeyCodeCombination(KeyCode.F2)); + + getItems().setAll( + new SeparatorMenuItem(), + cut, + rename + ); + + if (directory) { + var terminal = new MenuItem("Terminal"); + terminal.setOnAction(event -> { + event.consume(); + model.openTerminalAsync(path); + }); + getItems().add(0, terminal); + } else { + var open = new MenuItem("Edit"); + open.setOnAction(event -> { + event.consume(); + ExternalEditor.get().openInEditor(model.getFileSystem(), path); + }); + getItems().add(0, open); + } + } +} diff --git a/app/src/main/java/io/xpipe/app/browser/FileListComp.java b/app/src/main/java/io/xpipe/app/browser/FileListComp.java new file mode 100644 index 000000000..558e54653 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/FileListComp.java @@ -0,0 +1,346 @@ +/* SPDX-License-Identifier: MIT */ + +package io.xpipe.app.browser; + +import atlantafx.base.theme.Styles; +import atlantafx.base.theme.Tweaks; +import io.xpipe.app.comp.base.LazyTextFieldComp; +import io.xpipe.app.core.AppResources; +import io.xpipe.app.fxcomps.impl.PrettyImageComp; +import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.util.Containers; +import io.xpipe.app.util.HumanReadableFormat; +import io.xpipe.core.impl.FileNames; +import io.xpipe.core.store.FileSystem; +import javafx.beans.property.*; +import javafx.beans.value.ChangeListener; +import javafx.css.PseudoClass; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.control.*; +import javafx.scene.image.Image; +import javafx.scene.input.*; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.StackPane; + +import java.io.File; +import java.time.Instant; +import java.time.ZoneId; +import java.util.Comparator; +import java.util.stream.Stream; + +import static io.xpipe.app.util.HumanReadableFormat.byteCount; +import static javafx.scene.control.TableColumn.SortType.ASCENDING; + +final class FileListComp extends AnchorPane { + + private static final PseudoClass HIDDEN = PseudoClass.getPseudoClass("hidden"); + private static final PseudoClass FOLDER = PseudoClass.getPseudoClass("folder"); + private static final PseudoClass DRAG = PseudoClass.getPseudoClass("drag"); + private static final String UNKNOWN = "unknown"; + + private final FileListModel fileList; + + public FileListComp(FileListModel fileList) { + this.fileList = fileList; + TableView table = createTable(); + fileList.getComparatorProperty().bind(table.comparatorProperty()); + + getChildren().setAll(table); + getStyleClass().addAll("table-directory-view"); + Containers.setAnchors(table, Insets.EMPTY); + } + + @SuppressWarnings("unchecked") + private TableView createTable() { + var editing = new SimpleObjectProperty(); + var filenameCol = new TableColumn("Name"); + filenameCol.setCellValueFactory(param -> new SimpleStringProperty( + param.getValue() != null + ? FileNames.getFileName(param.getValue().getPath()) + : null)); + filenameCol.setComparator(Comparator.comparing(String::toLowerCase)); + filenameCol.setSortType(ASCENDING); + filenameCol.setCellFactory(col -> new FilenameCell(editing)); + + var sizeCol = new TableColumn("Size"); + sizeCol.setCellValueFactory( + param -> new SimpleLongProperty(param.getValue().getSize())); + sizeCol.setCellFactory(col -> new FileSizeCell()); + + var mtimeCol = new TableColumn("Modified"); + mtimeCol.setCellValueFactory( + param -> new SimpleObjectProperty<>(param.getValue().getDate())); + mtimeCol.setCellFactory(col -> new FileTimeCell()); + mtimeCol.getStyleClass().add(Tweaks.ALIGN_RIGHT); + + // ~ + + var table = new TableView(); + table.getStyleClass().add(Styles.STRIPED); + table.getColumns().setAll(filenameCol, sizeCol, mtimeCol); + table.getSortOrder().add(filenameCol); + table.setSortPolicy(param -> true); + table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); + table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + filenameCol.minWidthProperty().bind(table.widthProperty().multiply(0.5)); + + table.setOnKeyPressed(event -> { + if (event.isControlDown() + && event.getCode().equals(KeyCode.C) + && table.getSelectionModel().getSelectedItems().size() > 0) { + BrowserClipboard.startCopy(table.getSelectionModel().getSelectedItems()); + event.consume(); + } + + if (event.isControlDown() && event.getCode().equals(KeyCode.V)) { + var clipboard = BrowserClipboard.retrieveCopy(); + if (clipboard != null) { + var files = clipboard.getEntries(); + var target = fileList.getModel().getCurrentDirectory(); + fileList.getModel().dropFilesIntoAsync(target, files, true); + event.consume(); + } + } + }); + + table.setRowFactory(param -> { + TableRow row = new TableRow<>(); + + row.addEventHandler(MouseEvent.MOUSE_CLICKED, t -> { + t.consume(); + if (row.isEmpty()) { + return; + } + + var cm = new FileContextMenu( + fileList.getModel(), + row.getItem().getPath(), + row.getItem().isDirectory(), + editing); + if (t.getButton() == MouseButton.SECONDARY) { + cm.show(row, t.getScreenX(), t.getScreenY()); + } + }); + + row.setOnMouseClicked(e -> { + if (e.getClickCount() == 2 && !row.isEmpty()) { + fileList.onClick(row.getItem()); + } + }); + + row.setOnDragOver(event -> { + if (row.equals(event.getGestureSource())) { + return; + } + + row.pseudoClassStateChanged(DRAG, true); + event.acceptTransferModes(TransferMode.ANY); + event.consume(); + }); + + row.setOnDragDetected(event -> { + if (row.isEmpty()) { + return; + } + + var url = AppResources.getResourceURL(AppResources.XPIPE_MODULE, "img/file_drag_icon.png") + .orElseThrow(); + var image = new Image(url.toString(), 80, 80, true, false); + + var selected = table.getSelectionModel().getSelectedItems(); + Dragboard db = row.startDragAndDrop(TransferMode.COPY); + db.setContent(BrowserClipboard.startDrag(selected)); + db.setDragView(image, 30, 60); + event.setDragDetect(true); + event.consume(); + }); + + row.setOnDragExited(event -> { + row.pseudoClassStateChanged(DRAG, false); + event.consume(); + + if (event.getGestureSource() == null && event.getDragboard().hasFiles()) { + row.pseudoClassStateChanged(DRAG, false); + event.consume(); + } + + // if (event.getGestureSource() != null) { + // try { + // var f = Files.createTempFile(null, null); + // var cc = new ClipboardContent(); + // cc.putFiles(List.of(f.toFile())); + // Dragboard db = row.startDragAndDrop(TransferMode.COPY); + // db.setContent(cc); + // } catch (IOException e) { + // throw new RuntimeException(e); + // } + // } + }); + // + // row.setEventDispatcher((event, chain) -> { + // if (event.getEventType().getName().equals("MOUSE_DRAGGED")) { + // MouseEvent drag = (MouseEvent) event; + // + // if (drag.isDragDetect()) { + // return chain.dispatchEvent(event); + // } + // + // Rectangle area = new Rectangle( + // App.getApp().getStage().getX(), + // App.getApp().getStage().getY(), + // App.getApp().getStage().getWidth(), + // App.getApp().getStage().getHeight() + // ); + // if (!area.intersects(drag.getScreenX(), drag.getScreenY(), 20, 20)) { + // System.out.println("->Drag down"); + // drag.setDragDetect(true); + // } + // } + // + // return chain.dispatchEvent(event); + // }); + + row.setOnDragDropped(event -> { + // Accept drops from outside the app window + if (event.getGestureSource() == null && event.getDragboard().hasFiles()) { + event.setDropCompleted(true); + Dragboard db = event.getDragboard(); + var list = db.getFiles().stream().map(File::toPath).toList(); + var target = row.getItem() != null + ? row.getItem() + : fileList.getModel().getCurrentDirectory(); + fileList.getModel().dropLocalFilesIntoAsync(target, list); + } + + // Accept drops from inside the app window + if (event.getGestureSource() != null) { + event.setDropCompleted(true); + var files = BrowserClipboard.retrieveDrag(event.getDragboard()).getEntries(); + var target = row.getItem() != null + ? row.getItem() + : fileList.getModel().getCurrentDirectory(); + fileList.getModel().dropFilesIntoAsync(target, files, false); + } + + event.consume(); + }); + + return row; + }); + BindingsHelper.bindContent(table.getItems(), fileList.getShown()); + + return table; + } + + /////////////////////////////////////////////////////////////////////////// + + private class FilenameCell extends TableCell { + + private final StringProperty img = new SimpleStringProperty(); + private final StringProperty text = new SimpleStringProperty(); + private final Node imageView = new PrettyImageComp(img, 24, 24).createRegion(); + private final StackPane textField = + new LazyTextFieldComp(text).createStructure().get(); + private final ChangeListener listener; + + public FilenameCell(Property editing) { + editing.addListener((observable, oldValue, newValue) -> { + if (getTableRow().getItem() != null + && getTableRow().getItem().getPath().equals(newValue)) { + textField.requestFocus(); + } + }); + + listener = (observable, oldValue, newValue) -> { + fileList.rename(oldValue, newValue); + textField.getScene().getRoot().requestFocus(); + editing.setValue(null); + updateItem(getItem(), isEmpty()); + }; + } + + @Override + protected void updateItem(String fullPath, boolean empty) { + super.updateItem(fullPath, empty); + + text.removeListener(listener); + text.setValue(fullPath); + + if (empty || getTableRow() == null || getTableRow().getItem() == null) { + img.set(null); + setGraphic(null); + } else { + var isDirectory = getTableRow().getItem().isDirectory(); + var box = new HBox(imageView, textField); + box.setSpacing(10); + box.setAlignment(Pos.CENTER_LEFT); + HBox.setHgrow(textField, Priority.ALWAYS); + setGraphic(box); + + if (!isDirectory) { + img.set("file_drag_icon.png"); + } else { + img.set("folder_closed.svg"); + } + + pseudoClassStateChanged(FOLDER, isDirectory); + + var fileName = FileNames.getFileName(fullPath); + var hidden = getTableRow().getItem().isHidden() || fileName.startsWith("."); + getTableRow().pseudoClassStateChanged(HIDDEN, hidden); + text.set(fileName); + + text.addListener(listener); + } + } + } + + private class FileSizeCell extends TableCell { + + @Override + protected void updateItem(Number fileSize, boolean empty) { + super.updateItem(fileSize, empty); + if (empty || getTableRow() == null || getTableRow().getItem() == null) { + setText(null); + } else { + var path = getTableRow().getItem(); + if (path.isDirectory()) { + if (true) { + setText(""); + return; + } + + try (Stream stream = + path.getFileSystem().listFiles(path.getPath())) { + setText(stream.count() + " items"); + } catch (Exception e) { + setText(UNKNOWN); + } + } else { + setText(byteCount(fileSize.longValue())); + } + } + } + } + + private static class FileTimeCell extends TableCell { + + @Override + protected void updateItem(Instant fileTime, boolean empty) { + super.updateItem(fileTime, empty); + if (empty) { + setText(null); + } else { + setText( + fileTime != null + ? HumanReadableFormat.date( + fileTime.atZone(ZoneId.systemDefault()).toLocalDateTime()) + : UNKNOWN); + } + } + } +} diff --git a/app/src/main/java/io/xpipe/app/browser/FileListModel.java b/app/src/main/java/io/xpipe/app/browser/FileListModel.java new file mode 100644 index 000000000..40d130979 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/FileListModel.java @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: MIT */ + +package io.xpipe.app.browser; + +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.util.ExternalEditor; +import io.xpipe.core.impl.FileNames; +import io.xpipe.core.store.FileSystem; +import javafx.beans.binding.Bindings; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.Property; +import javafx.beans.property.SimpleObjectProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.collections.transformation.FilteredList; +import javafx.collections.transformation.SortedList; +import lombok.Getter; + +import java.util.Comparator; +import java.util.function.Predicate; + +@Getter +final class FileListModel { + + static final Comparator FILE_TYPE_COMPARATOR = + Comparator.comparing(path -> !path.isDirectory()); + static final Predicate PREDICATE_ANY = path -> true; + static final Predicate PREDICATE_NOT_HIDDEN = path -> true; + + private final OpenFileSystemModel model; + private final Property> comparatorProperty = + new SimpleObjectProperty<>(FILE_TYPE_COMPARATOR); + private final ObservableList all = FXCollections.observableArrayList(); + private final ObservableList shown; + private final ObjectProperty> predicateProperty = + new SimpleObjectProperty<>(path -> true); + + public FileListModel(OpenFileSystemModel model) { + this.model = model; + var filteredList = new FilteredList<>(all); + filteredList.predicateProperty().bind(predicateProperty); + + var sortedList = new SortedList<>(filteredList); + sortedList + .comparatorProperty() + .bind(Bindings.createObjectBinding( + () -> { + Comparator tableComparator = comparatorProperty.getValue(); + return tableComparator != null + ? FILE_TYPE_COMPARATOR.thenComparing(tableComparator) + : FILE_TYPE_COMPARATOR; + }, + comparatorProperty)); + shown = sortedList; + } + + public boolean rename(String filename, String newName) { + var fullPath = FileNames.join(model.getCurrentPath().get(), filename); + var newFullPath = FileNames.join(model.getCurrentPath().get(), newName); + try { + model.getFileSystem().move(fullPath, newFullPath); + model.refresh(); + return true; + } catch (Exception e) { + ErrorEvent.fromThrowable(e).handle(); + return false; + } + } + + public void onClick(FileSystem.FileEntry entry) { + if (entry.isDirectory()) { + model.navigate(entry.getPath(), true); + } else { + ExternalEditor.get().openInEditor(entry.getFileSystem(), entry.getPath()); + } + } + + public ObjectProperty> predicateProperty() { + return predicateProperty; + } +} diff --git a/app/src/main/java/io/xpipe/app/browser/FileSystemHelper.java b/app/src/main/java/io/xpipe/app/browser/FileSystemHelper.java new file mode 100644 index 000000000..f203fcde0 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/FileSystemHelper.java @@ -0,0 +1,135 @@ +package io.xpipe.app.browser; + +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.core.impl.FileNames; +import io.xpipe.core.store.FileSystem; +import io.xpipe.core.store.ShellStore; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.List; + +public class FileSystemHelper { + + private static OpenFileSystemModel local; + + public static OpenFileSystemModel getLocal() throws Exception { + if (local == null) { + var model = new OpenFileSystemModel(); + model.switchSync(ShellStore.local()); + local = model; + } + + return local; + } + + public static FileSystem.FileEntry getLocal(Path file) throws Exception { + return new FileSystem.FileEntry( + getLocal().getFileSystem(), + file.toString(), + Files.getLastModifiedTime(file).toInstant(), + Files.isDirectory(file), + Files.isHidden(file), + Files.size(file)); + } + + public static void dropLocalFilesInto(FileSystem.FileEntry entry, List files) { + try { + var entries = files.stream() + .map(path -> { + try { + return getLocal(path); + } catch (Exception e) { + throw new RuntimeException(e); + } + }) + .toList(); + dropFilesInto(entry, entries, false); + } catch (Exception ex) { + ErrorEvent.fromThrowable(ex).handle(); + } + } + + public static void dropFilesInto( + FileSystem.FileEntry target, List files, boolean explicitCopy) { + if (files.size() == 0) { + return; + } + + for (var file : files) { + if (file.getFileSystem().equals(target.getFileSystem())) { + dropFileAcrossSameFileSystem(target, file, explicitCopy); + } else { + dropFileAcrossFileSystems(target, file); + } + } + } + + private static void dropFileAcrossSameFileSystem( + FileSystem.FileEntry target, FileSystem.FileEntry file, boolean explicitCopy) { + // Prevent dropping directory into itself + if (FileNames.startsWith(file.getPath(), target.getPath())) { + return; + } + + try { + var sourceFile = file.getPath(); + var targetFile = FileNames.join(target.getPath(), FileNames.getFileName(sourceFile)); + if (explicitCopy) { + target.getFileSystem().copy(sourceFile, targetFile); + } else { + target.getFileSystem().move(sourceFile, targetFile); + } + } catch (Exception ex) { + ErrorEvent.fromThrowable(ex).handle(); + } + } + + private static void dropFileAcrossFileSystems(FileSystem.FileEntry target, FileSystem.FileEntry file) { + var flatFiles = new HashMap(); + + // Prevent dropping directory into itself + if (file.getFileSystem().equals(target.getFileSystem()) + && FileNames.startsWith(file.getPath(), target.getPath())) { + return; + } + + try { + if (file.isDirectory()) { + flatFiles.put(file, FileNames.getFileName(file.getPath())); + try (var stream = file.getFileSystem().listFilesRecursively(file.getPath())) { + stream.forEach(fileEntry -> { + flatFiles.put(fileEntry, FileNames.relativize(file.getPath(), fileEntry.getPath())); + }); + } + } else { + flatFiles.put(file, FileNames.getFileName(file.getPath())); + } + } catch (Exception ex) { + ErrorEvent.fromThrowable(ex).handle(); + return; + } + + for (var e : flatFiles.entrySet()) { + var sourceFile = e.getKey(); + var targetFile = FileNames.join(target.getPath(), e.getValue()); + try { + if (sourceFile.getFileSystem().equals(target.getFileSystem())) { + throw new IllegalStateException(); + } + + if (sourceFile.isDirectory()) { + target.getFileSystem().mkdirs(targetFile); + } else { + try (var in = sourceFile.getFileSystem().openInput(sourceFile.getPath()); + var out = target.getFileSystem().openOutput(targetFile)) { + in.transferTo(out); + } + } + } catch (Exception ex) { + ErrorEvent.fromThrowable(ex).handle(); + } + } + } +} diff --git a/app/src/main/java/io/xpipe/app/browser/NavigationHistory.java b/app/src/main/java/io/xpipe/app/browser/NavigationHistory.java new file mode 100644 index 000000000..d05df91d2 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/NavigationHistory.java @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: MIT */ + +package io.xpipe.app.browser; + +import javafx.beans.binding.Bindings; +import javafx.beans.binding.BooleanBinding; +import javafx.beans.property.IntegerProperty; +import javafx.beans.property.SimpleIntegerProperty; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +final class NavigationHistory { + + private final IntegerProperty cursor = new SimpleIntegerProperty(0); + private final List history = new ArrayList<>(); + private final BooleanBinding canGoBack = Bindings.createBooleanBinding( + () -> cursor.get() > 0 && history.size() > 1, cursor); + private final BooleanBinding canGoForth = Bindings.createBooleanBinding( + () -> cursor.get() < history.size() - 1, cursor); + + public String getCurrent() { + return history.size() > 0 ? history.get(cursor.get()) : null; + } + + public void append(String s) { + if (s == null) { + return; + } + var lastString = history.size() > 0 ? history.get(history.size() - 1) : null; + if (!Objects.equals(lastString, s)) { + history.add(s); + } + cursor.set(history.size() - 1); + } + + public Optional back() { + if (!canGoBack.get()) { + return Optional.empty(); + } + cursor.set(cursor.get() - 1); + return Optional.of(history.get(cursor.get())); + } + + public Optional forth() { + if (!canGoForth.get()) { + return Optional.empty(); + } + cursor.set(cursor.get() + 1); + return Optional.of(history.get(cursor.get())); + } + + public BooleanBinding canGoBackProperty() { + return canGoBack; + } + + public BooleanBinding canGoForthProperty() { + return canGoForth; + } +} diff --git a/app/src/main/java/io/xpipe/app/browser/OpenFileSystemComp.java b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemComp.java new file mode 100644 index 000000000..011a169aa --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemComp.java @@ -0,0 +1,124 @@ +package io.xpipe.app.browser; + +import atlantafx.base.controls.Spacer; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.TextFieldComp; +import io.xpipe.core.impl.FileNames; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.*; +import javafx.scene.layout.*; +import org.kordamp.ikonli.feather.Feather; +import org.kordamp.ikonli.javafx.FontIcon; + +import static io.xpipe.app.browser.FileListModel.PREDICATE_NOT_HIDDEN; +import static io.xpipe.app.util.Controls.iconButton; + +public class OpenFileSystemComp extends SimpleComp { + + private final OpenFileSystemModel model; + + public OpenFileSystemComp(OpenFileSystemModel model) { + this.model = model; + } + + @Override + protected Region createSimple() { + var creatingProperty = new SimpleBooleanProperty(); + var backBtn = iconButton(Feather.ARROW_LEFT, false); + backBtn.setOnAction(e -> model.back()); + backBtn.disableProperty().bind(model.getHistory().canGoBackProperty().not()); + + var forthBtn = iconButton(Feather.ARROW_RIGHT, false); + forthBtn.setOnAction(e -> model.forth()); + forthBtn.disableProperty().bind(model.getHistory().canGoForthProperty().not()); + + var path = new SimpleStringProperty(model.getCurrentPath().get()); + var pathBar = new TextFieldComp(path, true).createRegion(); + path.addListener((observable, oldValue, newValue) -> { + model.cd(newValue); + }); + model.getCurrentPath().addListener((observable, oldValue, newValue) -> { + path.set(newValue); + }); + HBox.setHgrow(pathBar, Priority.ALWAYS); + + var refreshBtn = new Button(null, new FontIcon("mdmz-refresh")); + refreshBtn.setOnAction(e -> model.refresh()); + + var terminalBtn = new Button(null, new FontIcon("mdi2c-code-greater-than")); + terminalBtn.setOnAction(e -> model.openTerminalAsync(model.getCurrentPath().get())); + + var addBtn = new Button(null, new FontIcon("mdmz-plus")); + addBtn.setOnAction(e -> { + creatingProperty.set(true); + }); + + var topBar = new ToolBar(); + topBar.getItems().setAll( + backBtn, + forthBtn, + new Spacer(10), + pathBar, + refreshBtn, + terminalBtn, + addBtn + ); + + // ~ + + FileListComp directoryView = new FileListComp(model.getFileList()); + + var root = new VBox(topBar, directoryView); + VBox.setVgrow(directoryView, Priority.ALWAYS); + root.setPadding(Insets.EMPTY); + model.getFileList().predicateProperty().set(PREDICATE_NOT_HIDDEN); + + var pane = new StackPane(); + pane.getChildren().add(root); + + var creation = createCreationWindow(creatingProperty); + var creationPain = new StackPane(creation); + creationPain.setAlignment(Pos.CENTER); + creationPain.setOnMouseClicked(event -> { + creatingProperty.set(false); + }); + pane.getChildren().add(creationPain); + creationPain.visibleProperty().bind(creatingProperty); + creationPain.managedProperty().bind(creatingProperty); + + return pane; + } + + private Region createCreationWindow(BooleanProperty creating) { + var creationName = new TextField(); + creating.addListener((observable, oldValue, newValue) -> { + if (!newValue) { + creationName.setText(""); + } + }); + var createFileButton = new Button("Create file"); + createFileButton.setOnAction(event -> { + model.createFileAsync(FileNames.join(model.getCurrentPath().get(), creationName.getText())); + creating.set(false); + }); + var createDirectoryButton = new Button("Create directory"); + createDirectoryButton.setOnAction(event -> { + model.createDirectoryAsync(FileNames.join(model.getCurrentPath().get(), creationName.getText())); + creating.set(false); + }); + var buttonBar = new ButtonBar(); + buttonBar.getButtons().addAll(createFileButton, createDirectoryButton); + var creationContent = new VBox(creationName, buttonBar); + creationContent.setSpacing(15); + var creation = new TitledPane("New", creationContent); + creation.setMaxWidth(400); + creation.setCollapsible(false); + creationContent.setPadding(new Insets(15)); + creation.getStyleClass().add("elevated-3"); + return creation; + } +} diff --git a/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java new file mode 100644 index 000000000..19ebe71d8 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java @@ -0,0 +1,224 @@ +/* SPDX-License-Identifier: MIT */ + +package io.xpipe.app.browser; + +import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.util.BusyProperty; +import io.xpipe.app.util.TerminalHelper; +import io.xpipe.app.util.ThreadHelper; +import io.xpipe.core.store.ConnectionFileSystem; +import io.xpipe.core.store.FileSystem; +import io.xpipe.core.store.FileSystemStore; +import io.xpipe.core.store.ShellStore; +import javafx.beans.property.*; +import lombok.Getter; + +import java.io.IOException; +import java.nio.file.Path; +import java.time.Instant; +import java.util.List; +import java.util.Objects; + +@Getter +final class OpenFileSystemModel { + + private Property store = new SimpleObjectProperty<>(); + private FileSystem fileSystem; + private List roots; + private final FileListModel fileList; + private final ReadOnlyObjectWrapper currentPath = new ReadOnlyObjectWrapper<>(); + private final NavigationHistory history = new NavigationHistory(); + private final BooleanProperty busy = new SimpleBooleanProperty(); + + public OpenFileSystemModel() { + fileList = new FileListModel(this); + } + + public void refresh() { + BusyProperty.execute(busy, () -> { + cdSync(currentPath.get()); + }); + } + + private void refreshInternal() { + cdSync(currentPath.get()); + } + + public FileSystem.FileEntry getCurrentDirectory() { + return new FileSystem.FileEntry(fileSystem, currentPath.get(), Instant.now(), true, false, 0); + } + + public void cd(String path) { + ThreadHelper.runFailableAsync(() -> { + cdSync(path); + }); + } + + private boolean cdSync(String path) { + try (var ignored = new BusyProperty(busy)) { + if (!navigateTo(path)) { + return false; + } + + currentPath.set(path); + if (!Objects.equals(history.getCurrent(), path)) { + history.append(path); + } + return true; + } + } + + private boolean navigateTo(String dir) { + try { + List newList; + if (dir != null) { + newList = getFileSystem().listFiles(dir).toList(); + } else { + newList = getFileSystem().listRoots().stream() + .map(s -> new FileSystem.FileEntry(getFileSystem(), s, Instant.now(), true, false, 0)) + .toList(); + } + BindingsHelper.setContent(fileList.getAll(), newList); + return true; + } catch (Exception e) { + ErrorEvent.fromThrowable(e).handle(); + return false; + } + } + + public void dropLocalFilesIntoAsync(FileSystem.FileEntry entry, List files) { + ThreadHelper.runFailableAsync(() -> { + BusyProperty.execute(busy, () -> { + FileSystemHelper.dropLocalFilesInto(entry, files); + refreshInternal(); + }); + }); + } + + public void dropFilesIntoAsync(FileSystem.FileEntry target, List files, boolean explicitCopy) { + ThreadHelper.runFailableAsync(() -> { + BusyProperty.execute(busy, () -> { + FileSystemHelper.dropFilesInto(target, files, explicitCopy); + refreshInternal(); + }); + }); + } + + public void createDirectoryAsync(String path) { + if (path.isBlank()) { + return; + } + + ThreadHelper.runFailableAsync(() -> { + BusyProperty.execute(busy, () -> { + fileSystem.mkdirs(path); + refreshInternal(); + }); + }); + } + + public void createFileAsync(String path) { + if (path.isBlank()) { + return; + } + + ThreadHelper.runFailableAsync(() -> { + BusyProperty.execute(busy, () -> { + fileSystem.touch(path); + refreshInternal(); + }); + }); + } + + public void deleteAsync(String path) { + ThreadHelper.runFailableAsync(() -> { + BusyProperty.execute(busy, () -> { + fileSystem.delete(path); + refreshInternal(); + }); + }); + } + + void closeSync() { + if (fileSystem == null) { + return; + } + + try { + fileSystem.close(); + } catch (IOException e) { + ErrorEvent.fromThrowable(e).handle(); + } + fileSystem = null; + store = null; + } + + public void switchSync(FileSystemStore fileSystem) throws Exception { + BusyProperty.execute(busy, () -> { + closeSync(); + this.store.setValue(fileSystem); + var fs = fileSystem.createFileSystem(); + fs.open(); + this.fileSystem = fs; + + var current = fs instanceof ConnectionFileSystem connectionFileSystem + ? connectionFileSystem + .getShellProcessControl() + .executeStringSimpleCommand(connectionFileSystem + .getShellProcessControl() + .getShellType() + .getPrintWorkingDirectoryCommand()) + : null; + cdSync(current); + }); + } + + public void switchAsync(FileSystemStore fileSystem) { + ThreadHelper.runFailableAsync(() -> { + switchSync(fileSystem); + }); + } + + public void openTerminalAsync(String directory) { + ThreadHelper.runFailableAsync(() -> { + BusyProperty.execute(busy, () -> { + if (store.getValue() instanceof ShellStore s) { + var connection = ((ConnectionFileSystem) fileSystem).getShellProcessControl(); + var command = s.create() + .initWith(List.of(connection.getShellType().getCdCommand(directory))) + .prepareTerminalOpen(); + TerminalHelper.open("", command); + } + }); + }); + } + + /////////////////////////////////////////////////////////////////////////// + // Properties // + /////////////////////////////////////////////////////////////////////////// + + public ReadOnlyObjectProperty currentPathProperty() { + return currentPath.getReadOnlyProperty(); + } + + public NavigationHistory getHistory() { + return history; + } + + /////////////////////////////////////////////////////////////////////////// + // Commands // + /////////////////////////////////////////////////////////////////////////// + + public void back() { + history.back().ifPresent(currentPath::set); + } + + public void forth() { + history.forth().ifPresent(currentPath::set); + } + + public void navigate(String path, boolean saveInHistory) { + currentPath.set(path); + } +} diff --git a/app/src/main/java/io/xpipe/app/browser/Utils.java b/app/src/main/java/io/xpipe/app/browser/Utils.java new file mode 100644 index 000000000..7463b6af6 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/browser/Utils.java @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: MIT */ + +package io.xpipe.app.browser; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; +import java.nio.file.attribute.FileTime; + +final class Utils { + + private Utils() { + // Default constructor + } + + public static long fileSize(Path path) { + if (path == null) { + return 0; + } + try { + return Files.size(path); + } catch (IOException e) { + return 0; + } + } + + public static boolean isFileHidden(Path path) { + if (path == null) { + return false; + } + try { + return Files.isHidden(path); + } catch (IOException e) { + return false; + } + } + + public static FileTime fileMTime(Path path, LinkOption... options) { + if (path == null) { + return null; + } + try { + return Files.getLastModifiedTime(path, options); + } catch (IOException e) { + return null; + } + } + + public static String getMimeType(Path path) { + try { + return Files.probeContentType(path); + } catch (IOException e) { + return null; + } + } +} 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 8ef0948e8..4bb88b1c1 100644 --- a/app/src/main/java/io/xpipe/app/comp/AppLayoutComp.java +++ b/app/src/main/java/io/xpipe/app/comp/AppLayoutComp.java @@ -1,24 +1,23 @@ package io.xpipe.app.comp; +import io.xpipe.app.browser.BrowserComp; +import io.xpipe.app.browser.BrowserModel; 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.AppActionLinkDetector; -import io.xpipe.app.core.AppCache; -import io.xpipe.app.core.AppFont; -import io.xpipe.app.core.AppProperties; +import io.xpipe.app.core.*; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import io.xpipe.app.prefs.AppPrefs; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; 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.BorderPane; +import lombok.SneakyThrows; import java.util.ArrayList; import java.util.List; @@ -40,21 +39,23 @@ public class AppLayoutComp extends Comp> { }); } + @SneakyThrows private List createEntryList() { var l = new ArrayList<>(List.of( - new SideMenuBarComp.Entry(I18n.observable("connections"), "mdi2c-connection", new StoreLayoutComp()), - new SideMenuBarComp.Entry(I18n.observable("data"), "mdsal-dvr", new SourceCollectionLayoutComp()), + new SideMenuBarComp.Entry(AppI18n.observable("connections"), "mdi2c-connection", new StoreLayoutComp()), + new SideMenuBarComp.Entry(AppI18n.observable("browser"), "mdi2f-file-cabinet", new BrowserComp(BrowserModel.DEFAULT)), + new SideMenuBarComp.Entry(AppI18n.observable("data"), "mdsal-dvr", new SourceCollectionLayoutComp()), new SideMenuBarComp.Entry( - I18n.observable("settings"), "mdsmz-miscellaneous_services", new PrefsComp(this)), - // new SideMenuBarComp.Entry(I18n.observable("help"), "mdi2b-book-open-variant", new + AppI18n.observable("settings"), "mdsmz-miscellaneous_services", new PrefsComp(this)), + // new SideMenuBarComp.Entry(AppI18n.observable("help"), "mdi2b-book-open-variant", new // StorageLayoutComp()), - // new SideMenuBarComp.Entry(I18n.observable("account"), "mdi2a-account", new StorageLayoutComp()), - new SideMenuBarComp.Entry(I18n.observable("about"), "mdi2p-package-variant", new AboutTabComp()))); + // new SideMenuBarComp.Entry(AppI18n.observable("account"), "mdi2a-account", new StorageLayoutComp()), + new SideMenuBarComp.Entry(AppI18n.observable("about"), "mdi2p-package-variant", new AboutTabComp()))); if (AppProperties.get().isDeveloperMode()) { - l.add(new SideMenuBarComp.Entry(I18n.observable("developer"), "mdi2b-book-open-variant", new + l.add(new SideMenuBarComp.Entry(AppI18n.observable("developer"), "mdi2b-book-open-variant", new DeveloperTabComp())); } - // l.add(new SideMenuBarComp.Entry(I18n.observable("abc"), "mdi2b-book-open-variant", Comp.of(() -> { + // l.add(new SideMenuBarComp.Entry(AppI18n.observable("abc"), "mdi2b-book-open-variant", Comp.of(() -> { // var fi = new FontIcon("mdsal-dvr"); // fi.setIconSize(30); // fi.setIconColor(Color.valueOf("#111C")); diff --git a/app/src/main/java/io/xpipe/app/comp/DeveloperTabComp.java b/app/src/main/java/io/xpipe/app/comp/DeveloperTabComp.java index 22758f22b..4b0786d01 100644 --- a/app/src/main/java/io/xpipe/app/comp/DeveloperTabComp.java +++ b/app/src/main/java/io/xpipe/app/comp/DeveloperTabComp.java @@ -1,10 +1,10 @@ package io.xpipe.app.comp; import io.xpipe.app.comp.base.ButtonComp; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.mode.OperationMode; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.issue.ErrorEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.Region; @@ -14,11 +14,11 @@ public class DeveloperTabComp extends SimpleComp { @Override protected Region createSimple() { - var button = new ButtonComp(I18n.observable("Throw exception"), null, () -> { + var button = new ButtonComp(AppI18n.observable("Throw exception"), null, () -> { throw new IllegalStateException(); }); - var button2 = new ButtonComp(I18n.observable("Throw exception with file"), null, () -> { + var button2 = new ButtonComp(AppI18n.observable("Throw exception with file"), null, () -> { try { throw new IllegalStateException(); } catch (Exception ex) { @@ -29,11 +29,11 @@ public class DeveloperTabComp extends SimpleComp { } }); - var button3 = new ButtonComp(I18n.observable("Exit"), null, () -> { + var button3 = new ButtonComp(AppI18n.observable("Exit"), null, () -> { System.exit(0); }); - var button4 = new ButtonComp(I18n.observable("Throw terminal exception"), null, () -> { + var button4 = new ButtonComp(AppI18n.observable("Throw terminal exception"), null, () -> { try { throw new IllegalStateException(); } catch (Exception ex) { @@ -41,7 +41,7 @@ public class DeveloperTabComp extends SimpleComp { } }); - var button5 = new ButtonComp(I18n.observable("Operation mode null"), null, OperationMode::close); + var button5 = new ButtonComp(AppI18n.observable("Operation mode null"), null, OperationMode::close); var box = new HBox( button.createRegion(), diff --git a/app/src/main/java/io/xpipe/app/comp/PrefsComp.java b/app/src/main/java/io/xpipe/app/comp/PrefsComp.java index 6cf9f019e..841300c58 100644 --- a/app/src/main/java/io/xpipe/app/comp/PrefsComp.java +++ b/app/src/main/java/io/xpipe/app/comp/PrefsComp.java @@ -2,10 +2,10 @@ package io.xpipe.app.comp; import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.ClearCacheAlert; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; import javafx.beans.binding.Bindings; import javafx.geometry.Pos; import javafx.scene.layout.AnchorPane; @@ -33,12 +33,12 @@ public class PrefsComp extends SimpleComp { MasterDetailPane p = (MasterDetailPane) pfx.getCenter(); p.dividerPositionProperty().setValue(0.27); - var cancel = new ButtonComp(I18n.observable("cancel"), null, () -> { + var cancel = new ButtonComp(AppI18n.observable("cancel"), null, () -> { AppPrefs.get().cancel(); layout.selectedProperty().setValue(layout.getEntries().get(0)); }) .createRegion(); - var apply = new ButtonComp(I18n.observable("apply"), null, () -> { + var apply = new ButtonComp(AppI18n.observable("apply"), null, () -> { AppPrefs.get().save(); layout.selectedProperty().setValue(layout.getEntries().get(0)); }) @@ -54,8 +54,8 @@ public class PrefsComp extends SimpleComp { AnchorPane.setBottomAnchor(rightButtons, 15.0); AnchorPane.setRightAnchor(rightButtons, 55.0); - var clearCaches = new ButtonComp(I18n.observable("clearCaches"), null, ClearCacheAlert::show).createRegion(); - // var reload = new ButtonComp(I18n.observable("reload"), null, () -> OperationMode.reload()).createRegion(); + var clearCaches = new ButtonComp(AppI18n.observable("clearCaches"), null, ClearCacheAlert::show).createRegion(); + // var reload = new ButtonComp(AppI18n.observable("reload"), null, () -> OperationMode.reload()).createRegion(); var leftButtons = new HBox(clearCaches); leftButtons.setAlignment(Pos.CENTER); leftButtons.prefWidthProperty().bind(((Region) p.getDetailNode()).widthProperty()); diff --git a/app/src/main/java/io/xpipe/app/comp/about/AboutTabComp.java b/app/src/main/java/io/xpipe/app/comp/about/AboutTabComp.java index ee78d2fc4..8b7cb8244 100644 --- a/app/src/main/java/io/xpipe/app/comp/about/AboutTabComp.java +++ b/app/src/main/java/io/xpipe/app/comp/about/AboutTabComp.java @@ -1,11 +1,11 @@ package io.xpipe.app.comp.about; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.impl.VerticalComp; +import io.xpipe.app.util.DynamicOptionsBuilder; import io.xpipe.app.util.Hyperlinks; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.impl.VerticalComp; -import io.xpipe.extension.util.DynamicOptionsBuilder; import javafx.scene.control.Hyperlink; import javafx.scene.control.Label; import javafx.scene.layout.BorderPane; @@ -36,16 +36,16 @@ public class AboutTabComp extends Comp> { private Comp createLinks() { return new DynamicOptionsBuilder(false) .addTitle("links") - .addComp(I18n.observable("website"), hyperlink(Hyperlinks.WEBSITE), null) - .addComp(I18n.observable("documentation"), hyperlink(Hyperlinks.DOCUMENTATION), null) - .addComp(I18n.observable("discord"), hyperlink(Hyperlinks.DISCORD), null) - .addComp(I18n.observable("slack"), hyperlink(Hyperlinks.SLACK), null) - .addComp(I18n.observable("github"), hyperlink(Hyperlinks.GITHUB), null) + .addComp(AppI18n.observable("website"), hyperlink(Hyperlinks.WEBSITE), null) + .addComp(AppI18n.observable("documentation"), hyperlink(Hyperlinks.DOCUMENTATION), null) + .addComp(AppI18n.observable("discord"), hyperlink(Hyperlinks.DISCORD), null) + .addComp(AppI18n.observable("slack"), hyperlink(Hyperlinks.SLACK), null) + .addComp(AppI18n.observable("github"), hyperlink(Hyperlinks.GITHUB), null) .buildComp(); } private Region createThirdPartyDeps() { - var label = new Label(I18n.get("openSourceNotices"), new FontIcon("mdi2o-open-source-initiative")); + var label = new Label(AppI18n.get("openSourceNotices"), new FontIcon("mdi2o-open-source-initiative")); label.getStyleClass().add("open-source-header"); var list = createDepsList(); var box = new VBox(label, list); diff --git a/app/src/main/java/io/xpipe/app/comp/about/BrowseDirectoryComp.java b/app/src/main/java/io/xpipe/app/comp/about/BrowseDirectoryComp.java index a340c9e7e..13299a3d9 100644 --- a/app/src/main/java/io/xpipe/app/comp/about/BrowseDirectoryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/about/BrowseDirectoryComp.java @@ -1,15 +1,15 @@ package io.xpipe.app.comp.about; import io.xpipe.app.comp.base.ButtonComp; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppLogs; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.UserReportComp; +import io.xpipe.app.util.DesktopHelper; +import io.xpipe.app.util.DynamicOptionsBuilder; import io.xpipe.app.util.ExternalEditor; import io.xpipe.core.util.XPipeInstallation; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.util.DesktopHelper; -import io.xpipe.extension.util.DynamicOptionsBuilder; import javafx.scene.layout.Region; public class BrowseDirectoryComp extends SimpleComp { @@ -19,7 +19,7 @@ public class BrowseDirectoryComp extends SimpleComp { return new DynamicOptionsBuilder(false) .addComp( "issueReporter", - new ButtonComp(I18n.observable("reportIssue"), () -> { + new ButtonComp(AppI18n.observable("reportIssue"), () -> { var event = ErrorEvent.fromMessage("User Report"); if (AppLogs.get().isWriteToFile()) { event.attachment(AppLogs.get().getSessionLogsDirectory()); @@ -29,7 +29,7 @@ public class BrowseDirectoryComp extends SimpleComp { null) .addComp( "logFile", - new ButtonComp(I18n.observable("openCurrentLogFile"), () -> { + new ButtonComp(AppI18n.observable("openCurrentLogFile"), () -> { ExternalEditor.get() .openInEditor(AppLogs.get() .getSessionLogsDirectory() @@ -39,14 +39,14 @@ public class BrowseDirectoryComp extends SimpleComp { null) .addComp( "logFiles", - new ButtonComp(I18n.observable("openLogsDirectory"), () -> { + new ButtonComp(AppI18n.observable("openLogsDirectory"), () -> { DesktopHelper.browsePath(AppLogs.get().getSessionLogsDirectory()); }), null) .addComp( "installationFiles", - new ButtonComp(I18n.observable("openInstallationDirectory"), () -> { - DesktopHelper.browsePath(XPipeInstallation.getLocalInstallationBasePath()); + new ButtonComp(AppI18n.observable("openInstallationDirectory"), () -> { + DesktopHelper.browsePath(XPipeInstallation.getCurrentInstallationBasePath()); }), null) .build(); diff --git a/app/src/main/java/io/xpipe/app/comp/about/PropertiesComp.java b/app/src/main/java/io/xpipe/app/comp/about/PropertiesComp.java index 55d68abec..242d61f91 100644 --- a/app/src/main/java/io/xpipe/app/comp/about/PropertiesComp.java +++ b/app/src/main/java/io/xpipe/app/comp/about/PropertiesComp.java @@ -2,12 +2,12 @@ package io.xpipe.app.comp.about; import io.xpipe.app.core.App; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppProperties; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.LabelComp; -import io.xpipe.extension.util.DynamicOptionsBuilder; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.LabelComp; +import io.xpipe.app.util.DynamicOptionsBuilder; import javafx.scene.control.Label; import javafx.scene.image.ImageView; import javafx.scene.layout.Region; @@ -20,7 +20,7 @@ public class PropertiesComp extends SimpleComp { var image = new ImageView(App.getApp().getIcon()); image.setPreserveRatio(true); image.setFitHeight(40); - var label = new Label(I18n.get("xPipeClient"), image); + var label = new Label(AppI18n.get("xPipeClient"), image); label.getStyleClass().add("header"); AppFont.setSize(label, 5); return label; @@ -29,16 +29,16 @@ public class PropertiesComp extends SimpleComp { var section = new DynamicOptionsBuilder(false) .addComp(title, null) .addComp( - I18n.observable("version"), + AppI18n.observable("version"), new LabelComp(AppProperties.get().getVersion() + " (x64)"), null) .addComp( - I18n.observable("build"), + AppI18n.observable("build"), new LabelComp(AppProperties.get().getBuild()), null) - .addComp(I18n.observable("runtimeVersion"), new LabelComp(System.getProperty("java.vm.version")), null) + .addComp(AppI18n.observable("runtimeVersion"), new LabelComp(System.getProperty("java.vm.version")), null) .addComp( - I18n.observable("virtualMachine"), + AppI18n.observable("virtualMachine"), new LabelComp(System.getProperty("java.vm.vendor") + " " + System.getProperty("java.vm.name")), null) .buildComp(); diff --git a/app/src/main/java/io/xpipe/app/comp/about/ThirdPartyDependencyListComp.java b/app/src/main/java/io/xpipe/app/comp/about/ThirdPartyDependencyListComp.java index 09fc90302..6ec225c83 100644 --- a/app/src/main/java/io/xpipe/app/comp/about/ThirdPartyDependencyListComp.java +++ b/app/src/main/java/io/xpipe/app/comp/about/ThirdPartyDependencyListComp.java @@ -1,10 +1,10 @@ package io.xpipe.app.comp.about; import io.xpipe.app.core.AppFont; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import io.xpipe.app.util.Hyperlinks; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.*; diff --git a/app/src/main/java/io/xpipe/app/comp/about/UpdateCheckComp.java b/app/src/main/java/io/xpipe/app/comp/about/UpdateCheckComp.java index 0840f3b29..52ed8c87a 100644 --- a/app/src/main/java/io/xpipe/app/comp/about/UpdateCheckComp.java +++ b/app/src/main/java/io/xpipe/app/comp/about/UpdateCheckComp.java @@ -1,12 +1,11 @@ package io.xpipe.app.comp.about; import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.update.AppUpdater; import io.xpipe.app.util.Hyperlinks; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.util.XPipeDistributionType; +import io.xpipe.app.util.XPipeDistributionType; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableBooleanValue; @@ -56,7 +55,7 @@ public class UpdateCheckComp extends SimpleComp { return PlatformThread.sync(Bindings.createStringBinding( () -> { if (AppUpdater.get().getDownloadedUpdate().getValue() != null) { - return I18n.get("updateRestart"); + return AppI18n.get("updateRestart"); } if (AppUpdater.get().getLastUpdateCheckResult().getValue() != null @@ -64,7 +63,7 @@ public class UpdateCheckComp extends SimpleComp { .getLastUpdateCheckResult() .getValue() .isUpdate()) { - return I18n.get( + return AppI18n.get( "updateAvailable", AppUpdater.get() .getLastUpdateCheckResult() @@ -78,7 +77,7 @@ public class UpdateCheckComp extends SimpleComp { .getLastUpdateCheckResult() .getValue() .getCheckTime()), - s -> I18n.get("lastChecked") + " " + s) + s -> AppI18n.get("lastChecked") + " " + s) .get(); } else { return null; @@ -97,15 +96,15 @@ public class UpdateCheckComp extends SimpleComp { .bind(Bindings.createStringBinding( () -> { if (updateReady.getValue()) { - return I18n.get("updateReady"); + return AppI18n.get("updateReady"); } if (updateAvailable.getValue()) { return XPipeDistributionType.get().supportsUpdate() - ? I18n.get("downloadUpdate") - : I18n.get("checkOutUpdate"); + ? AppI18n.get("downloadUpdate") + : AppI18n.get("checkOutUpdate"); } else { - return I18n.get("checkForUpdates"); + return AppI18n.get("checkForUpdates"); } }, updateAvailable, diff --git a/app/src/main/java/io/xpipe/app/comp/base/BackgroundImageComp.java b/app/src/main/java/io/xpipe/app/comp/base/BackgroundImageComp.java index 83d08c158..324aae28c 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/BackgroundImageComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/BackgroundImageComp.java @@ -1,8 +1,8 @@ package io.xpipe.app.comp.base; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import javafx.beans.value.ChangeListener; import javafx.geometry.Rectangle2D; import javafx.scene.image.Image; diff --git a/app/src/main/java/io/xpipe/app/comp/base/BigIconButton.java b/app/src/main/java/io/xpipe/app/comp/base/BigIconButton.java index 2a9646c0c..77a826e62 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/BigIconButton.java +++ b/app/src/main/java/io/xpipe/app/comp/base/BigIconButton.java @@ -1,7 +1,7 @@ package io.xpipe.app.comp.base; import com.jfoenix.controls.JFXButton; -import io.xpipe.extension.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.CompStructure; import javafx.beans.value.ObservableValue; import javafx.geometry.Pos; import javafx.scene.Node; diff --git a/app/src/main/java/io/xpipe/app/comp/base/ButtonComp.java b/app/src/main/java/io/xpipe/app/comp/base/ButtonComp.java index f97f6aea0..2eadf8819 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/ButtonComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/ButtonComp.java @@ -1,9 +1,9 @@ package io.xpipe.app.comp.base; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; diff --git a/app/src/main/java/io/xpipe/app/comp/base/CountComp.java b/app/src/main/java/io/xpipe/app/comp/base/CountComp.java index 52be636f2..542332476 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/CountComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/CountComp.java @@ -1,9 +1,9 @@ package io.xpipe.app.comp.base; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.beans.binding.Bindings; import javafx.collections.ObservableList; import javafx.geometry.Pos; diff --git a/app/src/main/java/io/xpipe/app/comp/base/FileDropOverlayComp.java b/app/src/main/java/io/xpipe/app/comp/base/FileDropOverlayComp.java index d225d7358..9bdac8cb0 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/FileDropOverlayComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/FileDropOverlayComp.java @@ -1,8 +1,8 @@ package io.xpipe.app.comp.base; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.issue.ErrorEvent; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.input.Dragboard; diff --git a/app/src/main/java/io/xpipe/app/comp/base/InstallExtensionComp.java b/app/src/main/java/io/xpipe/app/comp/base/InstallExtensionComp.java index 336c4992a..0ac58817c 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/InstallExtensionComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/InstallExtensionComp.java @@ -1,14 +1,14 @@ package io.xpipe.app.comp.base; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppResources; +import io.xpipe.app.ext.DownloadModuleInstall; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.LabelComp; +import io.xpipe.app.util.DynamicOptionsBuilder; import io.xpipe.app.util.Hyperlinks; -import io.xpipe.extension.DownloadModuleInstall; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.LabelComp; -import io.xpipe.extension.util.DynamicOptionsBuilder; import javafx.scene.control.Hyperlink; import javafx.scene.control.TextArea; import javafx.scene.layout.Priority; @@ -29,7 +29,7 @@ public class InstallExtensionComp extends SimpleComp { protected Region createSimple() { var builder = new DynamicOptionsBuilder(false); builder.addTitle("installRequired"); - var header = new LabelComp(I18n.observable("extensionInstallDescription")) + var header = new LabelComp(AppI18n.observable("extensionInstallDescription")) .apply(struc -> struc.get().setWrapText(true)); builder.addComp(header); @@ -45,7 +45,7 @@ public class InstallExtensionComp extends SimpleComp { if (install.getLicenseFile() != null) { builder.addTitle("license"); - var changeNotice = new LabelComp(I18n.observable("extensionInstallLicenseNote")) + var changeNotice = new LabelComp(AppI18n.observable("extensionInstallLicenseNote")) .apply(struc -> struc.get().setWrapText(true)); builder.addComp(changeNotice); diff --git a/app/src/main/java/io/xpipe/app/comp/base/IntegratedTextAreaComp.java b/app/src/main/java/io/xpipe/app/comp/base/IntegratedTextAreaComp.java index fcf9f130a..421150959 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/IntegratedTextAreaComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/IntegratedTextAreaComp.java @@ -1,10 +1,10 @@ package io.xpipe.app.comp.base; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.IconButtonComp; +import io.xpipe.app.fxcomps.impl.TextAreaComp; import io.xpipe.app.util.ExternalEditor; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.IconButtonComp; -import io.xpipe.extension.fxcomps.impl.TextAreaComp; import javafx.application.Platform; import javafx.beans.property.Property; import javafx.scene.layout.AnchorPane; diff --git a/app/src/main/java/io/xpipe/app/comp/base/LazyTextFieldComp.java b/app/src/main/java/io/xpipe/app/comp/base/LazyTextFieldComp.java index f918477f5..78a1a5aff 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/LazyTextFieldComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/LazyTextFieldComp.java @@ -1,10 +1,10 @@ package io.xpipe.app.comp.base; import com.jfoenix.controls.JFXTextField; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.property.Property; import javafx.beans.property.SimpleStringProperty; import javafx.event.EventHandler; diff --git a/app/src/main/java/io/xpipe/app/comp/base/ListBoxViewComp.java b/app/src/main/java/io/xpipe/app/comp/base/ListBoxViewComp.java index fa778542a..c86e4455c 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/ListBoxViewComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/ListBoxViewComp.java @@ -1,10 +1,10 @@ package io.xpipe.app.comp.base; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.BindingsHelper; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.application.Platform; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; 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 bd12530fa..ba7e023f5 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 @@ -1,6 +1,6 @@ package io.xpipe.app.comp.base; -import io.xpipe.extension.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.SimpleComp; import javafx.beans.property.ListProperty; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; diff --git a/app/src/main/java/io/xpipe/app/comp/base/ListViewComp.java b/app/src/main/java/io/xpipe/app/comp/base/ListViewComp.java index 835936dae..74699081e 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/ListViewComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/ListViewComp.java @@ -1,11 +1,11 @@ package io.xpipe.app.comp.base; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.BindingsHelper; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.util.PrettyListView; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.util.PrettyListView; import javafx.application.Platform; import javafx.beans.property.Property; import javafx.collections.ListChangeListener; 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 a3bfe8b6a..363860ae5 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 @@ -1,11 +1,11 @@ package io.xpipe.app.comp.base; import com.jfoenix.controls.JFXSpinner; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.util.ThreadHelper; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.util.ThreadHelper; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; diff --git a/app/src/main/java/io/xpipe/app/comp/base/MarkdownComp.java b/app/src/main/java/io/xpipe/app/comp/base/MarkdownComp.java index 5287e4717..654caa49e 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/MarkdownComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/MarkdownComp.java @@ -5,10 +5,10 @@ import com.vladsch.flexmark.parser.Parser; import com.vladsch.flexmark.util.ast.Document; import com.vladsch.flexmark.util.data.MutableDataSet; import io.xpipe.app.core.AppResources; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.issue.ErrorEvent; import javafx.application.Platform; import javafx.geometry.Insets; import javafx.scene.layout.StackPane; diff --git a/app/src/main/java/io/xpipe/app/comp/base/MessageComp.java b/app/src/main/java/io/xpipe/app/comp/base/MessageComp.java index ae34c3d10..e1f0b7f49 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/MessageComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/MessageComp.java @@ -1,9 +1,9 @@ package io.xpipe.app.comp.base; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; -import io.xpipe.extension.util.ThreadHelper; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.util.ThreadHelper; import javafx.beans.property.Property; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ObservableValue; diff --git a/app/src/main/java/io/xpipe/app/comp/base/MultiContentComp.java b/app/src/main/java/io/xpipe/app/comp/base/MultiContentComp.java index e582726b5..a6505cd6c 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/MultiContentComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/MultiContentComp.java @@ -1,9 +1,9 @@ package io.xpipe.app.comp.base; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.value.ObservableBooleanValue; import javafx.scene.layout.Region; import javafx.scene.layout.StackPane; diff --git a/app/src/main/java/io/xpipe/app/comp/base/MultiStepComp.java b/app/src/main/java/io/xpipe/app/comp/base/MultiStepComp.java index 534106514..545d0ac96 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/MultiStepComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/MultiStepComp.java @@ -1,11 +1,11 @@ package io.xpipe.app.comp.base; import com.jfoenix.controls.JFXTabPane; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.beans.binding.Bindings; import javafx.beans.property.Property; import javafx.beans.property.ReadOnlyProperty; @@ -196,7 +196,7 @@ public abstract class MultiStepComp extends Comp> { buttons.getStyleClass().add("buttons"); buttons.setSpacing(5); - var helpButton = new ButtonComp(I18n.observable("help"), null, () -> { + var helpButton = new ButtonComp(AppI18n.observable("help"), null, () -> { getValue().help.run(); }) .styleClass("help") @@ -213,10 +213,10 @@ public abstract class MultiStepComp extends Comp> { buttons.setAlignment(Pos.CENTER_RIGHT); var nextText = Bindings.createStringBinding( - () -> isLastPage() ? I18n.get("finishStep") : I18n.get("nextStep"), currentStep); + () -> isLastPage() ? AppI18n.get("finishStep") : AppI18n.get("nextStep"), currentStep); var nextButton = new ButtonComp(nextText, null, comp::next).styleClass("next"); - var previousButton = new ButtonComp(I18n.observable("previousStep"), null, comp::previous) + var previousButton = new ButtonComp(AppI18n.observable("previousStep"), null, comp::previous) .styleClass("next") .apply(struc -> struc.get() .disableProperty() 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 e41acdef4..3aa662f89 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 @@ -1,9 +1,9 @@ package io.xpipe.app.comp.base; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.augment.GrowAugment; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.augment.GrowAugment; import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; import javafx.css.PseudoClass; diff --git a/app/src/main/java/io/xpipe/app/comp/base/TitledPaneComp.java b/app/src/main/java/io/xpipe/app/comp/base/TitledPaneComp.java index 3471d0f09..1d9981c1a 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/TitledPaneComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/TitledPaneComp.java @@ -1,8 +1,8 @@ package io.xpipe.app.comp.base; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import javafx.beans.value.ObservableValue; import javafx.scene.control.TitledPane; diff --git a/app/src/main/java/io/xpipe/app/comp/source/DataSourceTargetChoiceComp.java b/app/src/main/java/io/xpipe/app/comp/source/DataSourceTargetChoiceComp.java index 47c490d70..ac33f01fd 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/DataSourceTargetChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/DataSourceTargetChoiceComp.java @@ -1,12 +1,12 @@ package io.xpipe.app.comp.source; import io.xpipe.app.core.AppCache; -import io.xpipe.extension.DataSourceTarget; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.util.CustomComboBoxBuilder; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceTarget; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.util.CustomComboBoxBuilder; import javafx.beans.property.Property; import javafx.geometry.Pos; import javafx.scene.Node; @@ -65,24 +65,24 @@ public class DataSourceTargetChoiceComp extends Comp> createBase() { - var addMoreLabel = new Label(I18n.get("addMore"), new FontIcon("mdmz-plus")); + var addMoreLabel = new Label(AppI18n.get("addMore"), new FontIcon("mdmz-plus")); var builder = new CustomComboBoxBuilder( selectedApplication, app -> createLabel(app), new Label(""), v -> true); // builder.addFilter((v, s) -> v.getName().getValue().toLowerCase().contains(s)); - builder.addHeader(I18n.get("programmingLanguages")); + builder.addHeader(AppI18n.get("programmingLanguages")); all.stream() .filter(p -> p.getCategory().equals(DataSourceTarget.Category.PROGRAMMING_LANGUAGE)) .forEach(builder::add); - builder.addHeader(I18n.get("applications")); + builder.addHeader(AppI18n.get("applications")); all.stream() .filter(p -> p.getCategory().equals(DataSourceTarget.Category.APPLICATION)) .forEach(builder::add); - builder.addHeader(I18n.get("other")); + builder.addHeader(AppI18n.get("other")); all.stream() .filter(p -> p.getCategory().equals(DataSourceTarget.Category.OTHER)) .forEach(builder::add); diff --git a/app/src/main/java/io/xpipe/app/comp/source/DsCollectionComp.java b/app/src/main/java/io/xpipe/app/comp/source/DsCollectionComp.java index 38c50cf9f..331180c6d 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/DsCollectionComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/DsCollectionComp.java @@ -1,10 +1,10 @@ package io.xpipe.app.comp.source; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.source.CollectionReadConnection; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; @@ -30,8 +30,8 @@ public class DsCollectionComp extends Comp>> { if (con.getValue() != null) { try { con.getValue().listEntries().forEach(e -> { - var item = new TreeItem(e.getFileName()); - c.add(item); +// var item = new TreeItem(e.getFileName()); +// c.add(item); }); } catch (Exception ex) { ErrorEvent.fromThrowable(ex).handle(); diff --git a/app/src/main/java/io/xpipe/app/comp/source/DsDataTransferComp.java b/app/src/main/java/io/xpipe/app/comp/source/DsDataTransferComp.java index 44998b06d..fdbf05db9 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/DsDataTransferComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/DsDataTransferComp.java @@ -3,22 +3,22 @@ package io.xpipe.app.comp.source; import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppWindowHelper; +import io.xpipe.app.ext.DataSourceTarget; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.DynamicOptionsComp; +import io.xpipe.app.fxcomps.impl.HorizontalComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.util.BusyProperty; import io.xpipe.app.util.Hyperlinks; +import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.source.DataSourceId; -import io.xpipe.extension.DataSourceTarget; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.DynamicOptionsComp; -import io.xpipe.extension.fxcomps.impl.HorizontalComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; -import io.xpipe.extension.util.BusyProperty; -import io.xpipe.extension.util.ThreadHelper; import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.property.Property; @@ -63,7 +63,7 @@ public class DsDataTransferComp extends SimpleComp { Platform.runLater(() -> { var loading = new SimpleBooleanProperty(); AppWindowHelper.sideWindow( - I18n.get("pipeDataSource"), + AppI18n.get("pipeDataSource"), window -> { var ms = new DsDataTransferComp(new SimpleObjectProperty<>(e)) .exclude(DataSourceTarget.byId("base.saveSource") @@ -156,7 +156,7 @@ public class DsDataTransferComp extends SimpleComp { != null); var setupGuideButton = new ButtonComp( - I18n.observable("setupGuide"), new FontIcon("mdoal-integration_instructions"), () -> { + AppI18n.observable("setupGuide"), new FontIcon("mdoal-integration_instructions"), () -> { Hyperlinks.open(selectedTarget.getValue().getSetupGuideURL()); }) .apply(s -> s.get() diff --git a/app/src/main/java/io/xpipe/app/comp/source/DsProviderChoiceComp.java b/app/src/main/java/io/xpipe/app/comp/source/DsProviderChoiceComp.java index b5ffa203f..bbe9e7ad6 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/DsProviderChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/DsProviderChoiceComp.java @@ -1,18 +1,14 @@ package io.xpipe.app.comp.source; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceProviders; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import io.xpipe.app.prefs.AppPrefs; -import io.xpipe.app.util.JfxHelper; +import io.xpipe.app.util.*; import io.xpipe.core.source.DataSourceType; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceProviders; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.util.CustomComboBoxBuilder; -import io.xpipe.extension.util.SimpleValidator; -import io.xpipe.extension.util.Validatable; -import io.xpipe.extension.util.Validator; import javafx.beans.property.Property; import javafx.scene.Node; import javafx.scene.control.ComboBox; @@ -37,16 +33,16 @@ public class DsProviderChoiceComp extends Comp>> im DataSourceProvider.Category type, Property> provider, DataSourceType filter) { this.type = type; this.provider = provider; - check = Validator.nonNull(validator, I18n.observable("provider"), provider); + check = Validator.nonNull(validator, AppI18n.observable("provider"), provider); this.filter = filter; } private Region createDefaultNode() { return switch (type) { case STREAM -> JfxHelper.createNamedEntry( - I18n.get("anyStream"), I18n.get("anyStreamDescription"), "file_icon.png"); + AppI18n.get("anyStream"), AppI18n.get("anyStreamDescription"), "file_icon.png"); case DATABASE -> JfxHelper.createNamedEntry( - I18n.get("selectQueryType"), I18n.get("selectQueryTypeDescription"), "db_icon.png"); + AppI18n.get("selectQueryType"), AppI18n.get("selectQueryTypeDescription"), "db_icon.png"); }; } diff --git a/app/src/main/java/io/xpipe/app/comp/source/DsRawComp.java b/app/src/main/java/io/xpipe/app/comp/source/DsRawComp.java index 9a7b349c2..c3b8ca3b2 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/DsRawComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/DsRawComp.java @@ -1,10 +1,10 @@ package io.xpipe.app.comp.source; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.value.ObservableValue; import javafx.scene.control.TextArea; diff --git a/app/src/main/java/io/xpipe/app/comp/source/DsStorageGroupSelector.java b/app/src/main/java/io/xpipe/app/comp/source/DsStorageGroupSelector.java index 8e8ce896a..168aff55c 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/DsStorageGroupSelector.java +++ b/app/src/main/java/io/xpipe/app/comp/source/DsStorageGroupSelector.java @@ -1,9 +1,9 @@ package io.xpipe.app.comp.source; +import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataStorage; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.util.CustomComboBoxBuilder; +import io.xpipe.app.util.CustomComboBoxBuilder; import javafx.beans.property.Property; import javafx.scene.Node; import javafx.scene.control.ComboBox; diff --git a/app/src/main/java/io/xpipe/app/comp/source/DsStorageTargetComp.java b/app/src/main/java/io/xpipe/app/comp/source/DsStorageTargetComp.java index 5279e233a..dc26c66b2 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/DsStorageTargetComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/DsStorageTargetComp.java @@ -2,12 +2,12 @@ package io.xpipe.app.comp.source; import com.jfoenix.controls.JFXTextField; import io.xpipe.app.comp.storage.DataSourceTypeComp; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.HorizontalComp; import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.core.source.DataSourceId; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.HorizontalComp; import javafx.beans.property.Property; import javafx.geometry.Pos; import javafx.scene.control.Label; diff --git a/app/src/main/java/io/xpipe/app/comp/source/DsStructureComp.java b/app/src/main/java/io/xpipe/app/comp/source/DsStructureComp.java index c2a97cceb..f7747ec3a 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/DsStructureComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/DsStructureComp.java @@ -1,9 +1,9 @@ package io.xpipe.app.comp.source; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import io.xpipe.core.data.node.DataStructureNode; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.scene.control.TreeItem; diff --git a/app/src/main/java/io/xpipe/app/comp/source/DsTableComp.java b/app/src/main/java/io/xpipe/app/comp/source/DsTableComp.java index ab5a6418d..4b89c2a88 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/DsTableComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/DsTableComp.java @@ -1,14 +1,14 @@ package io.xpipe.app.comp.source; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import io.xpipe.core.data.node.ArrayNode; import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.data.type.DataTypeVisitors; import io.xpipe.core.data.type.TupleType; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; diff --git a/app/src/main/java/io/xpipe/app/comp/source/DsTableMappingComp.java b/app/src/main/java/io/xpipe/app/comp/source/DsTableMappingComp.java index ec1fe588c..bd930cb6c 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/DsTableMappingComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/DsTableMappingComp.java @@ -1,11 +1,11 @@ package io.xpipe.app.comp.source; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.LabelComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import io.xpipe.core.source.TableMapping; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.LabelComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; import javafx.beans.value.ObservableValue; import javafx.scene.layout.GridPane; import javafx.scene.layout.Region; @@ -34,7 +34,7 @@ public class DsTableMappingComp extends SimpleComp { grid.add(new LabelComp("->").createRegion(), 1, i); var map = val.map(i).orElse(-1); var output = - new LabelComp(map != -1 ? val.getOutputType().getNames().get(map) : I18n.get("discarded")); + new LabelComp(map != -1 ? val.getOutputType().getNames().get(map) : AppI18n.get("discarded")); grid.add(output.createRegion(), 2, i); if (i % 2 != 0) { diff --git a/app/src/main/java/io/xpipe/app/comp/source/DsTextComp.java b/app/src/main/java/io/xpipe/app/comp/source/DsTextComp.java index 249894b5f..ddec255c6 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/DsTextComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/DsTextComp.java @@ -1,8 +1,8 @@ package io.xpipe.app.comp.source; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.scene.control.TextArea; diff --git a/app/src/main/java/io/xpipe/app/comp/source/DsTypeChoiceComp.java b/app/src/main/java/io/xpipe/app/comp/source/DsTypeChoiceComp.java index 19961b21a..8b2c8cb02 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/DsTypeChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/DsTypeChoiceComp.java @@ -1,14 +1,14 @@ package io.xpipe.app.comp.source; import io.xpipe.app.comp.storage.DataSourceTypeComp; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.util.CustomComboBoxBuilder; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceType; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.util.CustomComboBoxBuilder; import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; import javafx.geometry.Pos; @@ -35,7 +35,7 @@ public class DsTypeChoiceComp extends Comp> { } private Region createLabel(DataSourceType p) { - var l = new Label(I18n.get(p.name().toLowerCase()), new FontIcon(DataSourceTypeComp.ICONS.get(p))); + var l = new Label(AppI18n.get(p.name().toLowerCase()), new FontIcon(DataSourceTypeComp.ICONS.get(p))); l.setAlignment(Pos.CENTER); return l; } diff --git a/app/src/main/java/io/xpipe/app/comp/source/GuiDsConfigStep.java b/app/src/main/java/io/xpipe/app/comp/source/GuiDsConfigStep.java index 751a35658..3fa769533 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/GuiDsConfigStep.java +++ b/app/src/main/java/io/xpipe/app/comp/source/GuiDsConfigStep.java @@ -2,20 +2,20 @@ package io.xpipe.app.comp.source; import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.core.AppFont; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.impl.HorizontalComp; +import io.xpipe.app.fxcomps.impl.IconButtonComp; +import io.xpipe.app.fxcomps.impl.VerticalComp; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.util.BusyProperty; +import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.data.node.ArrayNode; import io.xpipe.core.data.node.TupleNode; import io.xpipe.core.source.*; import io.xpipe.core.store.DataFlow; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.impl.HorizontalComp; -import io.xpipe.extension.fxcomps.impl.IconButtonComp; -import io.xpipe.extension.fxcomps.impl.VerticalComp; -import io.xpipe.extension.util.BusyProperty; -import io.xpipe.extension.util.ThreadHelper; import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.Property; diff --git a/app/src/main/java/io/xpipe/app/comp/source/GuiDsCreatorMultiStep.java b/app/src/main/java/io/xpipe/app/comp/source/GuiDsCreatorMultiStep.java index 5f47c357d..daade5974 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/GuiDsCreatorMultiStep.java +++ b/app/src/main/java/io/xpipe/app/comp/source/GuiDsCreatorMultiStep.java @@ -2,17 +2,17 @@ package io.xpipe.app.comp.source; import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppWindowHelper; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceProviders; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataStorage; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceProviders; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; import javafx.application.Platform; import javafx.beans.property.*; import javafx.scene.control.Alert; @@ -70,7 +70,7 @@ public class GuiDsCreatorMultiStep { var loading = new SimpleBooleanProperty(); var stage = AppWindowHelper.sideWindow( - I18n.get("newDataSource"), + AppI18n.get("newDataSource"), window -> { var ms = new GuiDsCreatorMultiStep<>( window, null, sourceCollection, category, null, null, null, State.CREATE); @@ -93,7 +93,7 @@ public class GuiDsCreatorMultiStep { var loading = new SimpleBooleanProperty(); var stage = AppWindowHelper.sideWindow( - I18n.get("editDataSource"), + AppI18n.get("editDataSource"), window -> { var ms = new GuiDsCreatorMultiStep<>( window, @@ -122,7 +122,7 @@ public class GuiDsCreatorMultiStep { var stage = AppWindowHelper.sideWindow( - I18n.get("newDataSource"), + AppI18n.get("newDataSource"), window -> { var gui = new GuiDsCreatorMultiStep<>( window, @@ -159,9 +159,9 @@ public class GuiDsCreatorMultiStep ms, Stage s) { AppWindowHelper.showBlockingAlert(alert -> { - alert.setTitle(I18n.get("confirmDsCreationAbortTitle")); - alert.setHeaderText(I18n.get("confirmDsCreationAbortHeader")); - alert.setContentText(I18n.get("confirmDsCreationAbortContent")); + alert.setTitle(AppI18n.get("confirmDsCreationAbortTitle")); + alert.setHeaderText(AppI18n.get("confirmDsCreationAbortHeader")); + alert.setContentText(AppI18n.get("confirmDsCreationAbortContent")); alert.setAlertType(Alert.AlertType.CONFIRMATION); }) .filter(b -> b.getButtonData().isDefaultButton()) @@ -256,15 +256,15 @@ public class GuiDsCreatorMultiStep setup() { var list = new ArrayList(); - list.add(new Entry(I18n.observable("selectInput"), createInputStep())); + list.add(new Entry(AppI18n.observable("selectInput"), createInputStep())); list.add(new Entry( - I18n.observable("configure"), + AppI18n.observable("configure"), new GuiDsConfigStep(provider, store, baseSource, source, dataSourceType, loading))); switch (state) { case EDIT -> {} case CREATE -> { list.add( - new Entry(I18n.observable("target"), new GuiDsCreatorTransferStep(targetGroup, store, source))); + new Entry(AppI18n.observable("target"), new GuiDsCreatorTransferStep(targetGroup, store, source))); } } return list; diff --git a/app/src/main/java/io/xpipe/app/comp/source/GuiDsCreatorSaveStep.java b/app/src/main/java/io/xpipe/app/comp/source/GuiDsCreatorSaveStep.java index 14a6d88e9..f58b991ea 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/GuiDsCreatorSaveStep.java +++ b/app/src/main/java/io/xpipe/app/comp/source/GuiDsCreatorSaveStep.java @@ -3,12 +3,12 @@ package io.xpipe.app.comp.source; import com.jfoenix.controls.JFXCheckBox; import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.impl.VerticalComp; import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceEntry; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.impl.VerticalComp; import javafx.beans.property.Property; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; @@ -37,7 +37,7 @@ public class GuiDsCreatorSaveStep extends MultiStepComp.Step> { var cb = new JFXCheckBox(); cb.selectedProperty().bindBidirectional(storeForLaterUse); - var label = new Label(I18n.get("storeForLaterUse")); + var label = new Label(AppI18n.get("storeForLaterUse")); label.setGraphic(cb); return label; }); diff --git a/app/src/main/java/io/xpipe/app/comp/source/GuiDsCreatorTransferStep.java b/app/src/main/java/io/xpipe/app/comp/source/GuiDsCreatorTransferStep.java index cd1d94253..534c44287 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/GuiDsCreatorTransferStep.java +++ b/app/src/main/java/io/xpipe/app/comp/source/GuiDsCreatorTransferStep.java @@ -2,15 +2,15 @@ package io.xpipe.app.comp.source; import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.core.AppFont; +import io.xpipe.app.ext.DataSourceTarget; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.impl.VerticalComp; import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataStorage; import io.xpipe.core.source.DataSource; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataSourceTarget; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.impl.VerticalComp; import javafx.beans.binding.Bindings; import javafx.beans.property.ObjectProperty; import javafx.beans.property.Property; diff --git a/app/src/main/java/io/xpipe/app/comp/source/GuiDsStoreSelectStep.java b/app/src/main/java/io/xpipe/app/comp/source/GuiDsStoreSelectStep.java index c0db5a5fe..021f1af0c 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/GuiDsStoreSelectStep.java +++ b/app/src/main/java/io/xpipe/app/comp/source/GuiDsStoreSelectStep.java @@ -3,18 +3,18 @@ package io.xpipe.app.comp.source; import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.comp.source.store.DsDbStoreChooserComp; import io.xpipe.app.comp.source.store.DsStreamStoreChoiceComp; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.augment.GrowAugment; +import io.xpipe.app.fxcomps.impl.StackComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; +import io.xpipe.app.util.BusyProperty; +import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.source.DataSource; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.augment.GrowAugment; -import io.xpipe.extension.fxcomps.impl.StackComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.util.BusyProperty; -import io.xpipe.extension.util.ThreadHelper; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.Property; diff --git a/app/src/main/java/io/xpipe/app/comp/source/GuiDsTableMappingConfirmation.java b/app/src/main/java/io/xpipe/app/comp/source/GuiDsTableMappingConfirmation.java index 5c8b5f2bd..a3a83dbe6 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/GuiDsTableMappingConfirmation.java +++ b/app/src/main/java/io/xpipe/app/comp/source/GuiDsTableMappingConfirmation.java @@ -3,15 +3,15 @@ package io.xpipe.app.comp.source; import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.comp.storage.source.SourceEntryWrapper; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppWindowHelper; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.LabelComp; +import io.xpipe.app.fxcomps.impl.VerticalComp; +import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.core.source.TableMapping; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.LabelComp; -import io.xpipe.extension.fxcomps.impl.VerticalComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import javafx.geometry.Orientation; @@ -42,7 +42,7 @@ public class GuiDsTableMappingConfirmation extends SimpleComp { var confirmed = new AtomicBoolean(); AppWindowHelper.showAndWaitForWindow(() -> { var stage = AppWindowHelper.sideWindow( - I18n.get("confirmTableMappingTitle"), + AppI18n.get("confirmTableMappingTitle"), window -> { var ms = new GuiDsTableMappingConfirmation(new SimpleObjectProperty<>(mapping)); var multi = new MultiStepComp() { @@ -78,7 +78,7 @@ public class GuiDsTableMappingConfirmation extends SimpleComp { @Override protected Region createSimple() { - var header = new LabelComp(I18n.observable("confirmTableMapping")) + var header = new LabelComp(AppI18n.observable("confirmTableMapping")) .apply(struc -> struc.get().setWrapText(true)); var content = Comp.derive(new DsTableMappingComp(mapping), region -> { var box = new HBox(region); @@ -87,7 +87,7 @@ public class GuiDsTableMappingConfirmation extends SimpleComp { return box; }) .apply(struc -> AppFont.normal(struc.get())); - var changeNotice = new LabelComp(I18n.observable("changeTableMapping")) + var changeNotice = new LabelComp(AppI18n.observable("changeTableMapping")) .apply(struc -> struc.get().setWrapText(true)); var changeButton = Comp.of(() -> { var hl = new Hyperlink("Customizing Data Flows"); diff --git a/app/src/main/java/io/xpipe/app/comp/source/NamedSourceChoiceComp.java b/app/src/main/java/io/xpipe/app/comp/source/NamedSourceChoiceComp.java index 10cfc0e53..72b06f04f 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/NamedSourceChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/NamedSourceChoiceComp.java @@ -1,23 +1,23 @@ package io.xpipe.app.comp.source; import io.xpipe.app.comp.base.ListViewComp; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataStoreProviders; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.FilterComp; +import io.xpipe.app.fxcomps.impl.LabelComp; +import io.xpipe.app.fxcomps.impl.StackComp; +import io.xpipe.app.fxcomps.impl.VerticalComp; +import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.util.JfxHelper; +import io.xpipe.app.util.SimpleValidator; +import io.xpipe.app.util.Validatable; +import io.xpipe.app.util.Validator; import io.xpipe.core.source.DataSource; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataStoreProviders; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.FilterComp; -import io.xpipe.extension.fxcomps.impl.LabelComp; -import io.xpipe.extension.fxcomps.impl.StackComp; -import io.xpipe.extension.fxcomps.impl.VerticalComp; -import io.xpipe.extension.fxcomps.util.BindingsHelper; -import io.xpipe.extension.util.SimpleValidator; -import io.xpipe.extension.util.Validatable; -import io.xpipe.extension.util.Validator; import javafx.beans.binding.Bindings; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; @@ -56,7 +56,7 @@ public class NamedSourceChoiceComp extends SimpleComp implements Validatable { this.filter = filter; this.selected = selected; this.category = category; - check = Validator.nonNull(validator, I18n.observable("source"), selected); + check = Validator.nonNull(validator, AppI18n.observable("source"), selected); } @SuppressWarnings("unchecked") @@ -125,7 +125,7 @@ public class NamedSourceChoiceComp extends SimpleComp implements Validatable { var box = new VerticalComp(List.of(filterComp, view)); - var text = new LabelComp(I18n.observable("noMatchingSourceFound")) + var text = new LabelComp(AppI18n.observable("noMatchingSourceFound")) .apply(struc -> VBox.setVgrow(struc.get(), Priority.ALWAYS)); var notice = new VerticalComp(List.of(text)) .apply(struc -> { diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/DataStoreSelectorComp.java b/app/src/main/java/io/xpipe/app/comp/source/store/DataStoreSelectorComp.java index 219d6e6cb..da8d55c0f 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/DataStoreSelectorComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/DataStoreSelectorComp.java @@ -1,16 +1,16 @@ package io.xpipe.app.comp.source.store; import com.jfoenix.controls.JFXButton; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.DataStoreProviders; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.util.JfxHelper; import io.xpipe.core.impl.FileStore; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.DataStoreProviders; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; import javafx.beans.property.Property; import javafx.scene.control.Button; import javafx.scene.layout.Region; @@ -59,7 +59,7 @@ public class DataStoreSelectorComp extends Comp> { var graphic = provider != null ? provider.getDisplayIconFileName() : "file_icon.png"; if (chosenStore.getValue() == null || !(chosenStore.getValue() instanceof FileStore f)) { return JfxHelper.createNamedEntry( - I18n.get("selectStreamStore"), I18n.get("openStreamStoreWizard"), graphic); + AppI18n.get("selectStreamStore"), AppI18n.get("openStreamStoreWizard"), graphic); } else { return JfxHelper.createNamedEntry( f.getFileName().toString(), f.getFile().toString(), graphic); diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/DsDbStoreChooserComp.java b/app/src/main/java/io/xpipe/app/comp/source/store/DsDbStoreChooserComp.java index f115a42ca..9e10bc56a 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/DsDbStoreChooserComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/DsDbStoreChooserComp.java @@ -1,13 +1,13 @@ package io.xpipe.app.comp.source.store; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.TabPaneComp; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.TabPaneComp; import javafx.beans.binding.Bindings; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; @@ -40,7 +40,7 @@ public class DsDbStoreChooserComp extends SimpleComp { provider); var connections = new TabPaneComp.Entry( - I18n.observable("savedConnections"), + AppI18n.observable("savedConnections"), "mdi2m-monitor", NamedStoreChoiceComp.create(filter, input, DataStoreProvider.DataCategory.DATABASE) .styleClass("store-local-file-chooser")); diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/DsFileHistoryComp.java b/app/src/main/java/io/xpipe/app/comp/source/store/DsFileHistoryComp.java index 773e36c26..7cbdf49a4 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/DsFileHistoryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/DsFileHistoryComp.java @@ -3,11 +3,11 @@ package io.xpipe.app.comp.source.store; import com.jfoenix.controls.JFXButton; import io.xpipe.app.core.AppCache; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.util.JfxHelper; import io.xpipe.core.impl.FileStore; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; import javafx.beans.property.Property; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; @@ -39,7 +39,7 @@ public class DsFileHistoryComp extends SimpleComp { } previous.setFillWidth(true); - var label = new Label(I18n.get("recentFiles")); + var label = new Label(AppI18n.get("recentFiles")); AppFont.header(label); previous.getChildren().add(label); diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/DsLocalDirectoryBrowseComp.java b/app/src/main/java/io/xpipe/app/comp/source/store/DsLocalDirectoryBrowseComp.java index 857258244..6b28c73cc 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/DsLocalDirectoryBrowseComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/DsLocalDirectoryBrowseComp.java @@ -1,13 +1,13 @@ package io.xpipe.app.comp.source.store; import com.jfoenix.controls.JFXButton; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.util.JfxHelper; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; import javafx.beans.property.Property; import javafx.scene.control.Button; import javafx.scene.layout.Region; @@ -33,7 +33,7 @@ public class DsLocalDirectoryBrowseComp extends Comp> { button.setOnAction(e -> { var dirChooser = new DirectoryChooser(); dirChooser.setTitle( - I18n.get("browseDirectoryTitle", provider.getFileProvider().getFileName())); + AppI18n.get("browseDirectoryTitle", provider.getFileProvider().getFileName())); File file = dirChooser.showDialog(button.getScene().getWindow()); if (file != null && file.exists()) { chosenDir.setValue(file.toPath()); @@ -55,7 +55,7 @@ public class DsLocalDirectoryBrowseComp extends Comp> { private Region getGraphic() { var graphic = provider.getDisplayIconFileName(); if (chosenDir.getValue() == null) { - return JfxHelper.createNamedEntry(I18n.get("browse"), I18n.get("selectDirectoryFromComputer"), graphic); + return JfxHelper.createNamedEntry(AppI18n.get("browse"), AppI18n.get("selectDirectoryFromComputer"), graphic); } else { return JfxHelper.createNamedEntry( chosenDir.getValue().getFileName().toString(), diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/DsLocalFileBrowseComp.java b/app/src/main/java/io/xpipe/app/comp/source/store/DsLocalFileBrowseComp.java index 0903a6ef1..d26b5a781 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/DsLocalFileBrowseComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/DsLocalFileBrowseComp.java @@ -1,15 +1,15 @@ package io.xpipe.app.comp.source.store; import io.xpipe.app.comp.base.ButtonComp; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.util.JfxHelper; import io.xpipe.core.impl.FileStore; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; import javafx.scene.control.Button; @@ -69,16 +69,16 @@ public class DsLocalFileBrowseComp extends Comp> { private FileChooser createChooser() { FileChooser fileChooser = new FileChooser(); - fileChooser.setTitle(I18n.get("browseFileTitle")); + fileChooser.setTitle(AppI18n.get("browseFileTitle")); if (!hasProvider()) { - fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(I18n.get("anyFile"), "*")); + fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(AppI18n.get("anyFile"), "*")); return fileChooser; } if (hasProvider()) { provider.getValue().getFileProvider().getFileExtensions().forEach((key, value) -> { - var name = I18n.get(key); + var name = AppI18n.get(key); if (value != null) { fileChooser .getExtensionFilters() @@ -90,7 +90,7 @@ public class DsLocalFileBrowseComp extends Comp> { }); if (!provider.getValue().getFileProvider().getFileExtensions().containsValue(null)) { - fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(I18n.get("anyFile"), "*")); + fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(AppI18n.get("anyFile"), "*")); } } @@ -100,7 +100,7 @@ public class DsLocalFileBrowseComp extends Comp> { private Region getGraphic() { var graphic = hasProvider() ? provider.getValue().getDisplayIconFileName() : "file_icon.png"; if (chosenFile.getValue() == null || !(chosenFile.getValue() instanceof FileStore f) || f.getFile() == null) { - return JfxHelper.createNamedEntry(I18n.get("browse"), I18n.get("selectFileFromComputer"), graphic); + return JfxHelper.createNamedEntry(AppI18n.get("browse"), AppI18n.get("selectFileFromComputer"), graphic); } else { return JfxHelper.createNamedEntry( f.getFileName().toString(), f.getFile().toString(), graphic); diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/DsRemoteFileChoiceComp.java b/app/src/main/java/io/xpipe/app/comp/source/store/DsRemoteFileChoiceComp.java index 73d0df2f0..5f5eb0575 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/DsRemoteFileChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/DsRemoteFileChoiceComp.java @@ -1,12 +1,13 @@ package io.xpipe.app.comp.source.store; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.FileSystemStoreChoiceComp; +import io.xpipe.app.util.DynamicOptionsBuilder; import io.xpipe.core.impl.FileStore; import io.xpipe.core.store.DataStore; +import io.xpipe.core.store.FileSystem; import io.xpipe.core.store.FileSystemStore; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.FileSystemStoreChoiceComp; -import io.xpipe.extension.util.DynamicOptionsBuilder; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; @@ -25,8 +26,8 @@ public class DsRemoteFileChoiceComp extends SimpleComp { var machine = new SimpleObjectProperty(); var fileName = new SimpleStringProperty(); return new DynamicOptionsBuilder(false) - .addComp(I18n.observable("machine"), new FileSystemStoreChoiceComp(machine), machine) - .addString(I18n.observable("file"), fileName, true) + .addComp(AppI18n.observable("machine"), new FileSystemStoreChoiceComp(machine), machine) + .addString(AppI18n.observable("file"), fileName, true) .bind( () -> { if (fileName.get() == null || machine.get() == null) { diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/DsStoreProviderChoiceComp.java b/app/src/main/java/io/xpipe/app/comp/source/store/DsStoreProviderChoiceComp.java index 6fa188d6f..6ac44d45f 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/DsStoreProviderChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/DsStoreProviderChoiceComp.java @@ -1,14 +1,14 @@ package io.xpipe.app.comp.source.store; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.DataStoreProviders; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.app.util.CustomComboBoxBuilder; import io.xpipe.app.util.JfxHelper; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.DataStoreProviders; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.util.CustomComboBoxBuilder; import javafx.beans.property.Property; import javafx.scene.Node; import javafx.scene.control.ComboBox; @@ -29,7 +29,7 @@ public class DsStoreProviderChoiceComp extends Comp private Region createDefaultNode() { return JfxHelper.createNamedEntry( - I18n.get("selectType"), I18n.get("selectTypeDescription"), "machine_icon.png"); + AppI18n.get("selectType"), AppI18n.get("selectTypeDescription"), "machine_icon.png"); } private List getProviders() { diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/DsStreamStoreChoiceComp.java b/app/src/main/java/io/xpipe/app/comp/source/store/DsStreamStoreChoiceComp.java index 9b710e167..a3358f30f 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/DsStreamStoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/DsStreamStoreChoiceComp.java @@ -2,25 +2,25 @@ package io.xpipe.app.comp.source.store; import io.xpipe.app.comp.base.FileDropOverlayComp; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceProviders; +import io.xpipe.app.ext.DataStoreProvider; +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.TabPaneComp; +import io.xpipe.app.fxcomps.impl.VerticalComp; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.app.util.SimpleValidator; +import io.xpipe.app.util.Validatable; +import io.xpipe.app.util.Validator; +import io.xpipe.app.util.XPipeDaemon; import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.LocalStore; import io.xpipe.core.store.DataStore; import io.xpipe.core.store.StreamDataStore; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceProviders; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.augment.GrowAugment; -import io.xpipe.extension.fxcomps.impl.TabPaneComp; -import io.xpipe.extension.fxcomps.impl.VerticalComp; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; -import io.xpipe.extension.util.SimpleValidator; -import io.xpipe.extension.util.Validatable; -import io.xpipe.extension.util.Validator; -import io.xpipe.extension.util.XPipeDaemon; import javafx.beans.binding.Bindings; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; @@ -64,7 +64,7 @@ public class DsStreamStoreChoiceComp extends SimpleComp implements Validatable { this.showSaved = showSaved; this.mode = mode; validator = new SimpleValidator(); - check = Validator.nonNull(validator, I18n.observable("streamStore"), selected); + check = Validator.nonNull(validator, AppI18n.observable("streamStore"), selected); } @Override @@ -78,12 +78,12 @@ public class DsStreamStoreChoiceComp extends SimpleComp implements Validatable { ? selected.getValue() : null); var browseComp = new DsLocalFileBrowseComp(provider, localStore, mode).apply(GrowAugment.create(true, false)); - var dragAndDropLabel = Comp.of(() -> new Label(I18n.get("dragAndDropFilesHere"))) + var dragAndDropLabel = Comp.of(() -> new Label(AppI18n.get("dragAndDropFilesHere"))) .apply(s -> s.get().setAlignment(Pos.CENTER)) .apply(struc -> AppFont.small(struc.get())); // var historyComp = new DsFileHistoryComp(provider, chosenFile); var local = new TabPaneComp.Entry( - I18n.observable("localFile"), + AppI18n.observable("localFile"), "mdi2m-monitor", new VerticalComp(List.of(browseComp, dragAndDropLabel)) .styleClass("store-local-file-chooser") @@ -108,18 +108,18 @@ public class DsStreamStoreChoiceComp extends SimpleComp implements Validatable { ? selected.getValue() : null); var remote = new TabPaneComp.Entry( - I18n.observable("remote"), "mdi2e-earth", new DsRemoteFileChoiceComp(remoteStore)); + AppI18n.observable("remote"), "mdi2e-earth", new DsRemoteFileChoiceComp(remoteStore)); var namedStore = new SimpleObjectProperty(isNamedStore ? selected.getValue() : null); var named = new TabPaneComp.Entry( - I18n.observable("stored"), + AppI18n.observable("stored"), "mdrmz-storage", NamedStoreChoiceComp.create(filter, namedStore, DataStoreProvider.DataCategory.STREAM)); var otherStore = new SimpleObjectProperty( localStore.get() == null && remoteStore.get() == null && !isNamedStore ? selected.getValue() : null); var other = new TabPaneComp.Entry( - I18n.observable("other"), + AppI18n.observable("other"), "mdrmz-web_asset", new DataStoreSelectorComp(DataStoreProvider.DataCategory.STREAM, otherStore)); diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/GuiDsStoreCreator.java b/app/src/main/java/io/xpipe/app/comp/source/store/GuiDsStoreCreator.java index aa15698be..9104036fd 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/GuiDsStoreCreator.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/GuiDsStoreCreator.java @@ -6,23 +6,23 @@ import io.xpipe.app.comp.base.MessageComp; import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.core.AppExtensionManager; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppWindowHelper; import io.xpipe.app.core.mode.OperationMode; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.DownloadModuleInstall; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.augment.GrowAugment; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.ExceptionConverter; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.app.util.*; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.DownloadModuleInstall; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.ExceptionConverter; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.augment.GrowAugment; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; -import io.xpipe.extension.util.*; import javafx.application.Platform; import javafx.beans.property.*; import javafx.beans.value.ObservableValue; @@ -83,8 +83,8 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { }); this.apply(r -> { - r.get().setPrefWidth(AppFont.em(30)); - r.get().setPrefHeight(AppFont.em(35)); + r.get().setPrefWidth(AppFont.em(32)); + r.get().setPrefHeight(AppFont.em(38)); }); } @@ -121,7 +121,7 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { var name = "addConnection"; Platform.runLater(() -> { var stage = AppWindowHelper.sideWindow( - I18n.get(name), + AppI18n.get(name), window -> { return new MultiStepComp() { @@ -130,7 +130,7 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { @Override protected List setup() { - return List.of(new Entry(I18n.observable("a"), creator)); + return List.of(new Entry(AppI18n.observable("a"), creator)); } @Override @@ -150,9 +150,9 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { private static boolean showInvalidConfirmAlert() { return AppWindowHelper.showBlockingAlert(alert -> { - alert.setTitle(I18n.get("confirmInvalidStoreTitle")); - alert.setHeaderText(I18n.get("confirmInvalidStoreHeader")); - alert.setContentText(I18n.get("confirmInvalidStoreContent")); + alert.setTitle(AppI18n.get("confirmInvalidStoreTitle")); + alert.setHeaderText(AppI18n.get("confirmInvalidStoreHeader")); + alert.setContentText(AppI18n.get("confirmInvalidStoreContent")); alert.setAlertType(Alert.AlertType.CONFIRMATION); }) .map(b -> b.getButtonData().isDefaultButton()) @@ -162,8 +162,8 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { private Region createStoreProperties(Comp comp, Validator propVal) { return new DynamicOptionsBuilder(false) .addComp((ObservableValue) null, comp, input) - .addTitle(I18n.observable("properties")) - .addString(I18n.observable("name"), name, false) + .addTitle(AppI18n.observable("properties")) + .addString(AppI18n.observable("name"), name, false) .nonNull(propVal) .bind( () -> { diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/NamedStoreChoiceComp.java b/app/src/main/java/io/xpipe/app/comp/source/store/NamedStoreChoiceComp.java index 692786f1a..08c581074 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/NamedStoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/NamedStoreChoiceComp.java @@ -3,22 +3,22 @@ package io.xpipe.app.comp.source.store; import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ListViewComp; import io.xpipe.app.comp.storage.store.StoreViewState; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.FilterComp; +import io.xpipe.app.fxcomps.impl.LabelComp; +import io.xpipe.app.fxcomps.impl.StackComp; +import io.xpipe.app.fxcomps.impl.VerticalComp; +import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.JfxHelper; +import io.xpipe.app.util.SimpleValidator; +import io.xpipe.app.util.Validatable; +import io.xpipe.app.util.Validator; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.FilterComp; -import io.xpipe.extension.fxcomps.impl.LabelComp; -import io.xpipe.extension.fxcomps.impl.StackComp; -import io.xpipe.extension.fxcomps.impl.VerticalComp; -import io.xpipe.extension.fxcomps.util.BindingsHelper; -import io.xpipe.extension.util.SimpleValidator; -import io.xpipe.extension.util.Validatable; -import io.xpipe.extension.util.Validator; import javafx.beans.binding.Bindings; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; @@ -57,7 +57,7 @@ public class NamedStoreChoiceComp extends SimpleComp implements Validatable { this.filter = filter; this.selected = selected; this.category = category; - check = Validator.nonNull(validator, I18n.observable("store"), selected); + check = Validator.nonNull(validator, AppI18n.observable("store"), selected); } public static NamedStoreChoiceComp create( @@ -139,9 +139,9 @@ public class NamedStoreChoiceComp extends SimpleComp implements Validatable { var box = new VerticalComp(List.of(filterComp, view)); - var text = new LabelComp(I18n.observable("noMatchingStoreFound")) + var text = new LabelComp(AppI18n.observable("noMatchingStoreFound")) .apply(struc -> VBox.setVgrow(struc.get(), Priority.ALWAYS)); - var addButton = new ButtonComp(I18n.observable("addStore"), null, () -> { + var addButton = new ButtonComp(AppI18n.observable("addStore"), null, () -> { GuiDsStoreCreator.showCreation(v -> v.getCategory().equals(category)); }); var notice = new VerticalComp(List.of(text, addButton)) diff --git a/app/src/main/java/io/xpipe/app/comp/storage/DataSourceTypeComp.java b/app/src/main/java/io/xpipe/app/comp/storage/DataSourceTypeComp.java index bddd141af..382802df6 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/DataSourceTypeComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/DataSourceTypeComp.java @@ -1,8 +1,8 @@ package io.xpipe.app.comp.storage; +import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataFlow; -import io.xpipe.extension.fxcomps.SimpleComp; import javafx.beans.binding.Bindings; import javafx.geometry.Insets; import javafx.geometry.Pos; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/DataStoreTypeComp.java b/app/src/main/java/io/xpipe/app/comp/storage/DataStoreTypeComp.java index e36064421..eefee1d20 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/DataStoreTypeComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/DataStoreTypeComp.java @@ -1,7 +1,7 @@ package io.xpipe.app.comp.storage; +import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.core.source.DataSource; -import io.xpipe.extension.fxcomps.SimpleComp; import javafx.beans.binding.Bindings; import javafx.geometry.Pos; import javafx.scene.layout.Region; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/StorageFilter.java b/app/src/main/java/io/xpipe/app/comp/storage/StorageFilter.java index 58509cb36..3c2670d4c 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/StorageFilter.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/StorageFilter.java @@ -1,6 +1,6 @@ package io.xpipe.app.comp.storage; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.beans.value.ObservableValue; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionComp.java b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionComp.java index c14709279..ec1873ad1 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionComp.java @@ -6,15 +6,14 @@ import io.xpipe.app.comp.base.LazyTextFieldComp; import io.xpipe.app.comp.storage.source.SourceEntryWrapper; import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppI18n; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; -import io.xpipe.extension.fxcomps.impl.IconButtonComp; -import io.xpipe.extension.fxcomps.impl.PrettyImageComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.impl.FancyTooltipAugment; +import io.xpipe.app.fxcomps.impl.IconButtonComp; +import io.xpipe.app.fxcomps.impl.PrettyImageComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.issue.TrackEvent; import javafx.beans.binding.Bindings; import javafx.geometry.Insets; import javafx.geometry.Pos; @@ -125,7 +124,7 @@ public class SourceCollectionComp extends SimpleComp { infoIcon.setOpacity(0.75); return new StackPane(infoIcon); }) - .apply(new FancyTooltipAugment<>(I18n.observable("temporaryCollectionNote"))) + .apply(new FancyTooltipAugment<>(AppI18n.observable("temporaryCollectionNote"))) .createRegion(); var label = new Label(group.getName(), tempNote); label.getStyleClass().add("temp"); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionContextMenu.java b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionContextMenu.java index f1c7ab42e..aaa531380 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionContextMenu.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionContextMenu.java @@ -1,11 +1,11 @@ package io.xpipe.app.comp.storage.collection; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppWindowHelper; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.augment.PopupMenuAugment; import io.xpipe.app.prefs.AppPrefs; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.augment.PopupMenuAugment; -import io.xpipe.extension.util.DesktopHelper; +import io.xpipe.app.util.DesktopHelper; import javafx.scene.control.Alert; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; @@ -28,9 +28,9 @@ public class SourceCollectionContextMenu> extends Pop private void onDelete() { if (group.getEntries().size() > 0) { AppWindowHelper.showBlockingAlert(alert -> { - alert.setTitle(I18n.get("confirmCollectionDeletionTitle")); - alert.setHeaderText(I18n.get("confirmCollectionDeletionHeader", group.getName())); - alert.setContentText(I18n.get( + alert.setTitle(AppI18n.get("confirmCollectionDeletionTitle")); + alert.setHeaderText(AppI18n.get("confirmCollectionDeletionHeader", group.getName())); + alert.setContentText(AppI18n.get( "confirmCollectionDeletionContent", group.getEntries().size())); alert.setAlertType(Alert.AlertType.CONFIRMATION); @@ -47,9 +47,9 @@ public class SourceCollectionContextMenu> extends Pop private void onClean() { if (group.getEntries().size() > 0) { AppWindowHelper.showBlockingAlert(alert -> { - alert.setTitle(I18n.get("confirmCollectionDeletionTitle")); - alert.setHeaderText(I18n.get("confirmCollectionDeletionHeader", group.getName())); - alert.setContentText(I18n.get( + alert.setTitle(AppI18n.get("confirmCollectionDeletionTitle")); + alert.setHeaderText(AppI18n.get("confirmCollectionDeletionHeader", group.getName())); + alert.setContentText(AppI18n.get( "confirmCollectionDeletionContent", group.getEntries().size())); alert.setAlertType(Alert.AlertType.CONFIRMATION); @@ -72,13 +72,13 @@ public class SourceCollectionContextMenu> extends Pop cm.getItems().add(name); cm.getItems().add(new SeparatorMenuItem()); { - var properties = new MenuItem(I18n.get("properties"), new FontIcon("mdi2a-application-cog")); + var properties = new MenuItem(AppI18n.get("properties"), new FontIcon("mdi2a-application-cog")); properties.setOnAction(e -> {}); // cm.getItems().add(properties); } if (group.isRenameable()) { - var rename = new MenuItem(I18n.get("rename"), new FontIcon("mdal-edit")); + var rename = new MenuItem(AppI18n.get("rename"), new FontIcon("mdal-edit")); rename.setOnAction(e -> { renameTextField.requestFocus(); }); @@ -86,7 +86,7 @@ public class SourceCollectionContextMenu> extends Pop } if (AppPrefs.get().developerMode().getValue()) { - var openDir = new MenuItem(I18n.get("openDir"), new FontIcon("mdal-edit")); + var openDir = new MenuItem(AppI18n.get("openDir"), new FontIcon("mdal-edit")); openDir.setOnAction(e -> { DesktopHelper.browseFileInDirectory(group.getCollection().getDirectory()); }); @@ -94,13 +94,13 @@ public class SourceCollectionContextMenu> extends Pop } if (group.isDeleteable()) { - var del = new MenuItem(I18n.get("delete"), new FontIcon("mdal-delete_outline")); + var del = new MenuItem(AppI18n.get("delete"), new FontIcon("mdal-delete_outline")); del.setOnAction(e -> { onDelete(); }); cm.getItems().add(del); } else { - var del = new MenuItem(I18n.get("clean"), new FontIcon("mdal-delete_outline")); + var del = new MenuItem(AppI18n.get("clean"), new FontIcon("mdal-delete_outline")); del.setOnAction(e -> { onClean(); }); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionEmptyIntroComp.java b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionEmptyIntroComp.java index 73c4da583..f02a98163 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionEmptyIntroComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionEmptyIntroComp.java @@ -2,9 +2,9 @@ package io.xpipe.app.comp.storage.collection; import io.xpipe.app.comp.storage.DataSourceTypeComp; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.core.source.DataSourceType; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; import javafx.geometry.Orientation; import javafx.geometry.Pos; import javafx.scene.control.Label; @@ -18,38 +18,38 @@ public class SourceCollectionEmptyIntroComp extends SimpleComp { @Override protected Region createSimple() { - var title = new Label(I18n.get("dataSourceIntroTitle")); + var title = new Label(AppI18n.get("dataSourceIntroTitle")); AppFont.setSize(title, 7); title.getStyleClass().add("title-header"); var descFi = new FontIcon("mdi2i-information-outline"); - var introDesc = new Label(I18n.get("dataSourceIntroDescription")); + var introDesc = new Label(AppI18n.get("dataSourceIntroDescription")); introDesc.heightProperty().addListener((c, o, n) -> { descFi.iconSizeProperty().set(n.intValue()); }); var tableFi = new DataSourceTypeComp(DataSourceType.TABLE, null).createRegion(); - var table = new Label(I18n.get("dataSourceIntroTable"), tableFi); + var table = new Label(AppI18n.get("dataSourceIntroTable"), tableFi); tableFi.prefWidthProperty().bind(table.heightProperty()); tableFi.prefHeightProperty().bind(table.heightProperty()); var structureFi = new DataSourceTypeComp(DataSourceType.STRUCTURE, null).createRegion(); - var structure = new Label(I18n.get("dataSourceIntroStructure"), structureFi); + var structure = new Label(AppI18n.get("dataSourceIntroStructure"), structureFi); structureFi.prefWidthProperty().bind(structure.heightProperty()); structureFi.prefHeightProperty().bind(structure.heightProperty()); var textFi = new DataSourceTypeComp(DataSourceType.TEXT, null).createRegion(); - var text = new Label(I18n.get("dataSourceIntroText"), textFi); + var text = new Label(AppI18n.get("dataSourceIntroText"), textFi); textFi.prefWidthProperty().bind(text.heightProperty()); textFi.prefHeightProperty().bind(text.heightProperty()); var binaryFi = new DataSourceTypeComp(DataSourceType.RAW, null).createRegion(); - var binary = new Label(I18n.get("dataSourceIntroBinary"), binaryFi); + var binary = new Label(AppI18n.get("dataSourceIntroBinary"), binaryFi); binaryFi.prefWidthProperty().bind(binary.heightProperty()); binaryFi.prefHeightProperty().bind(binary.heightProperty()); var collectionFi = new DataSourceTypeComp(DataSourceType.COLLECTION, null).createRegion(); - var collection = new Label(I18n.get("dataSourceIntroCollection"), collectionFi); + var collection = new Label(AppI18n.get("dataSourceIntroCollection"), collectionFi); collectionFi.prefWidthProperty().bind(collection.heightProperty()); collectionFi.prefHeightProperty().bind(collection.heightProperty()); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionFilterBarComp.java b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionFilterBarComp.java index 003b8e3a6..882679fc2 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionFilterBarComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionFilterBarComp.java @@ -2,10 +2,10 @@ package io.xpipe.app.comp.storage.collection; import io.xpipe.app.comp.base.CountComp; import io.xpipe.app.core.AppFont; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; -import io.xpipe.extension.fxcomps.impl.FilterComp; -import io.xpipe.extension.fxcomps.impl.IconButtonComp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.FancyTooltipAugment; +import io.xpipe.app.fxcomps.impl.FilterComp; +import io.xpipe.app.fxcomps.impl.IconButtonComp; import javafx.geometry.Pos; import javafx.scene.control.Label; import javafx.scene.input.KeyCode; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionLayoutComp.java b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionLayoutComp.java index e7a5a1c2a..dc2a9e846 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionLayoutComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionLayoutComp.java @@ -3,14 +3,14 @@ package io.xpipe.app.comp.storage.collection; import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.storage.source.SourceEntryListComp; import io.xpipe.app.comp.storage.source.SourceEntryListHeaderComp; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; -import io.xpipe.extension.fxcomps.impl.StackComp; -import io.xpipe.extension.fxcomps.impl.VerticalComp; -import io.xpipe.extension.fxcomps.util.BindingsHelper; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.core.AppI18n; +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.StackComp; +import io.xpipe.app.fxcomps.impl.VerticalComp; +import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.beans.binding.Bindings; import javafx.geometry.Insets; import javafx.geometry.Pos; @@ -49,7 +49,7 @@ public class SourceCollectionLayoutComp extends SimpleComp { var filler = Comp.of(() -> new Region()); filler.styleClass("bar"); filler.styleClass("filler-bar"); - var button = new ButtonComp(I18n.observable("addCollection"), new FontIcon("mdi2f-folder-plus-outline"), () -> { + var button = new ButtonComp(AppI18n.observable("addCollection"), new FontIcon("mdi2f-folder-plus-outline"), () -> { SourceCollectionViewState.get().addNewCollection(); }) .apply(new FancyTooltipAugment<>("addCollectionFolder")); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionViewState.java b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionViewState.java index 8de122108..5c526a693 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionViewState.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionViewState.java @@ -2,14 +2,14 @@ package io.xpipe.app.comp.storage.collection; import io.xpipe.app.comp.storage.StorageFilter; import io.xpipe.app.comp.storage.source.SourceEntryWrapper; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.StorageListener; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.util.BindingsHelper; -import io.xpipe.extension.fxcomps.util.PlatformThread; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ChangeListener; @@ -80,7 +80,7 @@ public class SourceCollectionViewState { public void addNewCollection() { PlatformThread.runLaterIfNeeded(() -> { - var col = DataSourceCollection.createNew(I18n.get("newCollection")); + var col = DataSourceCollection.createNew(AppI18n.get("newCollection")); DataStorage.get().addCollection(col); allGroups.stream() .filter(g -> g.getCollection().equals(col)) diff --git a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionWrapper.java b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionWrapper.java index ad9788a16..93819e135 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/collection/SourceCollectionWrapper.java @@ -4,12 +4,12 @@ import io.xpipe.app.comp.source.GuiDsCreatorMultiStep; import io.xpipe.app.comp.storage.StorageFilter; import io.xpipe.app.comp.storage.source.SourceEntryDisplayMode; import io.xpipe.app.comp.storage.source.SourceEntryWrapper; +import io.xpipe.app.ext.DataSourceProvider; import io.xpipe.app.storage.CollectionListener; import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataStorage; import io.xpipe.core.impl.FileStore; -import io.xpipe.extension.DataSourceProvider; import javafx.beans.property.*; import javafx.collections.FXCollections; import javafx.collections.ObservableList; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryComp.java b/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryComp.java index d8b6d0c25..93f175931 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryComp.java @@ -7,17 +7,17 @@ import io.xpipe.app.comp.storage.DataSourceTypeComp; import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppResources; +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.IconButtonComp; +import io.xpipe.app.fxcomps.impl.LabelComp; +import io.xpipe.app.fxcomps.impl.PrettyImageComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.core.store.DataFlow; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.augment.GrowAugment; -import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; -import io.xpipe.extension.fxcomps.impl.IconButtonComp; -import io.xpipe.extension.fxcomps.impl.LabelComp; -import io.xpipe.extension.fxcomps.impl.PrettyImageComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleStringProperty; import javafx.css.PseudoClass; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryContextMenu.java b/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryContextMenu.java index 64454c5fe..13670fee4 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryContextMenu.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryContextMenu.java @@ -1,14 +1,14 @@ package io.xpipe.app.comp.storage.source; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.augment.PopupMenuAugment; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataStorage; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.augment.PopupMenuAugment; -import io.xpipe.extension.util.DesktopHelper; +import io.xpipe.app.util.DesktopHelper; import javafx.beans.binding.Bindings; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; @@ -57,28 +57,28 @@ public class SourceEntryContextMenu> extends PopupMen cm.getItems().add(new SeparatorMenuItem()); } - var properties = new MenuItem(I18n.get("properties"), new FontIcon("mdi2a-application-cog")); + var properties = new MenuItem(AppI18n.get("properties"), new FontIcon("mdi2a-application-cog")); properties.setOnAction(e -> {}); // cm.getItems().add(properties); - var rename = new MenuItem(I18n.get("rename"), new FontIcon("mdi2r-rename-box")); + var rename = new MenuItem(AppI18n.get("rename"), new FontIcon("mdi2r-rename-box")); rename.setOnAction(e -> { renameTextField.requestFocus(); }); cm.getItems().add(rename); - var validate = new MenuItem(I18n.get("refresh"), new FontIcon("mdal-360")); + var validate = new MenuItem(AppI18n.get("refresh"), new FontIcon("mdal-360")); validate.setOnAction(event -> { DataStorage.get().refreshAsync(entry.getEntry(), true); }); cm.getItems().add(validate); - var edit = new MenuItem(I18n.get("edit"), new FontIcon("mdal-edit")); + var edit = new MenuItem(AppI18n.get("edit"), new FontIcon("mdal-edit")); edit.setOnAction(event -> entry.editDialog()); edit.disableProperty().bind(Bindings.equal(DataSourceEntry.State.LOAD_FAILED, entry.getState())); cm.getItems().add(edit); - var del = new MenuItem(I18n.get("delete"), new FontIcon("mdal-delete_outline")); + var del = new MenuItem(AppI18n.get("delete"), new FontIcon("mdal-delete_outline")); del.setOnAction(e -> { entry.delete(); }); @@ -87,7 +87,7 @@ public class SourceEntryContextMenu> extends PopupMen if (AppPrefs.get().developerMode().getValue()) { cm.getItems().add(new SeparatorMenuItem()); - var openDir = new MenuItem(I18n.get("browseInternal"), new FontIcon("mdi2f-folder-open-outline")); + var openDir = new MenuItem(AppI18n.get("browseInternal"), new FontIcon("mdi2f-folder-open-outline")); openDir.setOnAction(e -> { DesktopHelper.browsePath(entry.getEntry().getDirectory()); }); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryListComp.java b/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryListComp.java index 93f748edb..7fe5a7cef 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryListComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryListComp.java @@ -5,8 +5,8 @@ import io.xpipe.app.comp.base.MultiContentComp; import io.xpipe.app.comp.storage.collection.SourceCollectionEmptyIntroComp; import io.xpipe.app.comp.storage.collection.SourceCollectionViewState; import io.xpipe.app.comp.storage.collection.SourceCollectionWrapper; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; import javafx.application.Platform; import javafx.beans.value.ObservableBooleanValue; import javafx.collections.ListChangeListener; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryListHeaderComp.java b/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryListHeaderComp.java index 061ff1ddb..349cd808c 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryListHeaderComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryListHeaderComp.java @@ -7,15 +7,15 @@ import io.xpipe.app.comp.storage.collection.SourceCollectionSortMode; import io.xpipe.app.comp.storage.collection.SourceCollectionViewState; import io.xpipe.app.comp.storage.collection.SourceCollectionWrapper; import io.xpipe.app.core.AppFont; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; -import io.xpipe.extension.fxcomps.impl.HorizontalComp; -import io.xpipe.extension.fxcomps.impl.IconButtonComp; -import io.xpipe.extension.fxcomps.impl.VerticalComp; -import io.xpipe.extension.fxcomps.util.BindingsHelper; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceProvider; +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.impl.VerticalComp; +import io.xpipe.app.fxcomps.util.BindingsHelper; import javafx.beans.binding.Bindings; import javafx.geometry.Orientation; import javafx.geometry.Pos; @@ -188,7 +188,7 @@ public class SourceEntryListHeaderComp extends SimpleComp { @Override protected Region createSimple() { - var label = new Label(I18n.get("none")); + var label = new Label(AppI18n.get("none")); if (SourceCollectionViewState.get().getSelectedGroup() != null) { label.textProperty() .bind(SourceCollectionViewState.get().getSelectedGroup().nameProperty()); @@ -239,7 +239,7 @@ public class SourceEntryListHeaderComp extends SimpleComp { private Comp createActionsButtonBar() { var newFile = new ButtonComp( - I18n.observable(group != null ? "addStream" : "pipeStream"), + AppI18n.observable(group != null ? "addStream" : "pipeStream"), new FontIcon("mdi2f-file-plus-outline"), () -> { var selected = SourceCollectionViewState.get() @@ -253,7 +253,7 @@ public class SourceEntryListHeaderComp extends SimpleComp { .apply(new FancyTooltipAugment<>("addStreamDataSource")); var newDb = new ButtonComp( - I18n.observable(group != null ? "addDatabase" : "pipeDatabase"), + AppI18n.observable(group != null ? "addDatabase" : "pipeDatabase"), new FontIcon("mdi2d-database-plus-outline"), () -> { var selected = SourceCollectionViewState.get() diff --git a/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryWrapper.java b/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryWrapper.java index f15e112e8..11e622ef0 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/source/SourceEntryWrapper.java @@ -4,16 +4,16 @@ import io.xpipe.app.comp.source.GuiDsCreatorMultiStep; import io.xpipe.app.comp.storage.StorageFilter; import io.xpipe.app.comp.storage.collection.SourceCollectionViewState; import io.xpipe.app.comp.storage.collection.SourceCollectionWrapper; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.ext.DataStoreProviders; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.StorageElement; import io.xpipe.core.source.DataSource; import io.xpipe.core.store.DataFlow; -import io.xpipe.extension.DataStoreProviders; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.util.ActionProvider; import javafx.beans.property.*; import lombok.Value; @@ -94,7 +94,7 @@ public class SourceEntryWrapper implements StorageFilter.Filterable { ? entry.getInformation() != null ? entry.getInformation() : entry.getProvider().getDisplayName() - : I18n.get("failedToLoad")); + : AppI18n.get("failedToLoad")); loading.setValue(entry.getState() == null || entry.getState() == DataSourceEntry.State.VALIDATING); actionProviders.clear(); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/source/SourceStorageEmptyIntroComp.java b/app/src/main/java/io/xpipe/app/comp/storage/source/SourceStorageEmptyIntroComp.java index 6ab640fd8..767f23d8c 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/source/SourceStorageEmptyIntroComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/source/SourceStorageEmptyIntroComp.java @@ -1,9 +1,9 @@ package io.xpipe.app.comp.storage.source; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.util.Hyperlinks; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; import javafx.geometry.Orientation; import javafx.geometry.Pos; import javafx.scene.control.Hyperlink; @@ -18,30 +18,30 @@ public class SourceStorageEmptyIntroComp extends SimpleComp { @Override public Region createSimple() { - var title = new Label(I18n.get("introTitle")); + var title = new Label(AppI18n.get("introTitle")); AppFont.setSize(title, 7); title.getStyleClass().add("title-header"); var descFi = new FontIcon("mdi2i-information-outline"); - var introDesc = new Label(I18n.get("introDescription")); + var introDesc = new Label(AppI18n.get("introDescription")); introDesc.heightProperty().addListener((c, o, n) -> { descFi.iconSizeProperty().set(n.intValue()); }); var fi = new FontIcon("mdi2f-folder-plus-outline"); - var addCollection = new Label(I18n.get("introCollection"), fi); + var addCollection = new Label(AppI18n.get("introCollection"), fi); addCollection.heightProperty().addListener((c, o, n) -> { fi.iconSizeProperty().set(n.intValue()); }); var pipeFi = new FontIcon("mdi2p-pipe-disconnected"); - var pipe = new Label(I18n.get("introPipe"), pipeFi); + var pipe = new Label(AppI18n.get("introPipe"), pipeFi); pipe.heightProperty().addListener((c, o, n) -> { pipeFi.iconSizeProperty().set(n.intValue()); }); var dfi = new FontIcon("mdi2b-book-open-variant"); - var documentation = new Label(I18n.get("introDocumentation"), dfi); + var documentation = new Label(AppI18n.get("introDocumentation"), dfi); documentation.heightProperty().addListener((c, o, n) -> { dfi.iconSizeProperty().set(n.intValue()); }); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreCreationBarComp.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreCreationBarComp.java index a566d7223..6ec8c7c38 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreCreationBarComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreCreationBarComp.java @@ -3,11 +3,11 @@ package io.xpipe.app.comp.storage.store; import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.source.store.GuiDsStoreCreator; import io.xpipe.app.core.AppFont; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; -import io.xpipe.extension.fxcomps.impl.VerticalComp; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.FancyTooltipAugment; +import io.xpipe.app.fxcomps.impl.VerticalComp; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCombination; @@ -21,28 +21,28 @@ public class StoreCreationBarComp extends SimpleComp { @Override protected Region createSimple() { var newOtherStore = new ButtonComp( - I18n.observable("addOther"), new FontIcon("mdi2c-card-plus-outline"), () -> { + AppI18n.observable("addOther"), new FontIcon("mdi2c-card-plus-outline"), () -> { GuiDsStoreCreator.showCreation(v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.OTHER)); }) .shortcut(new KeyCodeCombination(KeyCode.C, KeyCombination.SHORTCUT_DOWN)) .apply(new FancyTooltipAugment<>("addOther")); var newStreamStore = new ButtonComp( - I18n.observable("addCommand"), new FontIcon("mdi2c-code-greater-than"), () -> { + AppI18n.observable("addCommand"), new FontIcon("mdi2c-code-greater-than"), () -> { GuiDsStoreCreator.showCreation(v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.COMMAND)); }) .shortcut(new KeyCodeCombination(KeyCode.C, KeyCombination.SHORTCUT_DOWN)) .apply(new FancyTooltipAugment<>("addCommand")); var newShellStore = new ButtonComp( - I18n.observable("addHost"), new FontIcon("mdi2h-home-plus-outline"), () -> { + AppI18n.observable("addHost"), new FontIcon("mdi2h-home-plus-outline"), () -> { GuiDsStoreCreator.showCreation(v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.HOST)); }) .shortcut(new KeyCodeCombination(KeyCode.H, KeyCombination.SHORTCUT_DOWN)) .apply(new FancyTooltipAugment<>("addHost")); var newDbStore = new ButtonComp( - I18n.observable("addDatabase"), new FontIcon("mdi2d-database-plus-outline"), () -> { + AppI18n.observable("addDatabase"), new FontIcon("mdi2d-database-plus-outline"), () -> { GuiDsStoreCreator.showCreation(v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.DATABASE)); }) .shortcut(new KeyCodeCombination(KeyCode.D, KeyCombination.SHORTCUT_DOWN)) diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java index 5fdc7704f..76ce62776 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java @@ -5,22 +5,21 @@ import io.xpipe.app.comp.base.LazyTextFieldComp; import io.xpipe.app.comp.base.LoadingOverlayComp; 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.SimpleCompStructure; +import io.xpipe.app.fxcomps.augment.GrowAugment; +import io.xpipe.app.fxcomps.augment.PopupMenuAugment; +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.impl.PrettyImageComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.storage.DataStorage; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.augment.GrowAugment; -import io.xpipe.extension.fxcomps.augment.PopupMenuAugment; -import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; -import io.xpipe.extension.fxcomps.impl.HorizontalComp; -import io.xpipe.extension.fxcomps.impl.IconButtonComp; -import io.xpipe.extension.fxcomps.impl.PrettyImageComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; -import io.xpipe.extension.util.DesktopHelper; -import io.xpipe.extension.util.ThreadHelper; +import io.xpipe.app.util.DesktopHelper; +import io.xpipe.app.util.ThreadHelper; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleStringProperty; import javafx.css.PseudoClass; @@ -255,20 +254,20 @@ public class StoreEntryComp extends SimpleComp { } if (AppPrefs.get().developerMode().getValue()) { - var browse = new MenuItem(I18n.get("browse"), new FontIcon("mdi2f-folder-open-outline")); + var browse = new MenuItem(AppI18n.get("browse"), new FontIcon("mdi2f-folder-open-outline")); browse.setOnAction( event -> DesktopHelper.browsePath(entry.getEntry().getDirectory())); contextMenu.getItems().add(browse); } - var refresh = new MenuItem(I18n.get("refresh"), new FontIcon("mdal-360")); + var refresh = new MenuItem(AppI18n.get("refresh"), new FontIcon("mdal-360")); refresh.disableProperty().bind(entry.getRefreshable().not()); refresh.setOnAction(event -> { DataStorage.get().refreshAsync(entry.getEntry(), true); }); contextMenu.getItems().add(refresh); - var del = new MenuItem(I18n.get("delete"), new FontIcon("mdal-delete_outline")); + var del = new MenuItem(AppI18n.get("delete"), new FontIcon("mdal-delete_outline")); del.disableProperty().bind(entry.getDeletable().not()); del.setOnAction(event -> entry.delete()); contextMenu.getItems().add(del); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListComp.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListComp.java index d25815012..5ab8c253f 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListComp.java @@ -1,10 +1,11 @@ package io.xpipe.app.comp.storage.store; +import atlantafx.base.theme.Styles; import io.xpipe.app.comp.base.ListBoxViewComp; import io.xpipe.app.comp.base.MultiContentComp; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.util.BindingsHelper; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.util.BindingsHelper; import javafx.beans.binding.Bindings; import javafx.beans.value.ObservableBooleanValue; import javafx.scene.layout.Region; @@ -23,7 +24,7 @@ public class StoreEntryListComp extends SimpleComp { var content = new ListBoxViewComp<>(filtered, topLevel, (StoreEntrySection e) -> { return e.comp(true); }); - return content.styleClass("store-list-comp"); + return content.styleClass("store-list-comp").styleClass(Styles.STRIPED); } @Override diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListHeaderComp.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListHeaderComp.java index da7ddad40..a512abed5 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListHeaderComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListHeaderComp.java @@ -2,9 +2,9 @@ package io.xpipe.app.comp.storage.store; import io.xpipe.app.comp.base.CountComp; import io.xpipe.app.core.AppFont; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.FilterComp; -import io.xpipe.extension.util.ThreadHelper; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.FilterComp; +import io.xpipe.app.util.ThreadHelper; import javafx.beans.property.SimpleStringProperty; import javafx.geometry.Pos; import javafx.scene.control.Label; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntrySection.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntrySection.java index c81879242..80aa8e4d5 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntrySection.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntrySection.java @@ -2,11 +2,11 @@ package io.xpipe.app.comp.storage.store; import io.xpipe.app.comp.base.ListBoxViewComp; import io.xpipe.app.comp.storage.StorageFilter; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.augment.GrowAugment; -import io.xpipe.extension.fxcomps.impl.HorizontalComp; -import io.xpipe.extension.fxcomps.impl.VerticalComp; -import io.xpipe.extension.fxcomps.util.BindingsHelper; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.augment.GrowAugment; +import io.xpipe.app.fxcomps.impl.HorizontalComp; +import io.xpipe.app.fxcomps.impl.VerticalComp; +import io.xpipe.app.fxcomps.util.BindingsHelper; import javafx.beans.binding.Bindings; import javafx.collections.FXCollections; import javafx.collections.ObservableList; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryWrapper.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryWrapper.java index f13a32c70..9bdb27085 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryWrapper.java @@ -2,12 +2,12 @@ package io.xpipe.app.comp.storage.store; import io.xpipe.app.comp.source.store.GuiDsStoreCreator; import io.xpipe.app.comp.storage.StorageFilter; +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.util.ActionProvider; import javafx.beans.Observable; import javafx.beans.binding.Bindings; import javafx.beans.property.*; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreLayoutComp.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreLayoutComp.java index bcd2d5203..8c6b8eb98 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreLayoutComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreLayoutComp.java @@ -1,7 +1,7 @@ package io.xpipe.app.comp.storage.store; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.augment.GrowAugment; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.augment.GrowAugment; import javafx.scene.layout.BorderPane; import javafx.scene.layout.Region; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreNotFoundComp.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreNotFoundComp.java index 86224bf1d..c49790af9 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreNotFoundComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreNotFoundComp.java @@ -1,6 +1,6 @@ package io.xpipe.app.comp.storage.store; -import io.xpipe.extension.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.SimpleComp; import javafx.scene.layout.Region; import javafx.scene.layout.StackPane; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSidebarComp.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSidebarComp.java index 6c87da54d..4b30800f6 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSidebarComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSidebarComp.java @@ -1,8 +1,8 @@ package io.xpipe.app.comp.storage.store; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.VerticalComp; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.VerticalComp; import javafx.scene.layout.Priority; import javafx.scene.layout.Region; import javafx.scene.layout.VBox; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreStorageEmptyIntroComp.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreStorageEmptyIntroComp.java index 7164ba768..013b4f435 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreStorageEmptyIntroComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreStorageEmptyIntroComp.java @@ -1,9 +1,9 @@ package io.xpipe.app.comp.storage.store; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.util.Hyperlinks; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; import javafx.geometry.Orientation; import javafx.geometry.Pos; import javafx.scene.control.Hyperlink; @@ -18,36 +18,36 @@ public class StoreStorageEmptyIntroComp extends SimpleComp { @Override public Region createSimple() { - var title = new Label(I18n.get("storeIntroTitle")); + var title = new Label(AppI18n.get("storeIntroTitle")); AppFont.setSize(title, 7); title.getStyleClass().add("title-header"); var descFi = new FontIcon("mdi2i-information-outline"); - var introDesc = new Label(I18n.get("storeIntroDescription")); + var introDesc = new Label(AppI18n.get("storeIntroDescription")); introDesc.heightProperty().addListener((c, o, n) -> { descFi.iconSizeProperty().set(n.intValue()); }); var mfi = new FontIcon("mdi2h-home-plus-outline"); - var machine = new Label(I18n.get("storeMachineDescription"), mfi); + var machine = new Label(AppI18n.get("storeMachineDescription"), mfi); machine.heightProperty().addListener((c, o, n) -> { mfi.iconSizeProperty().set(n.intValue()); }); var dfi = new FontIcon("mdi2d-database-plus-outline"); - var database = new Label(I18n.get("storeDatabaseDescription"), dfi); + var database = new Label(AppI18n.get("storeDatabaseDescription"), dfi); database.heightProperty().addListener((c, o, n) -> { dfi.iconSizeProperty().set(n.intValue()); }); var fi = new FontIcon("mdi2c-card-plus-outline"); - var stream = new Label(I18n.get("storeStreamDescription"), fi); + var stream = new Label(AppI18n.get("storeStreamDescription"), fi); stream.heightProperty().addListener((c, o, n) -> { fi.iconSizeProperty().set(n.intValue()); }); var dofi = new FontIcon("mdi2b-book-open-variant"); - var documentation = new Label(I18n.get("introDocumentation"), dofi); + var documentation = new Label(AppI18n.get("introDocumentation"), dofi); documentation.heightProperty().addListener((c, o, n) -> { dofi.iconSizeProperty().set(n.intValue()); }); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreViewState.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreViewState.java index 341db0c46..6d4ff20f5 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreViewState.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreViewState.java @@ -1,12 +1,12 @@ package io.xpipe.app.comp.storage.store; import io.xpipe.app.comp.storage.StorageFilter; +import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.StorageListener; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.util.BindingsHelper; import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleObjectProperty; 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 04247f9f0..03ff47787 100644 --- a/app/src/main/java/io/xpipe/app/core/App.java +++ b/app/src/main/java/io/xpipe/app/core/App.java @@ -2,10 +2,10 @@ package io.xpipe.app.core; import io.xpipe.app.Main; import io.xpipe.app.comp.AppLayoutComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.core.process.OsType; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.fxcomps.util.PlatformThread; import javafx.application.Application; import javafx.application.Platform; import javafx.scene.image.Image; diff --git a/app/src/main/java/io/xpipe/app/core/AppActionLinkDetector.java b/app/src/main/java/io/xpipe/app/core/AppActionLinkDetector.java index 82af54a4e..fe6480274 100644 --- a/app/src/main/java/io/xpipe/app/core/AppActionLinkDetector.java +++ b/app/src/main/java/io/xpipe/app/core/AppActionLinkDetector.java @@ -1,7 +1,6 @@ package io.xpipe.app.core; import io.xpipe.app.launcher.LauncherInput; -import io.xpipe.extension.I18n; import javafx.scene.control.Alert; import javafx.scene.input.Clipboard; import javafx.scene.input.DataFormat; @@ -63,10 +62,10 @@ public class AppActionLinkDetector { private static boolean showAlert() { var paste = AppWindowHelper.showBlockingAlert(alert -> { alert.setAlertType(Alert.AlertType.CONFIRMATION); - alert.setTitle(I18n.get("clipboardActionDetectedTitle")); - alert.setHeaderText(I18n.get("clipboardActionDetectedHeader")); + alert.setTitle(AppI18n.get("clipboardActionDetectedTitle")); + alert.setHeaderText(AppI18n.get("clipboardActionDetectedHeader")); alert.getDialogPane() - .setContent(AppWindowHelper.alertContentText(I18n.get("clipboardActionDetectedContent"))); + .setContent(AppWindowHelper.alertContentText(AppI18n.get("clipboardActionDetectedContent"))); }) .map(buttonType -> buttonType.getButtonData().isDefaultButton()) .orElse(false); 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 edc000c60..adf19d3cc 100644 --- a/app/src/main/java/io/xpipe/app/core/AppCache.java +++ b/app/src/main/java/io/xpipe/app/core/AppCache.java @@ -1,18 +1,22 @@ package io.xpipe.app.core; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.util.JsonConfigHelper; import io.xpipe.core.util.JacksonMapper; -import io.xpipe.extension.Cache; -import io.xpipe.extension.event.ErrorEvent; import org.apache.commons.io.FileUtils; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Optional; import java.util.UUID; import java.util.function.Supplier; -public class AppCache implements Cache { +public class AppCache { + + public static Optional getIfPresent(String key, Class type) { + return Optional.ofNullable(get(key, type, () -> null)); + } public static UUID getCachedUserId() { var id = get("userId", UUID.class, UUID::randomUUID); @@ -78,12 +82,10 @@ public class AppCache implements Cache { } } - @Override public T getValue(String key, Class type, Supplier notPresent) { return get(key, type, notPresent); } - @Override public void updateValue(String key, T val) { update(key, val); } diff --git a/app/src/main/java/io/xpipe/app/core/AppChecks.java b/app/src/main/java/io/xpipe/app/core/AppChecks.java index 2368b4f8c..b26c0ce64 100644 --- a/app/src/main/java/io/xpipe/app/core/AppChecks.java +++ b/app/src/main/java/io/xpipe/app/core/AppChecks.java @@ -1,6 +1,6 @@ package io.xpipe.app.core; -import io.xpipe.extension.event.ErrorEvent; +import io.xpipe.app.issue.ErrorEvent; import java.io.IOException; import java.nio.file.Files; 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 c47e9440c..9722911ca 100644 --- a/app/src/main/java/io/xpipe/app/core/AppExtensionManager.java +++ b/app/src/main/java/io/xpipe/app/core/AppExtensionManager.java @@ -1,12 +1,12 @@ package io.xpipe.app.core; import io.xpipe.app.exchange.MessageExchangeImpls; +import io.xpipe.app.ext.ModuleInstall; +import io.xpipe.app.ext.XPipeServiceProviders; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.core.util.ModuleHelper; import io.xpipe.core.util.XPipeInstallation; -import io.xpipe.extension.ModuleInstall; -import io.xpipe.extension.XPipeServiceProviders; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; import lombok.Value; import java.io.IOException; @@ -23,7 +23,9 @@ public class AppExtensionManager { private static AppExtensionManager INSTANCE; private final List loadedExtensions = new ArrayList<>(); - private ModuleLayer baseLayer; + private final List leafModuleLayers = new ArrayList<>(); + private final List extensionBaseDirectories = new ArrayList<>(); + private ModuleLayer baseLayer = ModuleLayer.boot(); private ModuleLayer extendedLayer; public static void init() throws Exception { @@ -32,35 +34,54 @@ public class AppExtensionManager { } INSTANCE = new AppExtensionManager(); - INSTANCE.load(); + INSTANCE.determineExtensionDirectories(); + INSTANCE.loadBasicExtension(); + INSTANCE.loadExtensions(); + INSTANCE.loadContent(); } - public static void initBare() { + private void loadBasicExtension() { + var baseModule = loadExtension("base", ModuleLayer.boot()); + if (baseModule.isEmpty()) { + throw new IllegalStateException("Missing base module"); + } + + baseLayer = baseModule.get().getModule().getLayer(); + loadedExtensions.add(baseModule.get()); + } + + public static ModuleLayer initBare() { if (INSTANCE != null) { - return; + return INSTANCE.extendedLayer; } INSTANCE = new AppExtensionManager(); - INSTANCE.extendedLayer = ModuleLayer.boot(); + INSTANCE.determineExtensionDirectories(); + INSTANCE.loadBasicExtension(); + var proc = INSTANCE.loadExtension("proc", INSTANCE.baseLayer).orElseThrow(); + var procx = INSTANCE.loadExtension("procx", proc.getModule().getLayer()).orElseThrow(); + INSTANCE.leafModuleLayers.add(procx.getModule().getLayer()); + INSTANCE.extendedLayer = procx.getModule().getLayer(); + return INSTANCE.extendedLayer; } - public static ModuleLayer loadOnlyBundledExtension(String name) { - INSTANCE = new AppExtensionManager(); - INSTANCE.baseLayer = INSTANCE.loadBundledExtension("base"); - return INSTANCE.loadBundledExtension(name); - } + private void determineExtensionDirectories() { + if (!AppProperties.get().isImage()) { + extensionBaseDirectories.add(Path.of(System.getProperty("user.dir")).resolve("app").resolve("build").resolve("ext_dev")); + } - public ModuleLayer loadBundledExtension(String name) { - var productionRoot = XPipeInstallation.getLocalExtensionsDirectory(); - var userDir = AppProperties.get().isImage() - ? productionRoot.resolve(name) - : Path.of(System.getProperty("user.dir")) - .resolve("ext") - .resolve(name) - .resolve("build") - .resolve("libs_dev"); - var layer = loadDirectory(userDir); - return layer.size() > 0 ? layer.get(0) : null; + if (!AppProperties.get().isFullVersion()) { + var localInstallation = XPipeInstallation.getLocalDefaultInstallationBasePath(true); + var extensions = XPipeInstallation.getLocalExtensionsDirectory(Path.of(localInstallation)); + extensionBaseDirectories.add(extensions); + } + + var userDir = AppProperties.get().getDataDir().resolve("extensions"); + extensionBaseDirectories.add(userDir); + + var currentInstallation = XPipeInstallation.getCurrentInstallationBasePath(); + var productionRoot = XPipeInstallation.getLocalExtensionsDirectory(currentInstallation); + extensionBaseDirectories.add(productionRoot); } public static void reset() { @@ -73,11 +94,7 @@ public class AppExtensionManager { public Set getContentModules() { return Stream.concat( - Stream.of( - ModuleLayer.boot().findModule("io.xpipe.app").orElseThrow(), - ModuleLayer.boot() - .findModule("io.xpipe.extension") - .orElseThrow()), + Stream.of(ModuleLayer.boot().findModule("io.xpipe.app").orElseThrow()), loadedExtensions.stream().map(extension -> extension.module)) .collect(Collectors.toSet()); } @@ -109,25 +126,81 @@ public class AppExtensionManager { return ext != null ? base.resolve(ext) : base; } - private List loadDirectory(Path dir) { - if (!Files.exists(dir) || !Files.isDirectory(dir)) { - return List.of(); + private void loadExtensions() throws IOException { + for (Path extensionBaseDirectory : extensionBaseDirectories) { + loadExtensionBaseDirectory(extensionBaseDirectory); } - if (loadedExtensions.stream().anyMatch(extension -> extension.dir.equals(dir))) { - return List.of(); + if (leafModuleLayers.size() > 0) { + var scl = ClassLoader.getSystemClassLoader(); + var cfs = leafModuleLayers.stream().map(ModuleLayer::configuration).toList(); + var finder = ModuleFinder.ofSystem(); + var cf = Configuration.resolve(finder, cfs, finder, List.of()); + extendedLayer = ModuleLayer.defineModulesWithOneLoader(cf, leafModuleLayers, scl) + .layer(); + } else { + extendedLayer = baseLayer; + } + } + + private void loadContent() throws IOException { + addNativeLibrariesToPath(); + XPipeServiceProviders.load(extendedLayer); + MessageExchangeImpls.loadAll(); + } + + private void loadExtensionBaseDirectory(Path dir) { + if (!Files.exists(dir)) { + return; } - var layers = new ArrayList(); try (var s = Files.list(dir)) { s.forEach(sub -> { if (Files.isDirectory(sub)) { - layers.addAll(loadDirectory(sub)); + var extension = loadExtensionDirectory(sub, baseLayer); + if (extension.isEmpty()) { + return; + } + loadedExtensions.add(extension.get()); + + var xModule = loadExtension( + extension.get().getId() + "x", + extension.get().getModule().getLayer()); + if (xModule.isPresent()) { + loadedExtensions.add(xModule.get()); + leafModuleLayers.add(xModule.get().getModule().getLayer()); + } else { + leafModuleLayers.add(extension.get().getModule().getLayer()); + } } }); } catch (IOException ex) { ErrorEvent.fromThrowable(ex).handle(); } + } + + private Optional loadExtension(String name, ModuleLayer parent) { + for (Path extensionBaseDirectory : extensionBaseDirectories) { + var found = loadExtensionDirectory(extensionBaseDirectory.resolve(name), parent); + if (found.isPresent()) { + return found; + } + } + + return Optional.empty(); + } + + private Optional loadExtensionDirectory(Path dir, ModuleLayer parent) { + if (!Files.exists(dir) || !Files.isDirectory(dir)) { + return Optional.empty(); + } + + if (loadedExtensions.stream().anyMatch(extension -> extension.dir.equals(dir)) + || loadedExtensions.stream() + .anyMatch(extension -> + extension.id.equals(dir.getFileName().toString()))) { + return Optional.empty(); + } TrackEvent.trace(String.format("Scanning directory %s for extensions", dir)); @@ -139,7 +212,6 @@ public class AppExtensionManager { TrackEvent.withTrace("Found modules").elements(found).handle(); if (hasModules) { - ModuleLayer parent = baseLayer != null ? baseLayer : ModuleLayer.boot(); Configuration cf = parent.configuration() .resolve( finder, @@ -155,28 +227,22 @@ public class AppExtensionManager { .tag("dir", dir.toString()) .handle(); } else { + if (loadedExtensions.stream() + .anyMatch(extension -> extension.getName().equals(ext.get().name))) { + return Optional.empty(); + } + ext.get().getModule().getPackages().forEach(pkg -> { ModuleHelper.exportAndOpen(pkg, ext.get().getModule()); }); - layers.add(layer); - loadedExtensions.add(ext.get()); - TrackEvent.withInfo("Loaded extension module") .tag("name", ext.get().getName()) .tag("dir", dir.toString()) .tag("dependencies", ext.get().getDependencies()) .handle(); - var gen = getGeneratedModulesDirectory(ext.get().getModule().getName(), null); - if (Files.exists(gen)) { - var genLayer = loadGenerated(layer, gen); - layers.add(genLayer); - - TrackEvent.withTrace("Found generated modules") - .elements(genLayer.modules()) - .handle(); - } + return Optional.of(ext.get()); } } } catch (Throwable t) { @@ -184,8 +250,7 @@ public class AppExtensionManager { .description("Unable to load extension " + dir.getFileName().toString()) .handle(); } - - return layers; + return Optional.empty(); } private ModuleLayer loadGenerated(ModuleLayer parent, Path dir) throws IOException { @@ -218,7 +283,7 @@ public class AppExtensionManager { } var name = props.get("name").toString(); var deps = l.modules().size() - 1; - ext.set(new Extension(dir, name, m, deps)); + ext.set(new Extension(dir, dir.getFileName().toString(),name, m, deps)); } }); return Optional.ofNullable(ext.get()); @@ -227,42 +292,6 @@ public class AppExtensionManager { .findFirst(); } - private void load() throws IOException { - baseLayer = loadBundledExtension("base"); - - var ep = new ArrayList<>(AppProperties.get().getExtensionPaths()); - List extended = new ArrayList<>(); - for (var p : ep) { - extended.addAll(loadDirectory(p)); - } - - var userDir = AppProperties.get().getDataDir().resolve("extensions"); - var userExtensions = loadDirectory(userDir); - extended.addAll(userExtensions); - - if (AppProperties.get().isImage()) { - var bundledDir = XPipeInstallation.getLocalExtensionsDirectory(); - var bundledExtensions = loadDirectory(bundledDir); - extended.addAll(bundledExtensions); - } - - if (extended.size() > 0) { - var scl = ClassLoader.getSystemClassLoader(); - var cfs = extended.stream().map(ModuleLayer::configuration).toList(); - var finder = ModuleFinder.ofSystem(); - var cf = Configuration.resolve(finder, cfs, finder, List.of()); - extendedLayer = - ModuleLayer.defineModulesWithOneLoader(cf, extended, scl).layer(); - } else { - extendedLayer = baseLayer; - } - - addNativeLibrariesToPath(); - - XPipeServiceProviders.load(extendedLayer); - MessageExchangeImpls.loadAll(); - } - private void addNativeLibrariesToPath() throws IOException { var libsDir = AppProperties.get().isImage() ? XPipeInstallation.getLocalDynamicLibraryDirectory() : Path.of("lib"); @@ -297,6 +326,7 @@ public class AppExtensionManager { @Value private static class Extension { Path dir; + String id; String name; Module module; int dependencies; diff --git a/app/src/main/java/io/xpipe/app/core/AppFont.java b/app/src/main/java/io/xpipe/app/core/AppFont.java index 46645decd..b6dc44e0e 100644 --- a/app/src/main/java/io/xpipe/app/core/AppFont.java +++ b/app/src/main/java/io/xpipe/app/core/AppFont.java @@ -1,7 +1,7 @@ package io.xpipe.app.core; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; -import io.xpipe.extension.event.TrackEvent; import javafx.css.Size; import javafx.css.SizeUnits; import javafx.scene.Node; 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 7778bea35..ba6ac798d 100644 --- a/app/src/main/java/io/xpipe/app/core/AppGreetings.java +++ b/app/src/main/java/io/xpipe/app/core/AppGreetings.java @@ -3,8 +3,7 @@ package io.xpipe.app.core; import com.jfoenix.controls.JFXCheckBox; import io.xpipe.app.comp.base.MarkdownComp; import io.xpipe.app.core.mode.OperationMode; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; +import io.xpipe.app.fxcomps.Comp; import javafx.beans.property.SimpleBooleanProperty; import javafx.geometry.Insets; import javafx.geometry.Pos; @@ -21,7 +20,7 @@ public class AppGreetings { public static TitledPane createIntroduction() { var tp = new TitledPane(); tp.setExpanded(true); - tp.setText(I18n.get("introduction")); + tp.setText(AppI18n.get("introduction")); tp.setAlignment(Pos.CENTER_LEFT); AppFont.normal(tp); @@ -37,7 +36,7 @@ public class AppGreetings { private static TitledPane createPrivacyPolicy() { var tp = new TitledPane(); tp.setExpanded(false); - tp.setText(I18n.get("privacyPolicy")); + tp.setText(AppI18n.get("privacyPolicy")); tp.setAlignment(Pos.CENTER_LEFT); AppFont.normal(tp); @@ -53,7 +52,7 @@ public class AppGreetings { private static TitledPane createEULA() { var tp = new TitledPane(); tp.setExpanded(false); - tp.setText(I18n.get("eula")); + tp.setText(AppI18n.get("eula")); tp.setAlignment(Pos.CENTER_LEFT); AppFont.normal(tp); @@ -74,7 +73,7 @@ public class AppGreetings { var accepted = new SimpleBooleanProperty(); AppWindowHelper.showAlert( alert -> { - alert.setTitle(I18n.get("greetingsAlertTitle")); + alert.setTitle(AppI18n.get("greetingsAlertTitle")); alert.setAlertType(Alert.AlertType.NONE); alert.initModality(Modality.APPLICATION_MODAL); @@ -86,7 +85,7 @@ public class AppGreetings { var cb = new JFXCheckBox(); cb.selectedProperty().bindBidirectional(accepted); - var label = new Label(I18n.get("legalAccept")); + var label = new Label(AppI18n.get("legalAccept")); label.setGraphic(cb); AppFont.medium(label); label.setPadding(new Insets(40, 0, 10, 0)); @@ -101,7 +100,7 @@ public class AppGreetings { alert.getDialogPane().setContent(layout); - var buttonType = new ButtonType(I18n.get("confirm"), ButtonBar.ButtonData.OK_DONE); + var buttonType = new ButtonType(AppI18n.get("confirm"), ButtonBar.ButtonData.OK_DONE); alert.getButtonTypes().add(buttonType); var button = alert.getDialogPane().lookupButton(buttonType); button.disableProperty().bind(accepted.not()); diff --git a/app/src/main/java/io/xpipe/app/core/AppI18n.java b/app/src/main/java/io/xpipe/app/core/AppI18n.java index d5aefb4a4..331293b77 100644 --- a/app/src/main/java/io/xpipe/app/core/AppI18n.java +++ b/app/src/main/java/io/xpipe/app/core/AppI18n.java @@ -1,15 +1,14 @@ package io.xpipe.app.core; +import io.xpipe.app.ext.PrefsChoiceValue; +import io.xpipe.app.fxcomps.impl.FancyTooltipAugment; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.SupportedLocale; +import io.xpipe.app.util.DynamicOptionsBuilder; +import io.xpipe.app.util.Translatable; import io.xpipe.core.util.ModuleHelper; -import io.xpipe.extension.I18n; -import io.xpipe.extension.Translatable; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; -import io.xpipe.extension.prefs.PrefsChoiceValue; -import io.xpipe.extension.util.DynamicOptionsBuilder; import javafx.beans.binding.Bindings; import javafx.beans.binding.StringBinding; import javafx.beans.value.ObservableValue; @@ -33,14 +32,15 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.UnaryOperator; import java.util.regex.Pattern; -public class AppI18n implements I18n { +public class AppI18n { private static final Pattern VAR_PATTERN = Pattern.compile("\\$\\w+?\\$"); private Map translations; private PrettyTime prettyTime; +private static AppI18n INSTANCE = new AppI18n(); public static void init() { - var i = (AppI18n) INSTANCE; + var i = INSTANCE; if (i.translations != null) { return; } @@ -55,12 +55,12 @@ public class AppI18n implements I18n { } } - public static AppI18n get() { + public static AppI18n getInstance() { return ((AppI18n) INSTANCE); } public static StringBinding readableDuration(String s, ObservableValue instant) { - return readableDuration(instant, rs -> getValue(get().getLocalised(s), rs)); + return readableDuration(instant, rs -> getValue(getInstance().getLocalised(s), rs)); } public static StringBinding readableDuration(ObservableValue instant, UnaryOperator op) { @@ -70,11 +70,26 @@ public class AppI18n implements I18n { return "null"; } - return op.apply(get().prettyTime.format(instant.getValue().minus(Duration.ofSeconds(1)))); + return op.apply(getInstance().prettyTime.format(instant.getValue().minus(Duration.ofSeconds(1)))); }, instant); } + public static ObservableValue observable(String s, Object... vars) { + if (s == null) { + return null; + } + + var key = INSTANCE.getKey(s); + return Bindings.createStringBinding(() -> { + return get(key, vars); + }); + } + + public static String get(String s, Object... vars) { + return INSTANCE.getLocalised(s, vars); + } + private static String getValue(String s, Object... vars) { Objects.requireNonNull(s); @@ -113,7 +128,6 @@ public class AppI18n implements I18n { if (caller.equals(CallingClass.class) || caller.equals(ModuleHelper.class) || caller.equals(AppI18n.class) - || caller.equals(I18n.class) || caller.equals(FancyTooltipAugment.class) || caller.equals(PrefsChoiceValue.class) || caller.equals(Translatable.class) @@ -126,7 +140,6 @@ public class AppI18n implements I18n { return ""; } - @Override public String getKey(String s) { var key = s; if (!s.contains(".")) { @@ -161,7 +174,6 @@ public class AppI18n implements I18n { return getValue(localisedString, vars); } - @Override public boolean isLoaded() { return translations != null; } diff --git a/app/src/main/java/io/xpipe/app/core/AppImages.java b/app/src/main/java/io/xpipe/app/core/AppImages.java index 83b3c8fd3..60619287a 100644 --- a/app/src/main/java/io/xpipe/app/core/AppImages.java +++ b/app/src/main/java/io/xpipe/app/core/AppImages.java @@ -1,7 +1,7 @@ package io.xpipe.app.core; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import javafx.scene.image.Image; import javafx.scene.image.WritableImage; import org.apache.commons.io.FilenameUtils; @@ -35,17 +35,16 @@ public class AppImages { Files.walkFileTree(basePath, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + var relativeFileName = FilenameUtils.separatorsToUnix(basePath.relativize(file).toString()); try { if (FilenameUtils.getExtension(file.toString()).equals("svg")) { var s = Files.readString(file); svgImages.put( - defaultPrefix - + basePath.relativize(file).toString(), + defaultPrefix + relativeFileName, s); } else { images.put( - defaultPrefix - + basePath.relativize(file).toString(), + defaultPrefix + relativeFileName, loadImage(file)); } } catch (IOException ex) { @@ -69,10 +68,28 @@ public class AppImages { return svgImages.get(key); } - TrackEvent.warn("Image " + key + " not found"); + TrackEvent.warn("Svg image " + key + " not found"); return ""; } + public static boolean hasNormalImage(String file) { + if (file == null) { + return false; + } + + var key = file.contains(":") ? file : "app:" + file; + return images.containsKey(key); + } + + public static boolean hasSvgImage(String file) { + if (file == null) { + return false; + } + + var key = file.contains(":") ? file : "app:" + file; + return svgImages.containsKey(key); + } + public static Image image(String file) { if (file == null) { return DEFAULT_IMAGE; @@ -84,7 +101,7 @@ public class AppImages { return images.get(key); } - TrackEvent.warn("Image " + key + " not found"); + TrackEvent.warn("Normal image " + key + " not found"); return DEFAULT_IMAGE; } diff --git a/app/src/main/java/io/xpipe/app/core/AppLock.java b/app/src/main/java/io/xpipe/app/core/AppLock.java index bd75abdfa..af89f3aa8 100644 --- a/app/src/main/java/io/xpipe/app/core/AppLock.java +++ b/app/src/main/java/io/xpipe/app/core/AppLock.java @@ -1,6 +1,6 @@ package io.xpipe.app.core; -import io.xpipe.extension.event.ErrorEvent; +import io.xpipe.app.issue.ErrorEvent; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; diff --git a/app/src/main/java/io/xpipe/app/core/AppLogs.java b/app/src/main/java/io/xpipe/app/core/AppLogs.java index 5ddb15596..3ba589961 100644 --- a/app/src/main/java/io/xpipe/app/core/AppLogs.java +++ b/app/src/main/java/io/xpipe/app/core/AppLogs.java @@ -1,9 +1,9 @@ package io.xpipe.app.core; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.core.util.Deobfuscator; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; import lombok.Getter; import org.apache.commons.io.FilenameUtils; import org.slf4j.ILoggerFactory; 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 6f5c16513..172ac6c74 100644 --- a/app/src/main/java/io/xpipe/app/core/AppMainWindow.java +++ b/app/src/main/java/io/xpipe/app/core/AppMainWindow.java @@ -1,10 +1,10 @@ package io.xpipe.app.core; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.CloseBehaviourAlert; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.util.ThreadHelper; +import io.xpipe.app.util.ThreadHelper; import javafx.application.ConditionalFeature; import javafx.application.Platform; import javafx.beans.property.BooleanProperty; diff --git a/app/src/main/java/io/xpipe/app/core/AppProperties.java b/app/src/main/java/io/xpipe/app/core/AppProperties.java index b2e3bc7f2..ebf907f05 100644 --- a/app/src/main/java/io/xpipe/app/core/AppProperties.java +++ b/app/src/main/java/io/xpipe/app/core/AppProperties.java @@ -1,12 +1,11 @@ package io.xpipe.app.core; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.core.util.ModuleHelper; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; import lombok.Value; -import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.InvalidPathException; @@ -20,13 +19,13 @@ public class AppProperties { private static final String DATA_DIR_PROP = "io.xpipe.app.dataDir"; private static final String EXTENSION_PATHS_PROP = "io.xpipe.app.extensions"; private static AppProperties INSTANCE; + boolean fullVersion; String version; String build; UUID buildUuid; String sentryUrl; boolean image; Path dataDir; - List extensionPaths; public AppProperties() { image = ModuleHelper.isImage(); @@ -42,14 +41,13 @@ public class AppProperties { } }); + fullVersion = Optional.ofNullable(props.getProperty("io.xpipe.app.fullVersion")).map(Boolean::parseBoolean).orElse(false); version = Optional.ofNullable(props.getProperty("version")).orElse("dev"); build = Optional.ofNullable(props.getProperty("build")).orElse("unknown"); buildUuid = Optional.ofNullable(System.getProperty("io.xpipe.app.buildId")) .map(UUID::fromString) .orElse(UUID.randomUUID()); sentryUrl = System.getProperty("io.xpipe.app.sentryUrl"); - - extensionPaths = parseExtensionPaths(); dataDir = parseDataDir(); } @@ -72,7 +70,7 @@ public class AppProperties { .tag("version", INSTANCE.version) .tag("build", INSTANCE.build) .tag("dataDir", INSTANCE.dataDir) - .tag("extensionPaths", INSTANCE.extensionPaths) + .tag("fullVersion", INSTANCE.fullVersion) .build(); for (var e : System.getProperties().entrySet()) { @@ -105,23 +103,6 @@ public class AppProperties { return Path.of(System.getProperty("user.home"), ".xpipe"); } - private static List parseExtensionPaths() { - if (System.getProperty(EXTENSION_PATHS_PROP) != null) { - return Arrays.stream(System.getProperty(EXTENSION_PATHS_PROP).split(File.pathSeparator)) - .>map(s -> { - try { - return Optional.of(Path.of(s)); - } catch (InvalidPathException ignored) { - return Optional.empty(); - } - }) - .flatMap(Optional::stream) - .toList(); - } - - return List.of(); - } - public Path getDataDir() { return dataDir; } @@ -145,8 +126,4 @@ public class AppProperties { public String getBuild() { return build; } - - public List getExtensionPaths() { - return extensionPaths; - } } 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 8e79c3292..f35376e2b 100644 --- a/app/src/main/java/io/xpipe/app/core/AppResources.java +++ b/app/src/main/java/io/xpipe/app/core/AppResources.java @@ -1,7 +1,7 @@ package io.xpipe.app.core; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.charsetter.Charsetter; -import io.xpipe.extension.event.ErrorEvent; import io.xpipe.modulefs.ModuleFileSystem; import java.io.IOException; 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 3b1fe9836..28fa6a26e 100644 --- a/app/src/main/java/io/xpipe/app/core/AppSocketServer.java +++ b/app/src/main/java/io/xpipe/app/core/AppSocketServer.java @@ -7,14 +7,14 @@ import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; import io.xpipe.app.exchange.MessageExchangeImpls; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.beacon.*; import io.xpipe.beacon.exchange.MessageExchanges; import io.xpipe.beacon.exchange.data.ClientErrorMessage; import io.xpipe.beacon.exchange.data.ServerErrorMessage; import io.xpipe.core.util.Deobfuscator; import io.xpipe.core.util.JacksonMapper; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; import java.io.IOException; import java.io.InputStream; diff --git a/app/src/main/java/io/xpipe/app/core/AppStyle.java b/app/src/main/java/io/xpipe/app/core/AppStyle.java index fdd3154a9..10eb8e2f2 100644 --- a/app/src/main/java/io/xpipe/app/core/AppStyle.java +++ b/app/src/main/java/io/xpipe/app/core/AppStyle.java @@ -4,11 +4,10 @@ import atlantafx.base.theme.NordDark; import atlantafx.base.theme.NordLight; import atlantafx.base.theme.PrimerDark; import atlantafx.base.theme.PrimerLight; +import io.xpipe.app.ext.PrefsChoiceValue; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.prefs.PrefsChoiceValue; import javafx.application.Application; import javafx.scene.Scene; import lombok.AllArgsConstructor; @@ -137,7 +136,7 @@ public class AppStyle { @Override public String toTranslatedString() { - return I18n.get(id + "Theme"); + return theme.getName(); } } } diff --git a/app/src/main/java/io/xpipe/app/core/AppTray.java b/app/src/main/java/io/xpipe/app/core/AppTray.java index b1dbc3bd5..566d6025c 100644 --- a/app/src/main/java/io/xpipe/app/core/AppTray.java +++ b/app/src/main/java/io/xpipe/app/core/AppTray.java @@ -2,9 +2,8 @@ package io.xpipe.app.core; import com.dustinredmond.fxtrayicon.FXTrayIcon; import io.xpipe.app.core.mode.OperationMode; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.ErrorHandler; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; import javafx.application.Platform; import java.awt.*; @@ -23,7 +22,7 @@ public class AppTray { var url = AppResources.getResourceURL(AppResources.XPIPE_MODULE, "img/logo.png"); var builder = new FXTrayIcon.Builder(App.getApp().getStage(), url.orElse(null)) - .menuItem(I18n.get("open"), e -> { + .menuItem(AppI18n.get("open"), e -> { OperationMode.switchToAsync(OperationMode.GUI); }); if (AppProperties.get().isDeveloperMode()) { @@ -41,7 +40,7 @@ public class AppTray { }); } this.icon = builder.separator() - .menuItem(I18n.get("quit"), e -> { + .menuItem(AppI18n.get("quit"), e -> { OperationMode.close(); }) .toolTip("X-Pipe") @@ -92,14 +91,14 @@ public class AppTray { return; } - var title = I18n.get(event.isTerminal() ? "terminalErrorOccured" : "errorOccured"); + var title = AppI18n.get(event.isTerminal() ? "terminalErrorOccured" : "errorOccured"); var desc = event.getDescription(); if (desc == null && event.getThrowable() != null) { var tName = event.getThrowable().getClass().getSimpleName(); - desc = I18n.get("errorTypeOccured", tName); + desc = AppI18n.get("errorTypeOccured", tName); } if (desc == null) { - desc = I18n.get("errorNoDetail"); + desc = AppI18n.get("errorNoDetail"); } String finalDesc = desc; diff --git a/app/src/main/java/io/xpipe/app/core/AppWindowHelper.java b/app/src/main/java/io/xpipe/app/core/AppWindowHelper.java index 43be60e87..b9efd2f81 100644 --- a/app/src/main/java/io/xpipe/app/core/AppWindowHelper.java +++ b/app/src/main/java/io/xpipe/app/core/AppWindowHelper.java @@ -1,9 +1,9 @@ package io.xpipe.app.core; import io.xpipe.app.comp.base.LoadingOverlayComp; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.util.ThreadHelper; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.issue.TrackEvent; +import io.xpipe.app.util.ThreadHelper; import javafx.application.ConditionalFeature; import javafx.application.Platform; import javafx.beans.value.ObservableValue; @@ -19,7 +19,6 @@ import javafx.scene.input.KeyEvent; import javafx.scene.layout.Pane; import javafx.scene.layout.Region; import javafx.scene.layout.StackPane; -import javafx.scene.paint.Paint; import javafx.scene.text.Text; import javafx.stage.Stage; @@ -35,7 +34,6 @@ public class AppWindowHelper { public static Node alertContentText(String s) { var text = new Text(s); text.setWrappingWidth(450); - text.setFill(Paint.valueOf("WHITE")); AppFont.medium(text); return new StackPane(text); } diff --git a/app/src/main/java/io/xpipe/app/core/FileWatchManager.java b/app/src/main/java/io/xpipe/app/core/FileWatchManager.java index f903e1ad3..d3b206446 100644 --- a/app/src/main/java/io/xpipe/app/core/FileWatchManager.java +++ b/app/src/main/java/io/xpipe/app/core/FileWatchManager.java @@ -1,8 +1,8 @@ package io.xpipe.app.core; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.util.ThreadHelper; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; +import io.xpipe.app.util.ThreadHelper; import java.io.IOException; import java.nio.file.*; 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 0af0e4fae..6fec93a8a 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 @@ -5,12 +5,12 @@ import io.xpipe.app.comp.storage.store.StoreViewState; import io.xpipe.app.core.*; import io.xpipe.app.issue.BasicErrorHandler; import io.xpipe.app.issue.ErrorHandler; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.update.AppUpdater; import io.xpipe.app.util.ExternalEditor; import io.xpipe.core.util.JacksonMapper; -import io.xpipe.extension.event.TrackEvent; public class BaseMode extends OperationMode { 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 ae12327e4..9a0d31e31 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 @@ -2,11 +2,11 @@ package io.xpipe.app.core.mode; import io.xpipe.app.core.App; import io.xpipe.app.core.AppGreetings; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.ErrorHandler; import io.xpipe.app.issue.ErrorHandlerComp; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.update.UpdateChangelogAlert; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; import javafx.application.Platform; import java.util.concurrent.CountDownLatch; diff --git a/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java b/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java index f5fae5874..e4522962a 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java @@ -4,14 +4,14 @@ import io.xpipe.app.core.App; import io.xpipe.app.core.AppChecks; import io.xpipe.app.core.AppLogs; import io.xpipe.app.core.AppProperties; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.ErrorHandler; import io.xpipe.app.issue.SentryErrorHandler; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.launcher.LauncherCommand; +import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.util.XPipeDaemonMode; import io.xpipe.core.util.XPipeSession; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.util.ThreadHelper; import org.apache.commons.lang3.function.FailableRunnable; import java.util.ArrayList; 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 0abaa5e54..0d6a6a7a0 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 @@ -3,9 +3,9 @@ package io.xpipe.app.core.mode; import io.xpipe.app.comp.storage.collection.SourceCollectionViewState; import io.xpipe.app.comp.storage.store.StoreViewState; import io.xpipe.app.core.*; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.update.UpdateAvailableAlert; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.util.ThreadHelper; +import io.xpipe.app.util.ThreadHelper; import javafx.application.Application; import javafx.application.Platform; diff --git a/app/src/main/java/io/xpipe/app/core/mode/TrayMode.java b/app/src/main/java/io/xpipe/app/core/mode/TrayMode.java index 9f286b64d..408060a1b 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/TrayMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/TrayMode.java @@ -4,7 +4,7 @@ import com.dustinredmond.fxtrayicon.FXTrayIcon; import io.xpipe.app.core.App; import io.xpipe.app.core.AppTray; import io.xpipe.app.issue.ErrorHandler; -import io.xpipe.extension.event.TrackEvent; +import io.xpipe.app.issue.TrackEvent; public class TrayMode extends PlatformMode { diff --git a/app/src/main/java/io/xpipe/app/exchange/ConvertExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/ConvertExchangeImpl.java index f77206863..3fee35036 100644 --- a/app/src/main/java/io/xpipe/app/exchange/ConvertExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/exchange/ConvertExchangeImpl.java @@ -1,13 +1,13 @@ package io.xpipe.app.exchange; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceProviders; import io.xpipe.app.storage.DataStorage; import io.xpipe.beacon.BeaconHandler; import io.xpipe.beacon.ClientException; import io.xpipe.beacon.exchange.cli.ConvertExchange; import io.xpipe.core.dialog.Dialog; import io.xpipe.core.source.DataSource; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceProviders; public class ConvertExchangeImpl extends ConvertExchange implements MessageExchangeImpl { diff --git a/app/src/main/java/io/xpipe/app/exchange/DialogExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/DialogExchangeImpl.java index f488d00d4..6cb3eb22e 100644 --- a/app/src/main/java/io/xpipe/app/exchange/DialogExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/exchange/DialogExchangeImpl.java @@ -1,10 +1,10 @@ package io.xpipe.app.exchange; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.beacon.BeaconHandler; import io.xpipe.beacon.exchange.cli.DialogExchange; import io.xpipe.core.dialog.Dialog; import io.xpipe.core.dialog.DialogReference; -import io.xpipe.extension.event.TrackEvent; import org.apache.commons.lang3.function.FailableConsumer; import java.util.HashMap; diff --git a/app/src/main/java/io/xpipe/app/exchange/MessageExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/MessageExchangeImpl.java index 13e9b9e31..5a6d7f0da 100644 --- a/app/src/main/java/io/xpipe/app/exchange/MessageExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/exchange/MessageExchangeImpl.java @@ -1,5 +1,7 @@ package io.xpipe.app.exchange; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceProviders; import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataStorage; @@ -16,8 +18,6 @@ import io.xpipe.core.source.DataSourceId; import io.xpipe.core.source.DataSourceReference; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceProviders; import lombok.NonNull; import java.util.Optional; diff --git a/app/src/main/java/io/xpipe/app/exchange/ReadExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/ReadExchangeImpl.java index 52a8784d3..efbb1973b 100644 --- a/app/src/main/java/io/xpipe/app/exchange/ReadExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/exchange/ReadExchangeImpl.java @@ -1,5 +1,7 @@ package io.xpipe.app.exchange; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceProviders; import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataStorage; import io.xpipe.beacon.BeaconHandler; @@ -8,8 +10,6 @@ import io.xpipe.beacon.exchange.ReadExchange; import io.xpipe.core.dialog.Dialog; import io.xpipe.core.dialog.QueryConverter; import io.xpipe.core.source.DataSource; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceProviders; import java.util.UUID; diff --git a/app/src/main/java/io/xpipe/app/exchange/WritePreparationExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/WritePreparationExchangeImpl.java index 34095b2a8..243d19188 100644 --- a/app/src/main/java/io/xpipe/app/exchange/WritePreparationExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/exchange/WritePreparationExchangeImpl.java @@ -1,11 +1,11 @@ package io.xpipe.app.exchange; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceProviders; import io.xpipe.beacon.BeaconHandler; import io.xpipe.beacon.ClientException; import io.xpipe.beacon.exchange.cli.WritePreparationExchange; import io.xpipe.core.source.DataSource; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceProviders; import java.util.HashMap; import java.util.Map; diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/ReadDrainExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/ReadDrainExchangeImpl.java index 0bdbc7117..b217e0f75 100644 --- a/app/src/main/java/io/xpipe/app/exchange/cli/ReadDrainExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/exchange/cli/ReadDrainExchangeImpl.java @@ -3,12 +3,12 @@ package io.xpipe.app.exchange.cli; import io.xpipe.app.exchange.MessageExchangeImpl; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.app.util.ThreadHelper; import io.xpipe.beacon.BeaconHandler; import io.xpipe.beacon.ServerException; import io.xpipe.beacon.exchange.cli.ReadDrainExchange; import io.xpipe.core.impl.SinkDrainStore; import io.xpipe.core.store.StreamDataStore; -import io.xpipe.extension.util.ThreadHelper; import java.io.InputStream; import java.util.Optional; diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/SourceProviderListExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/SourceProviderListExchangeImpl.java index ab1e2ce7e..befa791e9 100644 --- a/app/src/main/java/io/xpipe/app/exchange/cli/SourceProviderListExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/exchange/cli/SourceProviderListExchangeImpl.java @@ -1,11 +1,11 @@ package io.xpipe.app.exchange.cli; import io.xpipe.app.exchange.MessageExchangeImpl; +import io.xpipe.app.ext.DataSourceProviders; import io.xpipe.beacon.BeaconHandler; import io.xpipe.beacon.exchange.cli.SourceProviderListExchange; import io.xpipe.beacon.exchange.data.ProviderEntry; import io.xpipe.core.source.DataSourceType; -import io.xpipe.extension.DataSourceProviders; import java.util.ArrayList; import java.util.LinkedHashMap; diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/StopExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/StopExchangeImpl.java index 89b2fa0ed..20ca353e6 100644 --- a/app/src/main/java/io/xpipe/app/exchange/cli/StopExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/exchange/cli/StopExchangeImpl.java @@ -2,9 +2,9 @@ package io.xpipe.app.exchange.cli; import io.xpipe.app.core.mode.OperationMode; import io.xpipe.app.exchange.MessageExchangeImpl; +import io.xpipe.app.util.ThreadHelper; import io.xpipe.beacon.BeaconHandler; import io.xpipe.beacon.exchange.StopExchange; -import io.xpipe.extension.util.ThreadHelper; public class StopExchangeImpl extends StopExchange implements MessageExchangeImpl { diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/StoreAddExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/StoreAddExchangeImpl.java index f8d518abc..580ba5d41 100644 --- a/app/src/main/java/io/xpipe/app/exchange/cli/StoreAddExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/exchange/cli/StoreAddExchangeImpl.java @@ -2,6 +2,9 @@ package io.xpipe.app.exchange.cli; import io.xpipe.app.exchange.DialogExchangeImpl; import io.xpipe.app.exchange.MessageExchangeImpl; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.DataStoreProviders; +import io.xpipe.app.issue.ExceptionConverter; import io.xpipe.app.storage.DataStorage; import io.xpipe.beacon.BeaconHandler; import io.xpipe.beacon.ClientException; @@ -10,9 +13,6 @@ import io.xpipe.core.dialog.Choice; import io.xpipe.core.dialog.Dialog; import io.xpipe.core.dialog.QueryConverter; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.DataStoreProviders; -import io.xpipe.extension.event.ExceptionConverter; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/StoreProviderListExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/StoreProviderListExchangeImpl.java index 0e967314a..abc70cc52 100644 --- a/app/src/main/java/io/xpipe/app/exchange/cli/StoreProviderListExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/exchange/cli/StoreProviderListExchangeImpl.java @@ -1,11 +1,11 @@ package io.xpipe.app.exchange.cli; import io.xpipe.app.exchange.MessageExchangeImpl; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.DataStoreProviders; import io.xpipe.beacon.BeaconHandler; import io.xpipe.beacon.exchange.cli.StoreProviderListExchange; import io.xpipe.beacon.exchange.data.ProviderEntry; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.DataStoreProviders; import java.util.Arrays; import java.util.stream.Collectors; diff --git a/extension/src/main/java/io/xpipe/extension/util/ActionProvider.java b/app/src/main/java/io/xpipe/app/ext/ActionProvider.java similarity index 96% rename from extension/src/main/java/io/xpipe/extension/util/ActionProvider.java rename to app/src/main/java/io/xpipe/app/ext/ActionProvider.java index d89aa0df3..918261a77 100644 --- a/extension/src/main/java/io/xpipe/extension/util/ActionProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/ActionProvider.java @@ -1,8 +1,9 @@ -package io.xpipe.extension.util; +package io.xpipe.app.ext; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.util.ModuleLayerLoader; import io.xpipe.core.source.DataSource; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.event.ErrorEvent; import javafx.beans.value.ObservableValue; import java.util.ArrayList; diff --git a/extension/src/main/java/io/xpipe/extension/DataSourceProvider.java b/app/src/main/java/io/xpipe/app/ext/DataSourceProvider.java similarity index 93% rename from extension/src/main/java/io/xpipe/extension/DataSourceProvider.java rename to app/src/main/java/io/xpipe/app/ext/DataSourceProvider.java index e29543312..9414b434a 100644 --- a/extension/src/main/java/io/xpipe/extension/DataSourceProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/DataSourceProvider.java @@ -1,6 +1,8 @@ -package io.xpipe.extension; +package io.xpipe.app.ext; +import io.xpipe.app.core.AppI18n; import io.xpipe.core.dialog.Dialog; +import io.xpipe.core.source.CollectionDataSource; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; @@ -12,6 +14,10 @@ import java.util.Map; public interface DataSourceProvider> { + default CollectionDataSource createContainer(T source) { + return null; + } + default void validate() throws Exception { getCategory(); getSourceClass(); @@ -36,7 +42,7 @@ public interface DataSourceProvider> { default void init() throws Exception {} default String i18n(String key) { - return I18n.get(i18nKey(key)); + return AppI18n.get(i18nKey(key)); } default String i18nKey(String key) { diff --git a/extension/src/main/java/io/xpipe/extension/DataSourceProviders.java b/app/src/main/java/io/xpipe/app/ext/DataSourceProviders.java similarity index 91% rename from extension/src/main/java/io/xpipe/extension/DataSourceProviders.java rename to app/src/main/java/io/xpipe/app/ext/DataSourceProviders.java index 650a8863c..d6fee3756 100644 --- a/extension/src/main/java/io/xpipe/extension/DataSourceProviders.java +++ b/app/src/main/java/io/xpipe/app/ext/DataSourceProviders.java @@ -1,9 +1,9 @@ -package io.xpipe.extension; +package io.xpipe.app.ext; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.impl.FileStore; import io.xpipe.core.source.*; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.event.ErrorEvent; import lombok.SneakyThrows; import java.util.Comparator; @@ -142,6 +142,21 @@ public class DataSourceProviders { .collect(Collectors.joining())); } + public static DataSource createDefault(DataStore store) { + if (ALL == null) { + throw new IllegalStateException("Not initialized"); + } + + var preferred = DataSourceProviders.byPreferredStore(store, null); + try { + return preferred.isPresent() + ? preferred.get().createDefaultSource(store).asNeeded() + : null; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + public static Optional> byPreferredStore(DataStore store, DataSourceType type) { if (ALL == null) { throw new IllegalStateException("Not initialized"); diff --git a/extension/src/main/java/io/xpipe/extension/DataSourceTarget.java b/app/src/main/java/io/xpipe/app/ext/DataSourceTarget.java similarity index 94% rename from extension/src/main/java/io/xpipe/extension/DataSourceTarget.java rename to app/src/main/java/io/xpipe/app/ext/DataSourceTarget.java index 0fb91faf1..ad26f67b8 100644 --- a/extension/src/main/java/io/xpipe/extension/DataSourceTarget.java +++ b/app/src/main/java/io/xpipe/app/ext/DataSourceTarget.java @@ -1,9 +1,9 @@ -package io.xpipe.extension; +package io.xpipe.app.ext; +import io.xpipe.app.util.ModuleLayerLoader; +import io.xpipe.app.util.Validator; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceId; -import io.xpipe.extension.util.ModuleLayerLoader; -import io.xpipe.extension.util.Validator; import javafx.beans.value.ObservableValue; import javafx.scene.layout.Region; import lombok.AllArgsConstructor; diff --git a/extension/src/main/java/io/xpipe/extension/DataStoreProvider.java b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java similarity index 88% rename from extension/src/main/java/io/xpipe/extension/DataStoreProvider.java rename to app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java index 73fc351d8..08a5b6652 100644 --- a/extension/src/main/java/io/xpipe/extension/DataStoreProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java @@ -1,8 +1,10 @@ -package io.xpipe.extension; +package io.xpipe.app.ext; +import io.xpipe.app.core.AppI18n; import io.xpipe.core.dialog.Dialog; +import io.xpipe.core.source.CollectionDataSource; import io.xpipe.core.store.DataStore; -import io.xpipe.core.store.FileSystemStore; +import io.xpipe.core.store.FileSystem; import io.xpipe.core.store.ShellStore; import io.xpipe.core.store.StreamDataStore; import io.xpipe.core.util.JacksonizedValue; @@ -12,6 +14,10 @@ import java.util.List; public interface DataStoreProvider { + default CollectionDataSource createAssociatedContainer(DataStore store) { + return null; + } + default ModuleInstall getRequiredAdditionalInstallation() { return null; } @@ -32,7 +38,7 @@ public interface DataStoreProvider { return DataCategory.STREAM; } - if (FileSystemStore.class.isAssignableFrom(c) || ShellStore.class.isAssignableFrom(c)) { + if (FileSystem.class.isAssignableFrom(c) || ShellStore.class.isAssignableFrom(c)) { return DataCategory.SHELL; } @@ -73,7 +79,7 @@ public interface DataStoreProvider { public String toSummaryString(DataStore store, int length); default String i18n(String key) { - return I18n.get(getId() + "." + key); + return AppI18n.get(getId() + "." + key); } default String i18nKey(String key) { diff --git a/extension/src/main/java/io/xpipe/extension/DataStoreProviders.java b/app/src/main/java/io/xpipe/app/ext/DataStoreProviders.java similarity index 97% rename from extension/src/main/java/io/xpipe/extension/DataStoreProviders.java rename to app/src/main/java/io/xpipe/app/ext/DataStoreProviders.java index 830b33e05..22cf3fbb6 100644 --- a/extension/src/main/java/io/xpipe/extension/DataStoreProviders.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreProviders.java @@ -1,7 +1,7 @@ -package io.xpipe.extension; +package io.xpipe.app.ext; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.event.ErrorEvent; import java.util.Comparator; import java.util.List; diff --git a/extension/src/main/java/io/xpipe/extension/DownloadModuleInstall.java b/app/src/main/java/io/xpipe/app/ext/DownloadModuleInstall.java similarity index 95% rename from extension/src/main/java/io/xpipe/extension/DownloadModuleInstall.java rename to app/src/main/java/io/xpipe/app/ext/DownloadModuleInstall.java index 79fc24568..9a9097b66 100644 --- a/extension/src/main/java/io/xpipe/extension/DownloadModuleInstall.java +++ b/app/src/main/java/io/xpipe/app/ext/DownloadModuleInstall.java @@ -1,4 +1,4 @@ -package io.xpipe.extension; +package io.xpipe.app.ext; import lombok.Getter; diff --git a/extension/src/main/java/io/xpipe/extension/ExtensionException.java b/app/src/main/java/io/xpipe/app/ext/ExtensionException.java similarity index 95% rename from extension/src/main/java/io/xpipe/extension/ExtensionException.java rename to app/src/main/java/io/xpipe/app/ext/ExtensionException.java index 2670e8d44..c1fe5abc0 100644 --- a/extension/src/main/java/io/xpipe/extension/ExtensionException.java +++ b/app/src/main/java/io/xpipe/app/ext/ExtensionException.java @@ -1,4 +1,4 @@ -package io.xpipe.extension; +package io.xpipe.app.ext; public class ExtensionException extends RuntimeException { diff --git a/extension/src/main/java/io/xpipe/extension/GuiDialog.java b/app/src/main/java/io/xpipe/app/ext/GuiDialog.java similarity index 63% rename from extension/src/main/java/io/xpipe/extension/GuiDialog.java rename to app/src/main/java/io/xpipe/app/ext/GuiDialog.java index 67648b116..2531e1e11 100644 --- a/extension/src/main/java/io/xpipe/extension/GuiDialog.java +++ b/app/src/main/java/io/xpipe/app/ext/GuiDialog.java @@ -1,8 +1,8 @@ -package io.xpipe.extension; +package io.xpipe.app.ext; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.util.SimpleValidator; -import io.xpipe.extension.util.Validator; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.util.SimpleValidator; +import io.xpipe.app.util.Validator; import lombok.AllArgsConstructor; import lombok.Value; diff --git a/extension/src/main/java/io/xpipe/extension/ModuleInstall.java b/app/src/main/java/io/xpipe/app/ext/ModuleInstall.java similarity index 94% rename from extension/src/main/java/io/xpipe/extension/ModuleInstall.java rename to app/src/main/java/io/xpipe/app/ext/ModuleInstall.java index a6c2a8043..32c1c263d 100644 --- a/extension/src/main/java/io/xpipe/extension/ModuleInstall.java +++ b/app/src/main/java/io/xpipe/app/ext/ModuleInstall.java @@ -1,4 +1,4 @@ -package io.xpipe.extension; +package io.xpipe.app.ext; import lombok.Getter; diff --git a/extension/src/main/java/io/xpipe/extension/prefs/PrefsChoiceValue.java b/app/src/main/java/io/xpipe/app/ext/PrefsChoiceValue.java similarity index 91% rename from extension/src/main/java/io/xpipe/extension/prefs/PrefsChoiceValue.java rename to app/src/main/java/io/xpipe/app/ext/PrefsChoiceValue.java index 261f94a98..20d02e645 100644 --- a/extension/src/main/java/io/xpipe/extension/prefs/PrefsChoiceValue.java +++ b/app/src/main/java/io/xpipe/app/ext/PrefsChoiceValue.java @@ -1,7 +1,7 @@ -package io.xpipe.extension.prefs; +package io.xpipe.app.ext; -import io.xpipe.extension.I18n; -import io.xpipe.extension.Translatable; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.util.Translatable; import lombok.SneakyThrows; import java.util.Arrays; @@ -55,7 +55,7 @@ public interface PrefsChoiceValue extends Translatable { @Override default String toTranslatedString() { - return I18n.get(getId()); + return AppI18n.get(getId()); } String getId(); diff --git a/extension/src/main/java/io/xpipe/extension/prefs/PrefsHandler.java b/app/src/main/java/io/xpipe/app/ext/PrefsHandler.java similarity index 85% rename from extension/src/main/java/io/xpipe/extension/prefs/PrefsHandler.java rename to app/src/main/java/io/xpipe/app/ext/PrefsHandler.java index 34f118b57..d11a82f3a 100644 --- a/extension/src/main/java/io/xpipe/extension/prefs/PrefsHandler.java +++ b/app/src/main/java/io/xpipe/app/ext/PrefsHandler.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.prefs; +package io.xpipe.app.ext; import com.dlsc.preferencesfx.model.Setting; diff --git a/extension/src/main/java/io/xpipe/extension/prefs/PrefsProvider.java b/app/src/main/java/io/xpipe/app/ext/PrefsProvider.java similarity index 94% rename from extension/src/main/java/io/xpipe/extension/prefs/PrefsProvider.java rename to app/src/main/java/io/xpipe/app/ext/PrefsProvider.java index 8beb27159..fdb90810a 100644 --- a/extension/src/main/java/io/xpipe/extension/prefs/PrefsProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/PrefsProvider.java @@ -1,7 +1,7 @@ -package io.xpipe.extension.prefs; +package io.xpipe.app.ext; import com.dlsc.formsfx.model.structure.Field; -import io.xpipe.extension.util.ModuleLayerLoader; +import io.xpipe.app.util.ModuleLayerLoader; import javafx.beans.value.ObservableBooleanValue; import java.util.ServiceLoader; diff --git a/extension/src/main/java/io/xpipe/extension/XPipeServiceProviders.java b/app/src/main/java/io/xpipe/app/ext/XPipeServiceProviders.java similarity index 90% rename from extension/src/main/java/io/xpipe/extension/XPipeServiceProviders.java rename to app/src/main/java/io/xpipe/app/ext/XPipeServiceProviders.java index db124a99f..cbcbed0dc 100644 --- a/extension/src/main/java/io/xpipe/extension/XPipeServiceProviders.java +++ b/app/src/main/java/io/xpipe/app/ext/XPipeServiceProviders.java @@ -1,12 +1,12 @@ -package io.xpipe.extension; +package io.xpipe.app.ext; import com.fasterxml.jackson.databind.jsontype.NamedType; +import io.xpipe.app.issue.TrackEvent; +import io.xpipe.app.util.ModuleLayerLoader; +import io.xpipe.app.util.XPipeDaemon; import io.xpipe.core.process.ProcessControlProvider; import io.xpipe.core.util.JacksonMapper; import io.xpipe.core.util.ProxyFunction; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.util.ModuleLayerLoader; -import io.xpipe.extension.util.XPipeDaemon; public class XPipeServiceProviders { diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/Comp.java b/app/src/main/java/io/xpipe/app/fxcomps/Comp.java similarity index 91% rename from extension/src/main/java/io/xpipe/extension/fxcomps/Comp.java rename to app/src/main/java/io/xpipe/app/fxcomps/Comp.java index d0e206a14..8cd02f293 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/Comp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/Comp.java @@ -1,10 +1,10 @@ -package io.xpipe.extension.fxcomps; +package io.xpipe.app.fxcomps; -import io.xpipe.extension.fxcomps.augment.Augment; -import io.xpipe.extension.fxcomps.augment.GrowAugment; -import io.xpipe.extension.fxcomps.impl.WrapperComp; -import io.xpipe.extension.fxcomps.util.Shortcuts; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.fxcomps.augment.Augment; +import io.xpipe.app.fxcomps.augment.GrowAugment; +import io.xpipe.app.fxcomps.impl.WrapperComp; +import io.xpipe.app.fxcomps.util.Shortcuts; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.value.ObservableValue; import javafx.scene.control.ButtonBase; import javafx.scene.control.Tooltip; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/CompStructure.java b/app/src/main/java/io/xpipe/app/fxcomps/CompStructure.java similarity index 74% rename from extension/src/main/java/io/xpipe/extension/fxcomps/CompStructure.java rename to app/src/main/java/io/xpipe/app/fxcomps/CompStructure.java index 2d8ad2716..0b625f479 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/CompStructure.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/CompStructure.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.fxcomps; +package io.xpipe.app.fxcomps; import javafx.scene.layout.Region; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/README.md b/app/src/main/java/io/xpipe/app/fxcomps/README.md similarity index 100% rename from extension/src/main/java/io/xpipe/extension/fxcomps/README.md rename to app/src/main/java/io/xpipe/app/fxcomps/README.md diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/SimpleComp.java b/app/src/main/java/io/xpipe/app/fxcomps/SimpleComp.java similarity index 88% rename from extension/src/main/java/io/xpipe/extension/fxcomps/SimpleComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/SimpleComp.java index 707df2531..9a3b41371 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/SimpleComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/SimpleComp.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.fxcomps; +package io.xpipe.app.fxcomps; import javafx.scene.layout.Region; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/SimpleCompStructure.java b/app/src/main/java/io/xpipe/app/fxcomps/SimpleCompStructure.java similarity index 88% rename from extension/src/main/java/io/xpipe/extension/fxcomps/SimpleCompStructure.java rename to app/src/main/java/io/xpipe/app/fxcomps/SimpleCompStructure.java index a308690e8..f137a50fe 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/SimpleCompStructure.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/SimpleCompStructure.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.fxcomps; +package io.xpipe.app.fxcomps; import javafx.scene.layout.Region; import lombok.AllArgsConstructor; diff --git a/app/src/main/java/io/xpipe/app/fxcomps/augment/Augment.java b/app/src/main/java/io/xpipe/app/fxcomps/augment/Augment.java new file mode 100644 index 000000000..bd58409a4 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/fxcomps/augment/Augment.java @@ -0,0 +1,8 @@ +package io.xpipe.app.fxcomps.augment; + +import io.xpipe.app.fxcomps.CompStructure; + +public interface Augment> { + + void augment(S struc); +} diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/augment/GrowAugment.java b/app/src/main/java/io/xpipe/app/fxcomps/augment/GrowAugment.java similarity index 95% rename from extension/src/main/java/io/xpipe/extension/fxcomps/augment/GrowAugment.java rename to app/src/main/java/io/xpipe/app/fxcomps/augment/GrowAugment.java index 59cf6e2a4..7cef93eeb 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/augment/GrowAugment.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/augment/GrowAugment.java @@ -1,6 +1,6 @@ -package io.xpipe.extension.fxcomps.augment; +package io.xpipe.app.fxcomps.augment; -import io.xpipe.extension.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.CompStructure; import javafx.beans.binding.Bindings; import javafx.scene.Node; import javafx.scene.layout.Region; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/augment/PopupMenuAugment.java b/app/src/main/java/io/xpipe/app/fxcomps/augment/PopupMenuAugment.java similarity index 90% rename from extension/src/main/java/io/xpipe/extension/fxcomps/augment/PopupMenuAugment.java rename to app/src/main/java/io/xpipe/app/fxcomps/augment/PopupMenuAugment.java index 608121e88..7a8e20643 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/augment/PopupMenuAugment.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/augment/PopupMenuAugment.java @@ -1,6 +1,6 @@ -package io.xpipe.extension.fxcomps.augment; +package io.xpipe.app.fxcomps.augment; -import io.xpipe.extension.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.CompStructure; import javafx.scene.control.ContextMenu; import javafx.scene.input.MouseButton; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/CharChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/CharChoiceComp.java similarity index 88% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/CharChoiceComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/CharChoiceComp.java index b2fa1b529..e2eed12a7 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/CharChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/CharChoiceComp.java @@ -1,8 +1,8 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; import javafx.geometry.Pos; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/CharComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/CharComp.java similarity index 79% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/CharComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/CharComp.java index 1acaa88bb..8c5c89301 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/CharComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/CharComp.java @@ -1,9 +1,9 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.beans.property.Property; import javafx.scene.control.TextField; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/CharsetChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/CharsetChoiceComp.java similarity index 77% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/CharsetChoiceComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/CharsetChoiceComp.java index a2e83604b..2395eb730 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/CharsetChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/CharsetChoiceComp.java @@ -1,9 +1,9 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.util.CustomComboBoxBuilder; import io.xpipe.core.charsetter.StreamCharset; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.util.CustomComboBoxBuilder; import javafx.beans.property.Property; import javafx.scene.control.Label; import javafx.scene.layout.Region; @@ -24,17 +24,17 @@ public class CharsetChoiceComp extends SimpleComp { return new Label(streamCharset.getCharset().displayName() + (streamCharset.hasByteOrderMark() ? " (BOM)" : "")); }, - new Label(I18n.get("extension.none")), + new Label(AppI18n.get("app.none")), null); builder.addFilter((charset, filter) -> { return charset.getCharset().displayName().contains(filter); }); - builder.addHeader(I18n.get("extension.common")); + builder.addHeader(AppI18n.get("app.common")); for (var e : StreamCharset.COMMON) { builder.add(e); } - builder.addHeader(I18n.get("extension.other")); + builder.addHeader(AppI18n.get("app.other")); for (var e : StreamCharset.RARE) { builder.add(e); } diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/ChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/ChoiceComp.java similarity index 84% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/ChoiceComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/ChoiceComp.java index e8c232541..8df53be03 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/ChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/ChoiceComp.java @@ -1,12 +1,12 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.BindingsHelper; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -44,7 +44,7 @@ public class ChoiceComp extends Comp>> { @Override public String toString(T object) { if (object == null) { - return I18n.get("extension.none"); + return AppI18n.get("app.none"); } var found = range.getValue().get(object); diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/ChoicePaneComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/ChoicePaneComp.java similarity index 85% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/ChoicePaneComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/ChoicePaneComp.java index 8b4a592d2..8f31f55cb 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/ChoicePaneComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/ChoicePaneComp.java @@ -1,11 +1,11 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; @@ -36,7 +36,7 @@ public class ChoicePaneComp extends Comp> { @Override public String toString(Entry object) { if (object == null) { - return I18n.get("extension.none"); + return AppI18n.get("app.none"); } return object.name().getValue(); diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/CodeSnippet.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/CodeSnippet.java similarity index 98% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/CodeSnippet.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/CodeSnippet.java index 791e18331..ace9d068a 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/CodeSnippet.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/CodeSnippet.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; import javafx.scene.paint.Color; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/CodeSnippetComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/CodeSnippetComp.java similarity index 95% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/CodeSnippetComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/CodeSnippetComp.java index de333f0a0..7e3a89b3a 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/CodeSnippetComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/CodeSnippetComp.java @@ -1,9 +1,9 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ObservableValue; import javafx.scene.control.Button; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/DataStoreFlowChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreFlowChoiceComp.java similarity index 63% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/DataStoreFlowChoiceComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreFlowChoiceComp.java index 22aef85cb..6568a563c 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/DataStoreFlowChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreFlowChoiceComp.java @@ -1,8 +1,8 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.core.store.DataFlow; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -22,16 +22,16 @@ public class DataStoreFlowChoiceComp extends SimpleComp { @Override protected Region createSimple() { var map = new LinkedHashMap>(); - map.put(DataFlow.INPUT, I18n.observable("extension.input")); - map.put(DataFlow.OUTPUT, I18n.observable("extension.output")); - map.put(DataFlow.INPUT_OUTPUT, I18n.observable("extension.inout")); + map.put(DataFlow.INPUT, AppI18n.observable("app.input")); + map.put(DataFlow.OUTPUT, AppI18n.observable("app.output")); + map.put(DataFlow.INPUT_OUTPUT, AppI18n.observable("app.inout")); return new ToggleGroupComp<>(selected, new SimpleObjectProperty<>(map)) .apply(struc -> { - new FancyTooltipAugment<>("extension.inputDescription") + new FancyTooltipAugment<>("app.inputDescription") .augment(struc.get().getChildren().get(0)); - new FancyTooltipAugment<>("extension.outputDescription") + new FancyTooltipAugment<>("app.outputDescription") .augment(struc.get().getChildren().get(1)); - new FancyTooltipAugment<>("extension.inoutDescription") + new FancyTooltipAugment<>("app.inoutDescription") .augment(struc.get().getChildren().get(2)); }) .createRegion(); diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/DynamicOptionsComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/DynamicOptionsComp.java similarity index 95% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/DynamicOptionsComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/DynamicOptionsComp.java index d2cb96177..d626e686f 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/DynamicOptionsComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/DynamicOptionsComp.java @@ -1,9 +1,9 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.beans.Observable; import javafx.beans.binding.Bindings; import javafx.beans.value.ObservableValue; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/FancyTooltipAugment.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/FancyTooltipAugment.java similarity index 96% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/FancyTooltipAugment.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/FancyTooltipAugment.java index 15413f744..08f8f56d1 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/FancyTooltipAugment.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/FancyTooltipAugment.java @@ -1,11 +1,11 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; import com.jfoenix.controls.JFXTooltip; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.augment.Augment; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.Shortcuts; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.augment.Augment; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.Shortcuts; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.beans.value.ObservableValue; @@ -30,7 +30,7 @@ public class FancyTooltipAugment> implements Augment< } public FancyTooltipAugment(String key) { - this.text = I18n.observable(key); + this.text = AppI18n.observable(key); } @Override diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/FileStoreChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/FileStoreChoiceComp.java similarity index 87% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/FileStoreChoiceComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/FileStoreChoiceComp.java index a6771e1f4..441f6cee3 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/FileStoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/FileStoreChoiceComp.java @@ -1,11 +1,11 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.LocalStore; import io.xpipe.core.store.FileSystemStore; import io.xpipe.core.store.MachineStore; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; import javafx.beans.property.Property; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; @@ -28,8 +28,8 @@ public class FileStoreChoiceComp extends SimpleComp { this.selected = selected; } - private void setSelected(FileSystemStore fileSystemStore, String file) { - selected.setValue(fileSystemStore != null && file != null ? new FileStore(fileSystemStore, file) : null); + private void setSelected(FileSystemStore fileSystem, String file) { + selected.setValue(fileSystem != null && file != null ? new FileStore(fileSystem, file) : null); } @Override @@ -70,8 +70,8 @@ public class FileStoreChoiceComp extends SimpleComp { private FileChooser createChooser() { FileChooser fileChooser = new FileChooser(); - fileChooser.setTitle(I18n.get("browseFileTitle")); - fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(I18n.get("anyFile"), "*")); + fileChooser.setTitle(AppI18n.get("browseFileTitle")); + fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(AppI18n.get("anyFile"), "*")); return fileChooser; } } diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/FileSystemStoreChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/FileSystemStoreChoiceComp.java similarity index 87% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/FileSystemStoreChoiceComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/FileSystemStoreChoiceComp.java index 829bfc8f0..3889c3392 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/FileSystemStoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/FileSystemStoreChoiceComp.java @@ -1,10 +1,10 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; +import io.xpipe.app.ext.DataStoreProviders; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.util.CustomComboBoxBuilder; +import io.xpipe.app.util.XPipeDaemon; import io.xpipe.core.store.FileSystemStore; -import io.xpipe.extension.DataStoreProviders; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.util.CustomComboBoxBuilder; -import io.xpipe.extension.util.XPipeDaemon; import javafx.beans.property.Property; import javafx.beans.property.SimpleStringProperty; import javafx.scene.Node; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/FilterComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/FilterComp.java similarity index 88% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/FilterComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/FilterComp.java index e3a237a40..8ef3215ff 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/FilterComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/FilterComp.java @@ -1,9 +1,9 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.binding.Bindings; import javafx.beans.property.Property; import javafx.scene.Node; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/GrowPaneComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/GrowPaneComp.java similarity index 75% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/GrowPaneComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/GrowPaneComp.java index 27ac8bd9a..97d6c0038 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/GrowPaneComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/GrowPaneComp.java @@ -1,8 +1,8 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import javafx.scene.layout.BorderPane; import javafx.scene.layout.Pane; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/HorizontalComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/HorizontalComp.java similarity index 76% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/HorizontalComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/HorizontalComp.java index 2f31de454..096b79d73 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/HorizontalComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/HorizontalComp.java @@ -1,8 +1,8 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import javafx.geometry.Pos; import javafx.scene.layout.HBox; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/IconButtonComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/IconButtonComp.java similarity index 87% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/IconButtonComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/IconButtonComp.java index 0d66c939a..750a7f159 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/IconButtonComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/IconButtonComp.java @@ -1,10 +1,10 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; import com.jfoenix.controls.JFXButton; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import javafx.css.Size; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/IntFieldComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/IntFieldComp.java similarity index 91% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/IntFieldComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/IntFieldComp.java index 50e22231c..0ee7ff81a 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/IntFieldComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/IntFieldComp.java @@ -1,9 +1,9 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.beans.property.Property; import javafx.beans.value.ChangeListener; import javafx.scene.control.TextField; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/LabelComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/LabelComp.java similarity index 74% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/LabelComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/LabelComp.java index d81ffebea..d1fa6d4a0 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/LabelComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/LabelComp.java @@ -1,9 +1,9 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ObservableValue; import javafx.geometry.Pos; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/PaneComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/PaneComp.java similarity index 74% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/PaneComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/PaneComp.java index 844bbb864..30fe2d467 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/PaneComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/PaneComp.java @@ -1,8 +1,8 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import javafx.scene.layout.Pane; import java.util.List; diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/PrettyImageComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/PrettyImageComp.java new file mode 100644 index 000000000..ed5c56866 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/PrettyImageComp.java @@ -0,0 +1,140 @@ +package io.xpipe.app.fxcomps.impl; + +import io.xpipe.app.core.AppImages; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.util.XPipeDaemon; +import javafx.beans.binding.Bindings; +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ObservableValue; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.image.ImageView; +import javafx.scene.layout.Region; +import javafx.scene.layout.StackPane; +import javafx.scene.web.WebView; + +public class PrettyImageComp extends SimpleComp { + + private final ObservableValue value; + private final double width; + private final double height; + + public PrettyImageComp(ObservableValue value, double width, double height) { + this.value = value; + this.width = width; + this.height = height; + } + + @Override + protected Region createSimple() { + var aspectRatioProperty = new SimpleDoubleProperty(1); + var widthProperty = Bindings.createDoubleBinding( + () -> { + boolean widthLimited = width / height < aspectRatioProperty.doubleValue(); + if (widthLimited) { + return width; + } else { + return height * aspectRatioProperty.doubleValue(); + } + }, + aspectRatioProperty); + var heightProperty = Bindings.createDoubleBinding( + () -> { + boolean widthLimited = width / height < aspectRatioProperty.doubleValue(); + if (widthLimited) { + return width / aspectRatioProperty.doubleValue(); + } else { + return height; + } + }, + aspectRatioProperty); + + var currentNode = new SimpleObjectProperty(); + SimpleChangeListener.apply(PlatformThread.sync(value), val -> { + var requiresChange = value.getValue() == null || (value.getValue().endsWith(".svg") && !(currentNode.get() instanceof WebView) || + !(currentNode.get() instanceof ImageView)); + if (!requiresChange) { + return; + } + + aspectRatioProperty.unbind(); + + if (value.getValue() == null) { + currentNode.set(new Region()); + } + + else if (value.getValue().endsWith(".svg")) { + var storeIcon = SvgComp.create( + Bindings.createStringBinding(() -> { + if (!AppImages.hasSvgImage(value.getValue())) { + return null; + } + + return XPipeDaemon.getInstance().svgImage(value.getValue()); + }, value)); + var ar = Bindings.createDoubleBinding( + () -> { + return storeIcon.getWidth().getValue().doubleValue() + / storeIcon.getHeight().getValue().doubleValue(); + }, + storeIcon.getWidth(), + storeIcon.getHeight()); + aspectRatioProperty.bind(ar); + var node = storeIcon.createWebview(); + ((WebView) node).prefWidthProperty().bind(widthProperty); + ((WebView) node).maxWidthProperty().bind(widthProperty); + ((WebView) node).minWidthProperty().bind(widthProperty); + ((WebView) node).prefHeightProperty().bind(heightProperty); + ((WebView) node).maxHeightProperty().bind(heightProperty); + ((WebView) node).minHeightProperty().bind(heightProperty); + currentNode.set(node); + } else { + var storeIcon = new ImageView(); + storeIcon + .imageProperty() + .bind(Bindings.createObjectBinding( + () -> { + if (!AppImages.hasNormalImage(value.getValue())) { + return null; + } + + return XPipeDaemon.getInstance().image(value.getValue()); + }, + PlatformThread.sync(value))); + var ar = Bindings.createDoubleBinding( + () -> { + if (storeIcon.getImage() == null) { + return 1.0; + } + + return storeIcon.getImage().getWidth() / storeIcon.getImage().getHeight(); + }, + storeIcon.imageProperty()); + aspectRatioProperty.bind(ar); + storeIcon.fitWidthProperty().bind(widthProperty); + storeIcon.fitHeightProperty().bind(heightProperty); + storeIcon.setSmooth(true); + currentNode.set(storeIcon); + } + }); + + var stack = new StackPane(); + SimpleChangeListener.apply(currentNode, val -> { + if (val == null) { + stack.getChildren().clear(); + return; + } + + stack.getChildren().setAll(val); + }); + stack.setPrefWidth(width); + stack.setMinWidth(width); + stack.setPrefHeight(height); + stack.setMinHeight(height); + stack.setAlignment(Pos.CENTER); + return stack; + } +} diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/SecretFieldComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/SecretFieldComp.java similarity index 80% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/SecretFieldComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/SecretFieldComp.java index 1fcbc4ebd..b31aa41e5 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/SecretFieldComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/SecretFieldComp.java @@ -1,10 +1,10 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.core.util.SecretValue; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; import javafx.beans.property.Property; import javafx.scene.control.PasswordField; import javafx.scene.control.TextField; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/ShellStoreChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/ShellStoreChoiceComp.java similarity index 87% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/ShellStoreChoiceComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/ShellStoreChoiceComp.java index 8bb27d26b..35250a282 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/ShellStoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/ShellStoreChoiceComp.java @@ -1,11 +1,11 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataStoreProviders; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.util.CustomComboBoxBuilder; +import io.xpipe.app.util.XPipeDaemon; import io.xpipe.core.store.ShellStore; -import io.xpipe.extension.DataStoreProviders; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.util.CustomComboBoxBuilder; -import io.xpipe.extension.util.XPipeDaemon; import javafx.beans.property.Property; import javafx.beans.property.SimpleStringProperty; import javafx.scene.Node; @@ -57,12 +57,12 @@ public class ShellStoreChoiceComp extends SimpleComp { .findAny() .flatMap(store -> { if (ShellStore.isLocal(store.asNeeded()) && mode == Mode.PROXY_CHOICE) { - return Optional.of(I18n.get("none")); + return Optional.of(AppI18n.get("none")); } return XPipeDaemon.getInstance().getStoreName(store); }) - .orElse(I18n.get("unknown")); + .orElse(AppI18n.get("unknown")); return new Label(name, imgView); } @@ -71,7 +71,7 @@ public class ShellStoreChoiceComp extends SimpleComp { @SuppressWarnings("unchecked") protected Region createSimple() { var comboBox = - new CustomComboBoxBuilder(selected, this::createGraphic, new Label(I18n.get("none")), n -> true); + new CustomComboBoxBuilder(selected, this::createGraphic, new Label(AppI18n.get("none")), n -> true); comboBox.setUnknownNode(t -> createGraphic(t)); var available = XPipeDaemon.getInstance().getNamedStores().stream() diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/StackComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/StackComp.java similarity index 76% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/StackComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/StackComp.java index 32c3c0fea..04c85f832 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/StackComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/StackComp.java @@ -1,8 +1,8 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; import javafx.geometry.Pos; import javafx.scene.layout.StackPane; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/SvgComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/SvgComp.java similarity index 90% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/SvgComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/SvgComp.java index 5044a4d1e..6db2bd83d 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/SvgComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/SvgComp.java @@ -1,8 +1,8 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.value.ObservableValue; @@ -51,9 +51,15 @@ public class SvgComp { var widthProperty = new SimpleIntegerProperty(); var heightProperty = new SimpleIntegerProperty(); SimpleChangeListener.apply(content, val -> { + if (val == null) { + return; + } + var regularExpression = Pattern.compile(" { + if (n == null) { + wv.getEngine().loadContent(""); + return; + } + wv.getEngine().loadContent(getHtml(n)); }); diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/TabPaneComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/TabPaneComp.java similarity index 89% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/TabPaneComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/TabPaneComp.java index bab53d1d8..53bc439a7 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/TabPaneComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/TabPaneComp.java @@ -1,10 +1,10 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; import com.jfoenix.controls.JFXTabPane; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; import javafx.geometry.Pos; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/TextAreaComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/TextAreaComp.java similarity index 92% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/TextAreaComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/TextAreaComp.java index f3c2caa6f..7bb51c670 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/TextAreaComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/TextAreaComp.java @@ -1,8 +1,8 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.binding.Bindings; import javafx.beans.property.Property; import javafx.beans.property.SimpleStringProperty; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/TextFieldComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/TextFieldComp.java similarity index 87% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/TextFieldComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/TextFieldComp.java index 7e34b5f48..ea36804d0 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/TextFieldComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/TextFieldComp.java @@ -1,10 +1,10 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.property.Property; import javafx.beans.property.SimpleStringProperty; import javafx.event.EventHandler; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/ToggleGroupComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/ToggleGroupComp.java similarity index 89% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/ToggleGroupComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/ToggleGroupComp.java index 2452a3e7f..116c0d6ae 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/ToggleGroupComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/ToggleGroupComp.java @@ -1,10 +1,10 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; import javafx.scene.control.ToggleButton; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/VerticalComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/VerticalComp.java similarity index 80% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/VerticalComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/VerticalComp.java index 9c1946360..2a6626ac5 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/VerticalComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/VerticalComp.java @@ -1,9 +1,9 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; -import io.xpipe.extension.fxcomps.SimpleCompStructure; -import io.xpipe.extension.fxcomps.util.PlatformThread; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/WrapperComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/WrapperComp.java similarity index 73% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/WrapperComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/WrapperComp.java index 057ec7936..5c86ef690 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/WrapperComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/WrapperComp.java @@ -1,7 +1,7 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.CompStructure; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.CompStructure; import java.util.function.Supplier; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/WriteModeChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/WriteModeChoiceComp.java similarity index 79% rename from extension/src/main/java/io/xpipe/extension/fxcomps/impl/WriteModeChoiceComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/WriteModeChoiceComp.java index 8940230ad..e8b661b62 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/WriteModeChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/WriteModeChoiceComp.java @@ -1,12 +1,12 @@ -package io.xpipe.extension.fxcomps.impl; +package io.xpipe.app.fxcomps.impl; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.util.SimpleValidator; +import io.xpipe.app.util.Validatable; +import io.xpipe.app.util.Validator; import io.xpipe.core.source.WriteMode; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.util.SimpleValidator; -import io.xpipe.extension.util.Validatable; -import io.xpipe.extension.util.Validator; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -35,7 +35,7 @@ public class WriteModeChoiceComp extends SimpleComp implements Validatable { if (available.size() == 1) { selected.setValue(available.get(0)); } - check = Validator.nonNull(validator, I18n.observable("mode"), selected); + check = Validator.nonNull(validator, AppI18n.observable("mode"), selected); } @Override @@ -44,13 +44,13 @@ public class WriteModeChoiceComp extends SimpleComp implements Validatable { Property>> map = new SimpleObjectProperty<>(new LinkedHashMap>()); for (WriteMode writeMode : a) { - map.getValue().put(writeMode, I18n.observable(writeMode.getId())); + map.getValue().put(writeMode, AppI18n.observable(writeMode.getId())); } PlatformThread.sync(available).addListener((ListChangeListener) c -> { var newMap = new LinkedHashMap>(); for (WriteMode writeMode : c.getList()) { - newMap.put(writeMode, I18n.observable(writeMode.getId())); + newMap.put(writeMode, AppI18n.observable(writeMode.getId())); } map.setValue(newMap); diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/util/BindingsHelper.java b/app/src/main/java/io/xpipe/app/fxcomps/util/BindingsHelper.java similarity index 98% rename from extension/src/main/java/io/xpipe/extension/fxcomps/util/BindingsHelper.java rename to app/src/main/java/io/xpipe/app/fxcomps/util/BindingsHelper.java index ee2a1134e..63861d5cb 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/util/BindingsHelper.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/util/BindingsHelper.java @@ -1,6 +1,6 @@ -package io.xpipe.extension.fxcomps.util; +package io.xpipe.app.fxcomps.util; -import io.xpipe.extension.util.ThreadHelper; +import io.xpipe.app.util.ThreadHelper; import javafx.beans.binding.Binding; import javafx.beans.binding.ListBinding; import javafx.beans.property.Property; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/util/PlatformThread.java b/app/src/main/java/io/xpipe/app/fxcomps/util/PlatformThread.java similarity index 99% rename from extension/src/main/java/io/xpipe/extension/fxcomps/util/PlatformThread.java rename to app/src/main/java/io/xpipe/app/fxcomps/util/PlatformThread.java index e93035813..7f1f13276 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/util/PlatformThread.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/util/PlatformThread.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.fxcomps.util; +package io.xpipe.app.fxcomps.util; import javafx.application.Platform; import javafx.beans.InvalidationListener; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/util/Shortcuts.java b/app/src/main/java/io/xpipe/app/fxcomps/util/Shortcuts.java similarity index 97% rename from extension/src/main/java/io/xpipe/extension/fxcomps/util/Shortcuts.java rename to app/src/main/java/io/xpipe/app/fxcomps/util/Shortcuts.java index ea6d2ce7d..f80ec6b23 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/util/Shortcuts.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/util/Shortcuts.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.fxcomps.util; +package io.xpipe.app.fxcomps.util; import javafx.event.EventHandler; import javafx.scene.Scene; diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/util/SimpleChangeListener.java b/app/src/main/java/io/xpipe/app/fxcomps/util/SimpleChangeListener.java similarity index 91% rename from extension/src/main/java/io/xpipe/extension/fxcomps/util/SimpleChangeListener.java rename to app/src/main/java/io/xpipe/app/fxcomps/util/SimpleChangeListener.java index 4141b0336..48720c16a 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/util/SimpleChangeListener.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/util/SimpleChangeListener.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.fxcomps.util; +package io.xpipe.app.fxcomps.util; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; diff --git a/app/src/main/java/io/xpipe/app/issue/BasicErrorHandler.java b/app/src/main/java/io/xpipe/app/issue/BasicErrorHandler.java index e2e99febf..18e015aae 100644 --- a/app/src/main/java/io/xpipe/app/issue/BasicErrorHandler.java +++ b/app/src/main/java/io/xpipe/app/issue/BasicErrorHandler.java @@ -2,8 +2,6 @@ package io.xpipe.app.issue; import io.xpipe.app.core.AppLogs; import io.xpipe.core.util.Deobfuscator; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; public class BasicErrorHandler implements ErrorHandler { diff --git a/app/src/main/java/io/xpipe/app/issue/ErrorAction.java b/app/src/main/java/io/xpipe/app/issue/ErrorAction.java index 44053d912..4bf7547d1 100644 --- a/app/src/main/java/io/xpipe/app/issue/ErrorAction.java +++ b/app/src/main/java/io/xpipe/app/issue/ErrorAction.java @@ -1,8 +1,7 @@ package io.xpipe.app.issue; import io.sentry.Sentry; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; +import io.xpipe.app.core.AppI18n; public interface ErrorAction { @@ -10,12 +9,12 @@ public interface ErrorAction { return new ErrorAction() { @Override public String getName() { - return I18n.get("reportError"); + return AppI18n.get("reportError"); } @Override public String getDescription() { - return I18n.get("reportErrorDescription"); + return AppI18n.get("reportErrorDescription"); } @Override @@ -30,12 +29,12 @@ public interface ErrorAction { return new ErrorAction() { @Override public String getName() { - return I18n.get("ignoreError"); + return AppI18n.get("ignoreError"); } @Override public String getDescription() { - return I18n.get("ignoreErrorDescription"); + return AppI18n.get("ignoreErrorDescription"); } @Override diff --git a/app/src/main/java/io/xpipe/app/issue/ErrorDetailsComp.java b/app/src/main/java/io/xpipe/app/issue/ErrorDetailsComp.java index 712dd855b..91ab892b9 100644 --- a/app/src/main/java/io/xpipe/app/issue/ErrorDetailsComp.java +++ b/app/src/main/java/io/xpipe/app/issue/ErrorDetailsComp.java @@ -2,12 +2,11 @@ package io.xpipe.app.issue; import io.xpipe.app.comp.base.ListViewComp; 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.impl.TabPaneComp; import io.xpipe.core.util.Deobfuscator; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.impl.TabPaneComp; import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; import javafx.scene.control.Label; @@ -61,12 +60,12 @@ public class ErrorDetailsComp extends SimpleComp { var items = new ArrayList(); if (event.getThrowable() != null) { items.add(new TabPaneComp.Entry( - I18n.observable("stackTrace"), "mdoal-code", Comp.of(this::createStrackTraceContent))); + AppI18n.observable("stackTrace"), "mdoal-code", Comp.of(this::createStrackTraceContent))); } if (event.getTrackEvents().size() > 0) { items.add(new TabPaneComp.Entry( - I18n.observable("events"), "mdi2c-clipboard-list-outline", createTrackEventHistory())); + AppI18n.observable("events"), "mdi2c-clipboard-list-outline", createTrackEventHistory())); } var tb = new TabPaneComp(new SimpleObjectProperty<>(items.get(0)), items); diff --git a/extension/src/main/java/io/xpipe/extension/event/ErrorEvent.java b/app/src/main/java/io/xpipe/app/issue/ErrorEvent.java similarity index 97% rename from extension/src/main/java/io/xpipe/extension/event/ErrorEvent.java rename to app/src/main/java/io/xpipe/app/issue/ErrorEvent.java index 9214abe42..95ff0e5a9 100644 --- a/extension/src/main/java/io/xpipe/extension/event/ErrorEvent.java +++ b/app/src/main/java/io/xpipe/app/issue/ErrorEvent.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.event; +package io.xpipe.app.issue; import lombok.Builder; import lombok.Getter; diff --git a/app/src/main/java/io/xpipe/app/issue/ErrorHandler.java b/app/src/main/java/io/xpipe/app/issue/ErrorHandler.java index b78bf6406..c6f2ce490 100644 --- a/app/src/main/java/io/xpipe/app/issue/ErrorHandler.java +++ b/app/src/main/java/io/xpipe/app/issue/ErrorHandler.java @@ -1,7 +1,5 @@ package io.xpipe.app.issue; -import io.xpipe.extension.event.ErrorEvent; - public interface ErrorHandler { void handle(ErrorEvent event); 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 c3df9c8af..34bdee657 100644 --- a/app/src/main/java/io/xpipe/app/issue/ErrorHandlerComp.java +++ b/app/src/main/java/io/xpipe/app/issue/ErrorHandlerComp.java @@ -3,13 +3,12 @@ package io.xpipe.app.issue; import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.TitledPaneComp; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppWindowHelper; +import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.augment.GrowAugment; +import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.util.JfxHelper; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.augment.GrowAugment; -import io.xpipe.extension.fxcomps.util.PlatformThread; import javafx.geometry.Orientation; import javafx.scene.control.Label; import javafx.scene.control.Separator; @@ -43,7 +42,7 @@ public class ErrorHandlerComp extends SimpleComp { if (!showing.get()) { showing.set(true); var window = AppWindowHelper.sideWindow( - I18n.get("errorHandler"), w -> new ErrorHandlerComp(event, w), true, null); + AppI18n.get("errorHandler"), w -> new ErrorHandlerComp(event, w), true, null); window.setOnHidden(e -> { showing.set(false); }); @@ -66,7 +65,7 @@ public class ErrorHandlerComp extends SimpleComp { private Region createDetails() { var content = new ErrorDetailsComp(event); - var tp = new TitledPaneComp(I18n.observable("errorDetails"), content, 250); + var tp = new TitledPaneComp(AppI18n.observable("errorDetails"), content, 250); var r = tp.createRegion(); r.getStyleClass().add("details"); return r; @@ -81,17 +80,17 @@ public class ErrorHandlerComp extends SimpleComp { var desc = event.getDescription(); if (desc == null && event.getThrowable() != null) { var tName = event.getThrowable().getClass().getSimpleName(); - desc = I18n.get("errorTypeOccured", tName); + desc = AppI18n.get("errorTypeOccured", tName); } if (desc == null) { - desc = I18n.get("errorNoDetail"); + desc = AppI18n.get("errorNoDetail"); } var limitedDescription = desc.substring(0, Math.min(1000, desc.length())); - var top = JfxHelper.createNamedEntry(I18n.get(headerId), limitedDescription, graphic); + var top = JfxHelper.createNamedEntry(AppI18n.get(headerId), limitedDescription, graphic); var content = new VBox(top, new Separator(Orientation.HORIZONTAL)); if (event.isReportable()) { - var header = new Label(I18n.get("possibleActions")); + var header = new Label(AppI18n.get("possibleActions")); AppFont.header(header); var actionBox = new VBox(header); actionBox.getStyleClass().add("actions"); diff --git a/extension/src/main/java/io/xpipe/extension/event/EventHandler.java b/app/src/main/java/io/xpipe/app/issue/EventHandler.java similarity index 98% rename from extension/src/main/java/io/xpipe/extension/event/EventHandler.java rename to app/src/main/java/io/xpipe/app/issue/EventHandler.java index 5b99ecf99..46b6320ef 100644 --- a/extension/src/main/java/io/xpipe/extension/event/EventHandler.java +++ b/app/src/main/java/io/xpipe/app/issue/EventHandler.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.event; +package io.xpipe.app.issue; import java.util.List; import java.util.ServiceLoader; diff --git a/app/src/main/java/io/xpipe/app/issue/EventHandlerImpl.java b/app/src/main/java/io/xpipe/app/issue/EventHandlerImpl.java index 9883671a8..7bb86457c 100644 --- a/app/src/main/java/io/xpipe/app/issue/EventHandlerImpl.java +++ b/app/src/main/java/io/xpipe/app/issue/EventHandlerImpl.java @@ -3,9 +3,6 @@ package io.xpipe.app.issue; import io.xpipe.app.core.AppLogs; import io.xpipe.app.core.mode.OperationMode; import io.xpipe.core.util.Deobfuscator; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.EventHandler; -import io.xpipe.extension.event.TrackEvent; import java.nio.file.Path; import java.util.ArrayList; diff --git a/app/src/main/java/io/xpipe/app/issue/ExceptionConverter.java b/app/src/main/java/io/xpipe/app/issue/ExceptionConverter.java new file mode 100644 index 000000000..17601ae6d --- /dev/null +++ b/app/src/main/java/io/xpipe/app/issue/ExceptionConverter.java @@ -0,0 +1,32 @@ +package io.xpipe.app.issue; + +import io.xpipe.app.core.AppI18n; + +import java.io.FileNotFoundException; + +public class ExceptionConverter { + + public static String convertMessage(Throwable ex) { + var msg = ex.getLocalizedMessage(); + + if (!AppI18n.getInstance().isLoaded()) { + return msg; + } + + return switch (ex) { + case StackOverflowError e -> AppI18n.get("app.stackOverflow"); + case OutOfMemoryError e -> AppI18n.get("app.outOfMemory"); + case FileNotFoundException e -> AppI18n.get("app.fileNotFound", msg); + case NullPointerException e -> AppI18n.get("app.nullPointer"); + case UnsupportedOperationException e -> AppI18n.get("app.unsupportedOperation", msg); + case ClassNotFoundException e -> AppI18n.get("app.classNotFound", msg); + default -> { + if (msg == null || msg.trim().length() == 0) { + yield AppI18n.get("app.noInformationAvailable"); + } + + yield msg; + } + }; + } +} diff --git a/app/src/main/java/io/xpipe/app/issue/SentryErrorHandler.java b/app/src/main/java/io/xpipe/app/issue/SentryErrorHandler.java index 8430ff60e..4d9113ef1 100644 --- a/app/src/main/java/io/xpipe/app/issue/SentryErrorHandler.java +++ b/app/src/main/java/io/xpipe/app/issue/SentryErrorHandler.java @@ -5,9 +5,7 @@ import io.sentry.protocol.SentryId; import io.sentry.protocol.User; import io.xpipe.app.core.AppCache; import io.xpipe.app.core.AppProperties; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.util.XPipeDistributionType; +import io.xpipe.app.util.XPipeDistributionType; import org.apache.commons.io.FileUtils; import java.nio.file.Files; diff --git a/app/src/main/java/io/xpipe/app/issue/TerminalErrorHandler.java b/app/src/main/java/io/xpipe/app/issue/TerminalErrorHandler.java index 1f693026e..8897a65ef 100644 --- a/app/src/main/java/io/xpipe/app/issue/TerminalErrorHandler.java +++ b/app/src/main/java/io/xpipe/app/issue/TerminalErrorHandler.java @@ -4,8 +4,6 @@ import io.sentry.Sentry; import io.xpipe.app.core.*; import io.xpipe.app.core.mode.OperationMode; import io.xpipe.app.update.AppUpdater; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; import javafx.application.Platform; import javafx.scene.control.Alert; import javafx.scene.control.ButtonBar; @@ -93,13 +91,13 @@ public class TerminalErrorHandler implements ErrorHandler { if (rel.isUpdate()) { var update = AppWindowHelper.showBlockingAlert(alert -> { alert.setAlertType(Alert.AlertType.INFORMATION); - alert.setTitle(I18n.get("updateAvailableTitle")); - alert.setHeaderText(I18n.get("updateAvailableHeader")); + alert.setTitle(AppI18n.get("updateAvailableTitle")); + alert.setHeaderText(AppI18n.get("updateAvailableHeader")); alert.getDialogPane() - .setContent(AppWindowHelper.alertContentText(I18n.get("updateAvailableContent"))); + .setContent(AppWindowHelper.alertContentText(AppI18n.get("updateAvailableContent"))); alert.getButtonTypes().clear(); - alert.getButtonTypes().add(new ButtonType(I18n.get("install"), ButtonBar.ButtonData.YES)); - alert.getButtonTypes().add(new ButtonType(I18n.get("ignore"), ButtonBar.ButtonData.NO)); + alert.getButtonTypes().add(new ButtonType(AppI18n.get("install"), ButtonBar.ButtonData.YES)); + alert.getButtonTypes().add(new ButtonType(AppI18n.get("ignore"), ButtonBar.ButtonData.NO)); }) .map(buttonType -> buttonType.getButtonData().isDefaultButton()) .orElse(false); diff --git a/extension/src/main/java/io/xpipe/extension/event/TrackEvent.java b/app/src/main/java/io/xpipe/app/issue/TrackEvent.java similarity index 99% rename from extension/src/main/java/io/xpipe/extension/event/TrackEvent.java rename to app/src/main/java/io/xpipe/app/issue/TrackEvent.java index 104718088..9408ec1a2 100644 --- a/extension/src/main/java/io/xpipe/extension/event/TrackEvent.java +++ b/app/src/main/java/io/xpipe/app/issue/TrackEvent.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.event; +package io.xpipe.app.issue; import lombok.Builder; import lombok.Getter; diff --git a/app/src/main/java/io/xpipe/app/issue/UserReportComp.java b/app/src/main/java/io/xpipe/app/issue/UserReportComp.java index fce311914..31e0c3001 100644 --- a/app/src/main/java/io/xpipe/app/issue/UserReportComp.java +++ b/app/src/main/java/io/xpipe/app/issue/UserReportComp.java @@ -5,13 +5,12 @@ import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ListSelectorComp; import io.xpipe.app.comp.base.TitledPaneComp; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppLogs; import io.xpipe.app.core.AppWindowHelper; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.util.Hyperlinks; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.SimpleComp; import javafx.beans.property.ListProperty; import javafx.beans.property.SimpleListProperty; import javafx.beans.property.SimpleStringProperty; @@ -44,7 +43,7 @@ public class UserReportComp extends SimpleComp { public static void show(ErrorEvent event) { var window = - AppWindowHelper.sideWindow(I18n.get("errorHandler"), w -> new UserReportComp(event, w), true, null); + AppWindowHelper.sideWindow(AppI18n.get("errorHandler"), w -> new UserReportComp(event, w), true, null); window.showAndWait(); } @@ -53,14 +52,14 @@ public class UserReportComp extends SimpleComp { event.getAttachments(), file -> { if (file.equals(AppLogs.get().getSessionLogsDirectory())) { - return I18n.get("logFilesAttachment"); + return AppI18n.get("logFilesAttachment"); } return file.getFileName().toString(); }, includedDiagnostics) .styleClass("attachment-list"); - var tp = new TitledPaneComp(I18n.observable("additionalErrorAttachments"), list, 100) + var tp = new TitledPaneComp(AppI18n.observable("additionalErrorAttachments"), list, 100) .apply(struc -> struc.get().setExpanded(true)) .apply(s -> AppFont.medium(s.get())) .styleClass("attachments"); @@ -69,7 +68,7 @@ public class UserReportComp extends SimpleComp { @Override protected Region createSimple() { - var header = new Label(I18n.get("additionalErrorInfo")); + var header = new Label(AppI18n.get("additionalErrorInfo")); AppFont.medium(header); var tf = new TextArea(); text.bind(tf.textProperty()); @@ -96,11 +95,11 @@ public class UserReportComp extends SimpleComp { } private Region createBottomBarNavigation() { - var dataPolicyButton = new Hyperlink(I18n.get("dataHandlingPolicies")); + var dataPolicyButton = new Hyperlink(AppI18n.get("dataHandlingPolicies")); dataPolicyButton.setOnAction(event1 -> { Hyperlinks.open(Hyperlinks.DOCS_PRIVACY); }); - var sendButton = new ButtonComp(I18n.observable("sendReport"), null, this::send) + var sendButton = new ButtonComp(AppI18n.observable("sendReport"), null, this::send) .apply(struc -> struc.get().getStyleClass().addAll(BUTTON_OUTLINED, ACCENT)) .createRegion(); var spacer = new Region(); diff --git a/app/src/main/java/io/xpipe/app/launcher/LauncherCommand.java b/app/src/main/java/io/xpipe/app/launcher/LauncherCommand.java index 63efbf9f2..824dbc32f 100644 --- a/app/src/main/java/io/xpipe/app/launcher/LauncherCommand.java +++ b/app/src/main/java/io/xpipe/app/launcher/LauncherCommand.java @@ -4,14 +4,14 @@ import io.xpipe.app.core.AppLock; import io.xpipe.app.core.AppLogs; import io.xpipe.app.core.mode.OperationMode; import io.xpipe.app.issue.BasicErrorHandler; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; +import io.xpipe.app.util.ThreadHelper; import io.xpipe.beacon.BeaconServer; import io.xpipe.beacon.exchange.FocusExchange; import io.xpipe.beacon.exchange.OpenExchange; import io.xpipe.core.process.OsType; import io.xpipe.core.util.XPipeDaemonMode; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.util.ThreadHelper; import picocli.CommandLine; import java.awt.*; diff --git a/app/src/main/java/io/xpipe/app/launcher/LauncherInput.java b/app/src/main/java/io/xpipe/app/launcher/LauncherInput.java index 02e53a753..c56d81bc4 100644 --- a/app/src/main/java/io/xpipe/app/launcher/LauncherInput.java +++ b/app/src/main/java/io/xpipe/app/launcher/LauncherInput.java @@ -2,11 +2,11 @@ package io.xpipe.app.launcher; import io.xpipe.app.comp.source.GuiDsCreatorMultiStep; import io.xpipe.app.core.mode.OperationMode; +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.core.impl.FileStore; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.util.ActionProvider; import lombok.Getter; import lombok.Value; 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 541eea015..fd08c6046 100644 --- a/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java +++ b/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java @@ -9,12 +9,12 @@ import com.dlsc.preferencesfx.model.Setting; import com.dlsc.preferencesfx.util.VisibilityProperty; import io.xpipe.app.core.AppProperties; import io.xpipe.app.core.AppStyle; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; -import io.xpipe.extension.prefs.PrefsChoiceValue; -import io.xpipe.extension.prefs.PrefsHandler; -import io.xpipe.extension.prefs.PrefsProvider; -import io.xpipe.extension.util.XPipeDistributionType; +import io.xpipe.app.ext.PrefsChoiceValue; +import io.xpipe.app.ext.PrefsHandler; +import io.xpipe.app.ext.PrefsProvider; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.util.XPipeDistributionType; import javafx.beans.binding.Bindings; import javafx.beans.property.*; import javafx.beans.value.ObservableBooleanValue; @@ -99,6 +99,23 @@ public class AppPrefs { private final BooleanProperty saveWindowLocationInternal = typed(new SimpleBooleanProperty(false), Boolean.class); public final ReadOnlyBooleanProperty saveWindowLocation = saveWindowLocationInternal; + // External terminal + // ================= + private final ObjectProperty terminalType = typed(new SimpleObjectProperty<>(), ExternalTerminalType.class); + private final SimpleListProperty terminalTypeList = new SimpleListProperty<>( + FXCollections.observableArrayList(PrefsChoiceValue.getSupported(ExternalTerminalType.class))); + private final SingleSelectionField terminalTypeControl = Field.ofSingleSelectionType( + terminalTypeList, terminalType) + .render(() -> new TranslatableComboBoxControl<>()); + + // Custom terminal + // =============== + private final StringProperty customTerminalCommand = typed(new SimpleStringProperty(""), String.class); + private final StringField customTerminalCommandControl = editable( + StringField.ofStringType(customTerminalCommand).render(() -> new SimpleTextControl()), + terminalType.isEqualTo(ExternalTerminalType.CUSTOM)); + + // Close behaviour // =============== @@ -236,6 +253,14 @@ public class AppPrefs { return confirmDeletions; } + public ObservableValue terminalType() { + return terminalType; + } + + public ObservableValue customTerminalCommand() { + return customTerminalCommand; + } + public ObservableValue storageDirectory() { return effectiveStorageDirectory; } @@ -344,6 +369,9 @@ public class AppPrefs { if (externalEditor.get() == null) { ExternalEditorType.detectDefault(); } + if (terminalType.get() == null) { + terminalType.set(ExternalTerminalType.getDefault()); + } } public void save() { @@ -441,7 +469,13 @@ public class AppPrefs { "editorReloadTimeout", editorReloadTimeout, editorReloadTimeoutMin, - editorReloadTimeoutMax))), + editorReloadTimeoutMax)), + Group.of( + "terminal", + Setting.of("terminalProgram", terminalTypeControl, terminalType), + Setting.of("customTerminalCommand", customTerminalCommandControl, customTerminalCommand) + .applyVisibility(VisibilityProperty.of( + terminalType.isEqualTo(ExternalTerminalType.CUSTOM))))), Category.of( "developer", Setting.of( diff --git a/app/src/main/java/io/xpipe/app/prefs/ClearCacheAlert.java b/app/src/main/java/io/xpipe/app/prefs/ClearCacheAlert.java index 67cea09d6..4907d4e08 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ClearCacheAlert.java +++ b/app/src/main/java/io/xpipe/app/prefs/ClearCacheAlert.java @@ -1,18 +1,18 @@ package io.xpipe.app.prefs; import io.xpipe.app.core.AppCache; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppWindowHelper; -import io.xpipe.extension.I18n; import javafx.scene.control.Alert; public class ClearCacheAlert { public static void show() { AppWindowHelper.showBlockingAlert(alert -> { - alert.setTitle(I18n.get("clearCachesAlertTitle")); - alert.setHeaderText(I18n.get("clearCachesAlertTitleHeader")); + alert.setTitle(AppI18n.get("clearCachesAlertTitle")); + alert.setHeaderText(AppI18n.get("clearCachesAlertTitleHeader")); alert.getDialogPane() - .setContent(AppWindowHelper.alertContentText(I18n.get("clearCachesAlertTitleContent"))); + .setContent(AppWindowHelper.alertContentText(AppI18n.get("clearCachesAlertTitleContent"))); alert.setAlertType(Alert.AlertType.CONFIRMATION); }) .filter(b -> b.getButtonData().isDefaultButton()) diff --git a/app/src/main/java/io/xpipe/app/prefs/CloseBehaviour.java b/app/src/main/java/io/xpipe/app/prefs/CloseBehaviour.java index 32790b8b1..732e2d882 100644 --- a/app/src/main/java/io/xpipe/app/prefs/CloseBehaviour.java +++ b/app/src/main/java/io/xpipe/app/prefs/CloseBehaviour.java @@ -1,7 +1,7 @@ package io.xpipe.app.prefs; import io.xpipe.app.core.mode.OperationMode; -import io.xpipe.extension.prefs.PrefsChoiceValue; +import io.xpipe.app.ext.PrefsChoiceValue; import lombok.Getter; @Getter diff --git a/app/src/main/java/io/xpipe/app/prefs/CloseBehaviourAlert.java b/app/src/main/java/io/xpipe/app/prefs/CloseBehaviourAlert.java index 07a5a6907..00aa1cba2 100644 --- a/app/src/main/java/io/xpipe/app/prefs/CloseBehaviourAlert.java +++ b/app/src/main/java/io/xpipe/app/prefs/CloseBehaviourAlert.java @@ -1,9 +1,9 @@ package io.xpipe.app.prefs; import io.xpipe.app.core.AppCache; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppWindowHelper; -import io.xpipe.extension.I18n; -import io.xpipe.extension.prefs.PrefsChoiceValue; +import io.xpipe.app.ext.PrefsChoiceValue; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.scene.control.Alert; @@ -22,8 +22,8 @@ public class CloseBehaviourAlert { Property prop = new SimpleObjectProperty<>(AppPrefs.get().closeBehaviour().getValue()); return AppWindowHelper.showBlockingAlert(alert -> { - alert.setTitle(I18n.get("closeBehaviourAlertTitle")); - alert.setHeaderText(I18n.get("closeBehaviourAlertTitleHeader")); + alert.setTitle(AppI18n.get("closeBehaviourAlertTitle")); + alert.setHeaderText(AppI18n.get("closeBehaviourAlertTitleHeader")); alert.setAlertType(Alert.AlertType.CONFIRMATION); ToggleGroup group = new ToggleGroup(); diff --git a/app/src/main/java/io/xpipe/app/prefs/CustomFormRenderer.java b/app/src/main/java/io/xpipe/app/prefs/CustomFormRenderer.java index 4aaed2ee0..4e3487a60 100644 --- a/app/src/main/java/io/xpipe/app/prefs/CustomFormRenderer.java +++ b/app/src/main/java/io/xpipe/app/prefs/CustomFormRenderer.java @@ -11,7 +11,6 @@ import com.dlsc.preferencesfx.formsfx.view.renderer.PreferencesFxGroupRenderer; import com.dlsc.preferencesfx.util.PreferencesFxUtils; import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppI18n; -import io.xpipe.extension.I18n; import javafx.geometry.Insets; import javafx.scene.control.Label; import javafx.scene.layout.GridPane; @@ -85,9 +84,9 @@ public class CustomFormRenderer extends PreferencesFxFormRenderer { descriptionLabel.managedProperty().bind(c.getFieldLabel().managedProperty()); descriptionLabel.visibleProperty().bind(c.getFieldLabel().visibleProperty()); descriptionLabel.setMaxHeight(USE_PREF_SIZE); - if (AppI18n.get().containsKey(descriptionKey)) { + if (AppI18n.getInstance().containsKey(descriptionKey)) { rowAmount++; - descriptionLabel.textProperty().bind(I18n.observable(descriptionKey)); + descriptionLabel.textProperty().bind(AppI18n.observable(descriptionKey)); grid.add(descriptionLabel, 0, i + rowAmount, 2, 1); } diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java index 8be8685c1..27776ed69 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java @@ -1,10 +1,10 @@ package io.xpipe.app.prefs; +import io.xpipe.app.ext.PrefsChoiceValue; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.process.OsType; import io.xpipe.core.process.ShellProcessControl; import io.xpipe.core.store.ShellStore; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.prefs.PrefsChoiceValue; import java.nio.file.Files; import java.nio.file.Path; diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java index 5c8028a25..8dc3384f0 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java @@ -1,10 +1,10 @@ package io.xpipe.app.prefs; +import io.xpipe.app.ext.PrefsChoiceValue; +import io.xpipe.app.util.ApplicationHelper; +import io.xpipe.app.util.WindowsRegistry; import io.xpipe.core.process.OsType; import io.xpipe.core.process.ShellTypes; -import io.xpipe.extension.prefs.PrefsChoiceValue; -import io.xpipe.extension.util.ApplicationHelper; -import io.xpipe.extension.util.WindowsRegistry; import java.io.IOException; import java.nio.file.Path; diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalStartupBehaviour.java b/app/src/main/java/io/xpipe/app/prefs/ExternalStartupBehaviour.java index 92c150faf..c315534e7 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalStartupBehaviour.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalStartupBehaviour.java @@ -1,7 +1,7 @@ package io.xpipe.app.prefs; import io.xpipe.app.core.mode.OperationMode; -import io.xpipe.extension.prefs.PrefsChoiceValue; +import io.xpipe.app.ext.PrefsChoiceValue; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalTerminalType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalTerminalType.java new file mode 100644 index 000000000..6958d65e9 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalTerminalType.java @@ -0,0 +1,290 @@ +package io.xpipe.app.prefs; + +import io.xpipe.app.ext.PrefsChoiceValue; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.util.ApplicationHelper; +import io.xpipe.app.util.MacOsPermissions; +import io.xpipe.core.process.OsType; +import io.xpipe.core.process.ShellProcessControl; +import io.xpipe.core.store.ShellStore; + +import java.util.List; + +public interface ExternalTerminalType extends PrefsChoiceValue { + + public static final ExternalTerminalType CMD = new SimpleType("cmd", "cmd", "cmd.exe") { + + @Override + protected String toCommand(String name, String command) { + return "cmd.exe /C " + command; + } + + @Override + public boolean isSelectable() { + return OsType.getLocal().equals(OsType.WINDOWS); + } + }; + + public static final ExternalTerminalType POWERSHELL = + new SimpleType("powershell", "powershell", "PowerShell") { + + @Override + protected String toCommand(String name, String command) { + return "powershell.exe -Command " + command; + } + + @Override + public boolean isSelectable() { + return OsType.getLocal().equals(OsType.WINDOWS); + } + }; + + public static final ExternalTerminalType WINDOWS_TERMINAL = + new SimpleType("windowsTerminal", "wt.exe", "Windows Terminal") { + + @Override + protected String toCommand(String name, String command) { + return "-w 1 nt --title \"" + name + "\" " + command; + } + + @Override + public boolean isSelectable() { + return OsType.getLocal().equals(OsType.WINDOWS); + } + }; + + public static final ExternalTerminalType GNOME_TERMINAL = + new SimpleType("gnomeTerminal", "gnome-terminal", "Gnome Terminal") { + + @Override + protected String toCommand(String name, String command) { + return "--title \"" + name + "\" -- " + command; + } + + @Override + public boolean isSelectable() { + return OsType.getLocal().equals(OsType.LINUX); + } + }; + + public static final ExternalTerminalType KONSOLE = new SimpleType("konsole", "konsole", "Konsole") { + + @Override + protected String toCommand(String name, String command) { + return "--new-tab -e bash -c " + command; + } + + @Override + public boolean isSelectable() { + return OsType.getLocal().equals(OsType.LINUX); + } + }; + + public static final ExternalTerminalType XFCE = new SimpleType("xfce", "xfce4-terminal", "Xfce") { + + @Override + protected String toCommand(String name, String command) { + return "--tab --title \"" + name + "\" --command " + command; + } + + @Override + public boolean isSelectable() { + return OsType.getLocal().equals(OsType.LINUX); + } + }; + + public static final ExternalTerminalType MACOS_TERMINAL = new MacOsTerminalType(); + + public static final ExternalTerminalType ITERM2 = new ITerm2Type(); + + public static final ExternalTerminalType WARP = new WarpType(); + + public static final ExternalTerminalType CUSTOM = new CustomType(); + + public static final List ALL = List.of( + WINDOWS_TERMINAL, + POWERSHELL, + CMD, + KONSOLE, + XFCE, + GNOME_TERMINAL, + WARP, + ITERM2, + MACOS_TERMINAL, + CUSTOM) + .stream() + .filter(terminalType -> terminalType.isSelectable()) + .toList(); + + public static ExternalTerminalType getDefault() { + return ALL.stream() + .filter(terminalType -> terminalType.isAvailable()) + .findFirst() + .orElse(CUSTOM); + } + + public abstract void launch(String name, String command) throws Exception; + + static class MacOsTerminalType extends ExternalApplicationType.MacApplication implements ExternalTerminalType { + + public MacOsTerminalType() { + super("macosTerminal", "Terminal"); + } + + @Override + public void launch(String name, String command) throws Exception { + try (ShellProcessControl pc = ShellStore.local().create().start()) { + var suffix = command.equals(pc.getShellType().getNormalOpenCommand()) + ? "\"\"" + : "\"" + command.replaceAll("\"", "\\\\\"") + "\""; + var cmd = "osascript -e 'tell app \"" + "Terminal" + "\" to do script " + suffix + "'"; + pc.executeSimpleCommand(cmd); + } + } + } + + static class CustomType extends ExternalApplicationType implements ExternalTerminalType { + + public CustomType() { + super("custom"); + } + + @Override + public void launch(String name, String command) throws Exception { + var custom = AppPrefs.get().customTerminalCommand().getValue(); + if (custom == null || custom.trim().isEmpty()) { + return; + } + + var format = custom.contains("$cmd") ? custom : custom + " $cmd"; + try (var pc = ShellStore.local().create().start()) { + var toExecute = format.replace("$cmd", command); + if (pc.getOsType().equals(OsType.WINDOWS)) { + toExecute = "start \"" + name + "\" " + toExecute; + } else { + toExecute = "nohup " + toExecute + " /dev/null & disown"; + } + pc.executeSimpleCommand(toExecute); + } + } + + @Override + public boolean isSelectable() { + return true; + } + + @Override + public boolean isAvailable() { + return true; + } + } + + static class ITerm2Type extends ExternalApplicationType.MacApplication implements ExternalTerminalType { + + public ITerm2Type() { + super("iterm2", "iTerm2"); + } + + @Override + public void launch(String name, String command) throws Exception { + try (ShellProcessControl pc = ShellStore.local().create().start()) { + var cmd = String.format( + """ + osascript - "$@" </dev/null & disown"; + } + pc.executeSimpleCommand(toExecute); + } + } + + protected abstract String toCommand(String name, String command); + + public boolean isAvailable() { + try (ShellProcessControl pc = ShellStore.local().create().start()) { + return pc.executeBooleanSimpleCommand(pc.getShellType().getWhichCommand(executable)); + } catch (Exception e) { + ErrorEvent.fromThrowable(e).omit().handle(); + return false; + } + } + + @Override + public boolean isSelectable() { + return true; + } + } +} 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 317ea5bc2..5ba974d5f 100644 --- a/app/src/main/java/io/xpipe/app/prefs/JsonStorageHandler.java +++ b/app/src/main/java/io/xpipe/app/prefs/JsonStorageHandler.java @@ -6,19 +6,19 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; import com.fasterxml.jackson.databind.type.CollectionType; import io.xpipe.app.core.AppProperties; +import io.xpipe.app.ext.PrefsChoiceValue; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.util.JsonConfigHelper; import io.xpipe.core.util.JacksonMapper; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.prefs.PrefsChoiceValue; import javafx.collections.ObservableList; import org.apache.commons.io.FileUtils; import java.nio.file.Path; import java.util.List; -import static io.xpipe.extension.prefs.PrefsChoiceValue.getAll; -import static io.xpipe.extension.prefs.PrefsChoiceValue.getSupported; +import static io.xpipe.app.ext.PrefsChoiceValue.getAll; +import static io.xpipe.app.ext.PrefsChoiceValue.getSupported; public class JsonStorageHandler implements StorageHandler { diff --git a/app/src/main/java/io/xpipe/app/prefs/PrefFields.java b/app/src/main/java/io/xpipe/app/prefs/PrefFields.java index 38551ba03..b7e92c4d4 100644 --- a/app/src/main/java/io/xpipe/app/prefs/PrefFields.java +++ b/app/src/main/java/io/xpipe/app/prefs/PrefFields.java @@ -2,7 +2,7 @@ package io.xpipe.app.prefs; import com.dlsc.formsfx.model.structure.StringField; import com.dlsc.preferencesfx.formsfx.view.controls.SimpleChooserControl; -import io.xpipe.extension.I18n; +import io.xpipe.app.core.AppI18n; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; @@ -31,6 +31,6 @@ public class PrefFields { }); return StringField.ofStringType(stringProperty) .render(() -> new SimpleChooserControl( - I18n.get("browse"), fileProperty.getValue().toFile(), true)); + AppI18n.get("browse"), fileProperty.getValue().toFile(), true)); } } diff --git a/app/src/main/java/io/xpipe/app/prefs/QuietResourceBundleService.java b/app/src/main/java/io/xpipe/app/prefs/QuietResourceBundleService.java index 79e958387..df50e5f58 100644 --- a/app/src/main/java/io/xpipe/app/prefs/QuietResourceBundleService.java +++ b/app/src/main/java/io/xpipe/app/prefs/QuietResourceBundleService.java @@ -1,7 +1,7 @@ package io.xpipe.app.prefs; import com.dlsc.formsfx.model.util.ResourceBundleService; -import io.xpipe.extension.I18n; +import io.xpipe.app.core.AppI18n; import java.util.Enumeration; import java.util.ResourceBundle; @@ -24,7 +24,7 @@ public class QuietResourceBundleService extends ResourceBundleService { @Override public String translate(String key) { - var value = I18n.get(key); + var value = AppI18n.get(key); return value; } } diff --git a/app/src/main/java/io/xpipe/app/prefs/SupportedLocale.java b/app/src/main/java/io/xpipe/app/prefs/SupportedLocale.java index 7b2fe2d0d..da3943456 100644 --- a/app/src/main/java/io/xpipe/app/prefs/SupportedLocale.java +++ b/app/src/main/java/io/xpipe/app/prefs/SupportedLocale.java @@ -1,6 +1,6 @@ package io.xpipe.app.prefs; -import io.xpipe.extension.prefs.PrefsChoiceValue; +import io.xpipe.app.ext.PrefsChoiceValue; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/app/src/main/java/io/xpipe/app/prefs/TranslatableComboBoxControl.java b/app/src/main/java/io/xpipe/app/prefs/TranslatableComboBoxControl.java index eb0bd2683..e4641dd53 100644 --- a/app/src/main/java/io/xpipe/app/prefs/TranslatableComboBoxControl.java +++ b/app/src/main/java/io/xpipe/app/prefs/TranslatableComboBoxControl.java @@ -2,7 +2,7 @@ package io.xpipe.app.prefs; import com.dlsc.formsfx.model.structure.SingleSelectionField; import com.dlsc.preferencesfx.formsfx.view.controls.SimpleControl; -import io.xpipe.extension.Translatable; +import io.xpipe.app.util.Translatable; import javafx.geometry.Pos; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; diff --git a/app/src/main/java/io/xpipe/app/storage/DataSourceEntry.java b/app/src/main/java/io/xpipe/app/storage/DataSourceEntry.java index 3f9b6ca01..792a54a07 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataSourceEntry.java +++ b/app/src/main/java/io/xpipe/app/storage/DataSourceEntry.java @@ -5,13 +5,13 @@ 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.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceProviders; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; import io.xpipe.core.util.JacksonMapper; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceProviders; -import io.xpipe.extension.event.ErrorEvent; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; 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 c89660b9a..5b2177270 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStorage.java @@ -1,17 +1,17 @@ package io.xpipe.app.storage; import io.xpipe.app.core.AppCharsets; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataStoreProviders; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.charsetter.Charsettable; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceId; import io.xpipe.core.source.DataSourceReference; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataStoreProviders; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.util.ThreadHelper; import lombok.Getter; import lombok.NonNull; @@ -106,11 +106,11 @@ public abstract class DataStorage { var typeName = switch (source.getType()) { - case TABLE -> I18n.get("table"); - case STRUCTURE -> I18n.get("structure"); - case TEXT -> I18n.get("text"); - case RAW -> I18n.get("raw"); - case COLLECTION -> I18n.get("collection"); + case TABLE -> AppI18n.get("table"); + case STRUCTURE -> AppI18n.get("structure"); + case TEXT -> AppI18n.get("text"); + case RAW -> AppI18n.get("raw"); + case COLLECTION -> AppI18n.get("collection"); }; return createUniqueSourceEntryName(col, typeName); } diff --git a/app/src/main/java/io/xpipe/app/storage/DataStorageParser.java b/app/src/main/java/io/xpipe/app/storage/DataStorageParser.java index f7ba4c4c0..5e2a7ca6d 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStorageParser.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStorageParser.java @@ -4,11 +4,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.NullNode; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.core.source.DataSource; import io.xpipe.core.store.DataStore; import io.xpipe.core.util.JacksonMapper; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; import java.util.HashSet; import java.util.Optional; 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 cbd7ca18d..26d780ae6 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java @@ -6,11 +6,11 @@ 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.ext.DataStoreProvider; +import io.xpipe.app.ext.DataStoreProviders; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.store.DataStore; import io.xpipe.core.util.JacksonMapper; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.DataStoreProviders; -import io.xpipe.extension.event.ErrorEvent; import lombok.*; import lombok.experimental.NonFinal; import org.apache.commons.io.FileUtils; diff --git a/app/src/main/java/io/xpipe/app/storage/ImpersistentStorage.java b/app/src/main/java/io/xpipe/app/storage/ImpersistentStorage.java index f17de2309..4cfe8d0d1 100644 --- a/app/src/main/java/io/xpipe/app/storage/ImpersistentStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/ImpersistentStorage.java @@ -1,7 +1,7 @@ package io.xpipe.app.storage; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import lombok.NonNull; import org.apache.commons.io.FileUtils; 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 776100600..ab9954586 100644 --- a/app/src/main/java/io/xpipe/app/storage/StandardStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/StandardStorage.java @@ -1,8 +1,8 @@ package io.xpipe.app.storage; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.core.util.XPipeSession; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; import lombok.NonNull; import org.apache.commons.io.FileUtils; diff --git a/extension/src/main/java/io/xpipe/extension/test/DaemonExtensionTest.java b/app/src/main/java/io/xpipe/app/test/DaemonExtensionTest.java similarity index 93% rename from extension/src/main/java/io/xpipe/extension/test/DaemonExtensionTest.java rename to app/src/main/java/io/xpipe/app/test/DaemonExtensionTest.java index b0a7f7447..a96c496c4 100644 --- a/extension/src/main/java/io/xpipe/extension/test/DaemonExtensionTest.java +++ b/app/src/main/java/io/xpipe/app/test/DaemonExtensionTest.java @@ -1,12 +1,12 @@ -package io.xpipe.extension.test; +package io.xpipe.app.test; import io.xpipe.api.DataSource; +import io.xpipe.app.ext.XPipeServiceProviders; import io.xpipe.beacon.BeaconDaemonController; import io.xpipe.core.store.DataStore; import io.xpipe.core.util.JacksonMapper; import io.xpipe.core.util.XPipeDaemonMode; import io.xpipe.core.util.XPipeSession; -import io.xpipe.extension.XPipeServiceProviders; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; diff --git a/extension/src/main/java/io/xpipe/extension/test/ExtensionTest.java b/app/src/main/java/io/xpipe/app/test/ExtensionTest.java similarity index 97% rename from extension/src/main/java/io/xpipe/extension/test/ExtensionTest.java rename to app/src/main/java/io/xpipe/app/test/ExtensionTest.java index 62b542a1a..99a05a99b 100644 --- a/extension/src/main/java/io/xpipe/extension/test/ExtensionTest.java +++ b/app/src/main/java/io/xpipe/app/test/ExtensionTest.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.test; +package io.xpipe.app.test; import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.impl.FileStore; diff --git a/extension/src/main/java/io/xpipe/extension/test/LocalExtensionTest.java b/app/src/main/java/io/xpipe/app/test/LocalExtensionTest.java similarity index 84% rename from extension/src/main/java/io/xpipe/extension/test/LocalExtensionTest.java rename to app/src/main/java/io/xpipe/app/test/LocalExtensionTest.java index 92e89b15c..cf9244663 100644 --- a/extension/src/main/java/io/xpipe/extension/test/LocalExtensionTest.java +++ b/app/src/main/java/io/xpipe/app/test/LocalExtensionTest.java @@ -1,8 +1,8 @@ -package io.xpipe.extension.test; +package io.xpipe.app.test; +import io.xpipe.app.ext.XPipeServiceProviders; import io.xpipe.core.util.JacksonMapper; import io.xpipe.core.util.XPipeSession; -import io.xpipe.extension.XPipeServiceProviders; import org.junit.jupiter.api.BeforeAll; import java.util.UUID; diff --git a/extension/src/main/java/io/xpipe/extension/test/TestModule.java b/app/src/main/java/io/xpipe/app/test/TestModule.java similarity index 98% rename from extension/src/main/java/io/xpipe/extension/test/TestModule.java rename to app/src/main/java/io/xpipe/app/test/TestModule.java index 5def81f6e..3e83150ff 100644 --- a/extension/src/main/java/io/xpipe/extension/test/TestModule.java +++ b/app/src/main/java/io/xpipe/app/test/TestModule.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.test; +package io.xpipe.app.test; import org.junit.jupiter.api.Named; diff --git a/app/src/main/java/io/xpipe/app/update/AppDownloads.java b/app/src/main/java/io/xpipe/app/update/AppDownloads.java index 693b7ec65..fc25e3e2b 100644 --- a/app/src/main/java/io/xpipe/app/update/AppDownloads.java +++ b/app/src/main/java/io/xpipe/app/update/AppDownloads.java @@ -1,9 +1,9 @@ package io.xpipe.app.update; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.util.HttpHelper; +import io.xpipe.app.util.HttpHelper; import org.apache.commons.io.FileUtils; import org.kohsuke.github.GHRelease; import org.kohsuke.github.GHRepository; diff --git a/app/src/main/java/io/xpipe/app/update/AppInstaller.java b/app/src/main/java/io/xpipe/app/update/AppInstaller.java index 96fe722ce..cfcba943e 100644 --- a/app/src/main/java/io/xpipe/app/update/AppInstaller.java +++ b/app/src/main/java/io/xpipe/app/update/AppInstaller.java @@ -3,7 +3,8 @@ package io.xpipe.app.update; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import io.xpipe.app.util.TerminalProvider; +import io.xpipe.app.util.ScriptHelper; +import io.xpipe.app.util.TerminalHelper; import io.xpipe.core.impl.FileNames; import io.xpipe.core.process.CommandProcessControl; import io.xpipe.core.process.OsType; @@ -11,7 +12,6 @@ import io.xpipe.core.process.ShellProcessControl; import io.xpipe.core.process.ShellTypes; import io.xpipe.core.store.ShellStore; import io.xpipe.core.util.XPipeInstallation; -import io.xpipe.extension.util.ScriptHelper; import lombok.Getter; import java.io.InputStream; @@ -81,7 +81,7 @@ public class AppInstaller { if (p.getOsType().equals(OsType.LINUX)) { try (CommandProcessControl c = p.command(p.getShellType().getFileExistsCommand("/etc/debian_version")) .start()) { - return c.startAndCheckExit() ? new InstallerAssetType.Debian() : new InstallerAssetType.Rpm(); + return c.discardAndCheckExit() ? new InstallerAssetType.Debian() : new InstallerAssetType.Rpm(); } } @@ -199,7 +199,7 @@ public class AppInstaller { var command = "set -x\n" + "DEBIAN_FRONTEND=noninteractive sudo apt-get remove -qy xpipe\n" + "DEBIAN_FRONTEND=noninteractive sudo apt-get install -qy \"" + file + "\"\n" + "xpipe daemon start"; - TerminalProvider.open("X-Pipe Updater", command); + TerminalHelper.open("X-Pipe Updater", command); } } @@ -225,7 +225,7 @@ public class AppInstaller { @Override public void installLocal(String file) throws Exception { var command = "set -x\n" + "sudo rpm -U -v --force \"" + file + "\"\n" + "xpipe daemon start"; - TerminalProvider.open("X-Pipe Updater", command); + TerminalHelper.open("X-Pipe Updater", command); } } @@ -253,7 +253,7 @@ public class AppInstaller { public void installLocal(String file) throws Exception { var command = "set -x\n" + "sudo installer -verboseR -allowUntrusted -pkg \"" + file + "\" -target /\n" + "xpipe daemon start"; - TerminalProvider.open("X-Pipe Updater", command); + TerminalHelper.open("X-Pipe Updater", command); } } } diff --git a/app/src/main/java/io/xpipe/app/update/AppUpdater.java b/app/src/main/java/io/xpipe/app/update/AppUpdater.java index 37470a39a..b8bf8085f 100644 --- a/app/src/main/java/io/xpipe/app/update/AppUpdater.java +++ b/app/src/main/java/io/xpipe/app/update/AppUpdater.java @@ -4,14 +4,14 @@ import io.xpipe.app.core.AppCache; import io.xpipe.app.core.AppExtensionManager; import io.xpipe.app.core.AppProperties; import io.xpipe.app.core.mode.OperationMode; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.app.util.BusyProperty; +import io.xpipe.app.util.ThreadHelper; +import io.xpipe.app.util.XPipeDistributionType; import io.xpipe.core.process.ProcessControlProvider; import io.xpipe.core.util.XPipeSession; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.util.BusyProperty; -import io.xpipe.extension.util.ThreadHelper; -import io.xpipe.extension.util.XPipeDistributionType; import javafx.beans.property.BooleanProperty; import javafx.beans.property.Property; import javafx.beans.property.SimpleBooleanProperty; @@ -108,7 +108,7 @@ public class AppUpdater { AppProperties.init(); XPipeSession.init(AppProperties.get().getBuildUuid()); - var layer = AppExtensionManager.loadOnlyBundledExtension("proc"); + var layer = AppExtensionManager.initBare(); if (layer == null) { return; } diff --git a/app/src/main/java/io/xpipe/app/update/UpdateAvailableAlert.java b/app/src/main/java/io/xpipe/app/update/UpdateAvailableAlert.java index 9454f7c53..4e3789d4c 100644 --- a/app/src/main/java/io/xpipe/app/update/UpdateAvailableAlert.java +++ b/app/src/main/java/io/xpipe/app/update/UpdateAvailableAlert.java @@ -1,7 +1,7 @@ package io.xpipe.app.update; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppWindowHelper; -import io.xpipe.extension.I18n; import javafx.scene.control.Alert; public class UpdateAvailableAlert { @@ -13,9 +13,9 @@ public class UpdateAvailableAlert { } var update = AppWindowHelper.showBlockingAlert(alert -> { - alert.setTitle(I18n.get("updateReadyTitle")); - alert.setHeaderText(I18n.get("updateReadyHeader")); - alert.setContentText(I18n.get("updateReadyContent")); + alert.setTitle(AppI18n.get("updateReadyTitle")); + alert.setHeaderText(AppI18n.get("updateReadyHeader")); + alert.setContentText(AppI18n.get("updateReadyContent")); alert.setAlertType(Alert.AlertType.INFORMATION); }) .map(buttonType -> buttonType.getButtonData().isDefaultButton()) diff --git a/app/src/main/java/io/xpipe/app/update/UpdateChangelogAlert.java b/app/src/main/java/io/xpipe/app/update/UpdateChangelogAlert.java index 61e4dba54..d16a3e07c 100644 --- a/app/src/main/java/io/xpipe/app/update/UpdateChangelogAlert.java +++ b/app/src/main/java/io/xpipe/app/update/UpdateChangelogAlert.java @@ -1,8 +1,8 @@ package io.xpipe.app.update; import io.xpipe.app.comp.base.MarkdownComp; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppWindowHelper; -import io.xpipe.extension.I18n; import javafx.scene.control.Alert; import javafx.scene.control.ButtonBar; import javafx.scene.control.ButtonType; @@ -18,18 +18,18 @@ public class UpdateChangelogAlert { AppWindowHelper.showAlert( alert -> { - alert.setTitle(I18n.get("updateChangelogAlertTitle")); + alert.setTitle(AppI18n.get("updateChangelogAlertTitle")); alert.setAlertType(Alert.AlertType.NONE); alert.initModality(Modality.NONE); var markdown = new MarkdownComp(update.getRawDescription(), s -> { - var header = "

" + I18n.get("whatsNew", update.getName()) + "

"; + var header = "

" + AppI18n.get("whatsNew", update.getName()) + "

"; return header + s; }) .createRegion(); alert.getDialogPane().setContent(markdown); - alert.getButtonTypes().add(new ButtonType(I18n.get("gotIt"), ButtonBar.ButtonData.OK_DONE)); + alert.getButtonTypes().add(new ButtonType(AppI18n.get("gotIt"), ButtonBar.ButtonData.OK_DONE)); }, r -> r.filter(b -> b.getButtonData().isDefaultButton()).ifPresent(t -> {})); } diff --git a/app/src/main/java/io/xpipe/app/update/XPipeInstanceHelper.java b/app/src/main/java/io/xpipe/app/update/XPipeInstanceHelper.java index 700e77c34..1041a3e48 100644 --- a/app/src/main/java/io/xpipe/app/update/XPipeInstanceHelper.java +++ b/app/src/main/java/io/xpipe/app/update/XPipeInstanceHelper.java @@ -1,10 +1,10 @@ package io.xpipe.app.update; import io.xpipe.app.core.AppProperties; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.storage.DataStorage; import io.xpipe.beacon.XPipeInstance; import io.xpipe.core.store.ShellStore; -import io.xpipe.extension.event.ErrorEvent; import java.io.IOException; import java.nio.file.Files; diff --git a/extension/src/main/java/io/xpipe/extension/util/ApplicationHelper.java b/app/src/main/java/io/xpipe/app/util/ApplicationHelper.java similarity index 95% rename from extension/src/main/java/io/xpipe/extension/util/ApplicationHelper.java rename to app/src/main/java/io/xpipe/app/util/ApplicationHelper.java index f8df8c853..e848c1d50 100644 --- a/extension/src/main/java/io/xpipe/extension/util/ApplicationHelper.java +++ b/app/src/main/java/io/xpipe/app/util/ApplicationHelper.java @@ -1,9 +1,9 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.core.process.ShellProcessControl; import io.xpipe.core.process.ShellTypes; import io.xpipe.core.store.ShellStore; -import io.xpipe.extension.event.TrackEvent; import java.io.IOException; import java.util.List; diff --git a/extension/src/main/java/io/xpipe/extension/util/BusyProperty.java b/app/src/main/java/io/xpipe/app/util/BusyProperty.java similarity index 53% rename from extension/src/main/java/io/xpipe/extension/util/BusyProperty.java rename to app/src/main/java/io/xpipe/app/util/BusyProperty.java index 0b7a42d43..f1e94989f 100644 --- a/extension/src/main/java/io/xpipe/extension/util/BusyProperty.java +++ b/app/src/main/java/io/xpipe/app/util/BusyProperty.java @@ -1,9 +1,16 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import javafx.beans.property.BooleanProperty; +import org.apache.commons.lang3.function.FailableRunnable; public class BusyProperty implements AutoCloseable { + public static void execute(BooleanProperty prop, FailableRunnable r) throws E { + try (var ignored = new BusyProperty(prop)) { + r.run(); + } + } + private final BooleanProperty prop; public BusyProperty(BooleanProperty prop) { diff --git a/extension/src/main/java/io/xpipe/extension/util/ChainedValidator.java b/app/src/main/java/io/xpipe/app/util/ChainedValidator.java similarity index 99% rename from extension/src/main/java/io/xpipe/extension/util/ChainedValidator.java rename to app/src/main/java/io/xpipe/app/util/ChainedValidator.java index 318c6d831..a191222a2 100644 --- a/extension/src/main/java/io/xpipe/extension/util/ChainedValidator.java +++ b/app/src/main/java/io/xpipe/app/util/ChainedValidator.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import javafx.beans.Observable; import javafx.beans.binding.Bindings; diff --git a/app/src/main/java/io/xpipe/app/util/Containers.java b/app/src/main/java/io/xpipe/app/util/Containers.java new file mode 100644 index 000000000..f7a901d16 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/util/Containers.java @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: MIT */ + +package io.xpipe.app.util; + +import javafx.geometry.Insets; +import javafx.scene.Node; +import javafx.scene.control.ScrollPane; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.ColumnConstraints; +import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; + +import static javafx.scene.layout.Region.USE_COMPUTED_SIZE; +import static javafx.scene.layout.Region.USE_PREF_SIZE; + +public final class Containers { + + public static final ColumnConstraints H_GROW_NEVER = columnConstraints(Priority.NEVER); + + public static void setAnchors(Node node, Insets insets) { + if (insets.getTop() >= 0) { + AnchorPane.setTopAnchor(node, insets.getTop()); + } + if (insets.getRight() >= 0) { + AnchorPane.setRightAnchor(node, insets.getRight()); + } + if (insets.getBottom() >= 0) { + AnchorPane.setBottomAnchor(node, insets.getBottom()); + } + if (insets.getLeft() >= 0) { + AnchorPane.setLeftAnchor(node, insets.getLeft()); + } + } + + public static void setScrollConstraints(ScrollPane scrollPane, + ScrollPane.ScrollBarPolicy vbarPolicy, boolean fitHeight, + ScrollPane.ScrollBarPolicy hbarPolicy, boolean fitWidth) { + scrollPane.setVbarPolicy(vbarPolicy); + scrollPane.setFitToHeight(fitHeight); + scrollPane.setHbarPolicy(hbarPolicy); + scrollPane.setFitToWidth(fitWidth); + } + + public static ColumnConstraints columnConstraints(Priority hgrow) { + return columnConstraints(USE_COMPUTED_SIZE, hgrow); + } + + public static ColumnConstraints columnConstraints(double minWidth, Priority hgrow) { + double maxWidth = hgrow == Priority.ALWAYS ? Double.MAX_VALUE : USE_PREF_SIZE; + ColumnConstraints constraints = new ColumnConstraints(minWidth, USE_COMPUTED_SIZE, maxWidth); + constraints.setHgrow(hgrow); + return constraints; + } + + public static void usePrefWidth(Region region) { + region.setMinWidth(USE_PREF_SIZE); + region.setMaxWidth(USE_PREF_SIZE); + } + + public static void usePrefHeight(Region region) { + region.setMinHeight(USE_PREF_SIZE); + region.setMaxHeight(USE_PREF_SIZE); + } +} diff --git a/app/src/main/java/io/xpipe/app/util/Controls.java b/app/src/main/java/io/xpipe/app/util/Controls.java new file mode 100644 index 000000000..238aea073 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/util/Controls.java @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: MIT */ + +package io.xpipe.app.util; + +import javafx.scene.control.*; +import javafx.scene.input.KeyCombination; +import org.kordamp.ikonli.Ikon; +import org.kordamp.ikonli.javafx.FontIcon; + +import java.net.URI; + +import static atlantafx.base.theme.Styles.BUTTON_ICON; + +public final class Controls { + + public static Button iconButton(Ikon icon, boolean disable) { + return button("", icon, disable, BUTTON_ICON); + } + + public static Button button(String text, Ikon icon, boolean disable, String... styleClasses) { + var button = new Button(text); + if (icon != null) { + button.setGraphic(new FontIcon(icon)); + } + button.setDisable(disable); + button.getStyleClass().addAll(styleClasses); + return button; + } + + public static MenuItem menuItem(String text, Ikon graphic, KeyCombination accelerator) { + return menuItem(text, graphic, accelerator, false); + } + + public static MenuItem menuItem(String text, Ikon graphic, KeyCombination accelerator, boolean disable) { + var item = new MenuItem(text); + + if (graphic != null) { + item.setGraphic(new FontIcon(graphic)); + } + if (accelerator != null) { + item.setAccelerator(accelerator); + } + item.setDisable(disable); + + return item; + } + + public static ToggleButton toggleButton(String text, + Ikon icon, + ToggleGroup group, + boolean selected, + String... styleClasses) { + var toggleButton = new ToggleButton(text); + if (icon != null) { + toggleButton.setGraphic(new FontIcon(icon)); + } + if (group != null) { + toggleButton.setToggleGroup(group); + } + toggleButton.setSelected(selected); + toggleButton.getStyleClass().addAll(styleClasses); + + return toggleButton; + } + + public static Hyperlink hyperlink(String text, URI uri) { + var hyperlink = new Hyperlink(text); + if (uri != null) { + hyperlink.setOnAction(event -> Hyperlinks.open(uri.toString())); + } + return hyperlink; + } +} diff --git a/extension/src/main/java/io/xpipe/extension/util/CustomComboBoxBuilder.java b/app/src/main/java/io/xpipe/app/util/CustomComboBoxBuilder.java similarity index 97% rename from extension/src/main/java/io/xpipe/extension/util/CustomComboBoxBuilder.java rename to app/src/main/java/io/xpipe/app/util/CustomComboBoxBuilder.java index 8ee8b41b5..965d16f2f 100644 --- a/extension/src/main/java/io/xpipe/extension/util/CustomComboBoxBuilder.java +++ b/app/src/main/java/io/xpipe/app/util/CustomComboBoxBuilder.java @@ -1,7 +1,7 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; -import io.xpipe.extension.fxcomps.impl.FilterComp; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.fxcomps.impl.FilterComp; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.application.Platform; import javafx.beans.property.Property; import javafx.beans.property.SimpleStringProperty; diff --git a/extension/src/main/java/io/xpipe/extension/util/DataStoreFormatter.java b/app/src/main/java/io/xpipe/app/util/DataStoreFormatter.java similarity index 97% rename from extension/src/main/java/io/xpipe/extension/util/DataStoreFormatter.java rename to app/src/main/java/io/xpipe/app/util/DataStoreFormatter.java index ffe2ff759..f2ab70221 100644 --- a/extension/src/main/java/io/xpipe/extension/util/DataStoreFormatter.java +++ b/app/src/main/java/io/xpipe/app/util/DataStoreFormatter.java @@ -1,8 +1,8 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; +import io.xpipe.app.ext.DataStoreProviders; import io.xpipe.core.store.DataStore; import io.xpipe.core.store.ShellStore; -import io.xpipe.extension.DataStoreProviders; import java.util.function.IntFunction; diff --git a/extension/src/main/java/io/xpipe/extension/util/DataTypeParser.java b/app/src/main/java/io/xpipe/app/util/DataTypeParser.java similarity index 97% rename from extension/src/main/java/io/xpipe/extension/util/DataTypeParser.java rename to app/src/main/java/io/xpipe/app/util/DataTypeParser.java index b22d2b589..4a3e8f520 100644 --- a/extension/src/main/java/io/xpipe/extension/util/DataTypeParser.java +++ b/app/src/main/java/io/xpipe/app/util/DataTypeParser.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.data.node.ValueNode; diff --git a/extension/src/main/java/io/xpipe/extension/util/DataTypeParserInternal.java b/app/src/main/java/io/xpipe/app/util/DataTypeParserInternal.java similarity index 99% rename from extension/src/main/java/io/xpipe/extension/util/DataTypeParserInternal.java rename to app/src/main/java/io/xpipe/app/util/DataTypeParserInternal.java index 8bf3c4dc9..201b5fe47 100644 --- a/extension/src/main/java/io/xpipe/extension/util/DataTypeParserInternal.java +++ b/app/src/main/java/io/xpipe/app/util/DataTypeParserInternal.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import io.xpipe.core.data.node.ValueNode; import org.apache.commons.lang3.math.NumberUtils; diff --git a/extension/src/main/java/io/xpipe/extension/util/DesktopHelper.java b/app/src/main/java/io/xpipe/app/util/DesktopHelper.java similarity index 94% rename from extension/src/main/java/io/xpipe/extension/util/DesktopHelper.java rename to app/src/main/java/io/xpipe/app/util/DesktopHelper.java index 9c883b194..a7abfdb40 100644 --- a/extension/src/main/java/io/xpipe/extension/util/DesktopHelper.java +++ b/app/src/main/java/io/xpipe/app/util/DesktopHelper.java @@ -1,6 +1,6 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; -import io.xpipe.extension.event.ErrorEvent; +import io.xpipe.app.issue.ErrorEvent; import java.awt.*; import java.nio.file.Path; diff --git a/extension/src/main/java/io/xpipe/extension/util/DesktopShortcuts.java b/app/src/main/java/io/xpipe/app/util/DesktopShortcuts.java similarity index 99% rename from extension/src/main/java/io/xpipe/extension/util/DesktopShortcuts.java rename to app/src/main/java/io/xpipe/app/util/DesktopShortcuts.java index bbe43bf49..99abde2b1 100644 --- a/extension/src/main/java/io/xpipe/extension/util/DesktopShortcuts.java +++ b/app/src/main/java/io/xpipe/app/util/DesktopShortcuts.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import io.xpipe.core.process.OsType; import io.xpipe.core.store.ShellStore; diff --git a/extension/src/main/java/io/xpipe/extension/util/DialogHelper.java b/app/src/main/java/io/xpipe/app/util/DialogHelper.java similarity index 97% rename from extension/src/main/java/io/xpipe/extension/util/DialogHelper.java rename to app/src/main/java/io/xpipe/app/util/DialogHelper.java index cb599ee16..bd2090f0f 100644 --- a/extension/src/main/java/io/xpipe/extension/util/DialogHelper.java +++ b/app/src/main/java/io/xpipe/app/util/DialogHelper.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import io.xpipe.core.charsetter.NewLine; import io.xpipe.core.charsetter.StreamCharset; @@ -8,7 +8,7 @@ import io.xpipe.core.impl.LocalStore; import io.xpipe.core.source.DataSource; import io.xpipe.core.store.DataFlow; import io.xpipe.core.store.DataStore; -import io.xpipe.core.store.FileSystemStore; +import io.xpipe.core.store.FileSystem; import io.xpipe.core.store.ShellStore; import io.xpipe.core.util.SecretValue; import lombok.Value; @@ -37,7 +37,7 @@ public class DialogHelper { throw new IllegalArgumentException(String.format("Store not found: %s", name)); } - if (!(stored.get() instanceof FileSystemStore)) { + if (!(stored.get() instanceof FileSystem)) { throw new IllegalArgumentException(String.format("Store not a machine store: %s", name)); } diff --git a/extension/src/main/java/io/xpipe/extension/util/DynamicOptionsBuilder.java b/app/src/main/java/io/xpipe/app/util/DynamicOptionsBuilder.java similarity index 87% rename from extension/src/main/java/io/xpipe/extension/util/DynamicOptionsBuilder.java rename to app/src/main/java/io/xpipe/app/util/DynamicOptionsBuilder.java index f23da1ed5..960466c79 100644 --- a/extension/src/main/java/io/xpipe/extension/util/DynamicOptionsBuilder.java +++ b/app/src/main/java/io/xpipe/app/util/DynamicOptionsBuilder.java @@ -1,11 +1,11 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.impl.*; import io.xpipe.core.charsetter.NewLine; import io.xpipe.core.charsetter.StreamCharset; import io.xpipe.core.util.SecretValue; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.impl.*; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -43,7 +43,7 @@ public class DynamicOptionsBuilder { public DynamicOptionsBuilder addTitle(String titleKey) { entries.add(new DynamicOptionsComp.Entry( - titleKey, null, new LabelComp(I18n.observable(titleKey)).styleClass("title-header"))); + titleKey, null, new LabelComp(AppI18n.observable(titleKey)).styleClass("title-header"))); return this; } @@ -67,10 +67,10 @@ public class DynamicOptionsBuilder { public DynamicOptionsBuilder addNewLine(Property prop) { var map = new LinkedHashMap>(); for (var e : NewLine.values()) { - map.put(e, I18n.observable("extension." + e.getId())); + map.put(e, AppI18n.observable("app." + e.getId())); } var comp = new ChoiceComp<>(prop, map, false); - entries.add(new DynamicOptionsComp.Entry("newLine", I18n.observable("extension.newLine"), comp)); + entries.add(new DynamicOptionsComp.Entry("newLine", AppI18n.observable("app.newLine"), comp)); props.add(prop); return this; } @@ -99,10 +99,10 @@ public class DynamicOptionsBuilder { prop, new SimpleObjectProperty<>(Map.of( Boolean.TRUE, - I18n.observable("extension.yes"), + AppI18n.observable("app.yes"), Boolean.FALSE, - I18n.observable("extension.no")))); - entries.add(new DynamicOptionsComp.Entry(nameKey, I18n.observable(nameKey), comp)); + AppI18n.observable("app.no")))); + entries.add(new DynamicOptionsComp.Entry(nameKey, AppI18n.observable(nameKey), comp)); props.add(prop); return this; } @@ -139,28 +139,28 @@ public class DynamicOptionsBuilder { public DynamicOptionsBuilder addCharset(Property prop) { var comp = new CharsetChoiceComp(prop); - entries.add(new DynamicOptionsComp.Entry("charset", I18n.observable("extension.charset"), comp)); + entries.add(new DynamicOptionsComp.Entry("charset", AppI18n.observable("app.charset"), comp)); props.add(prop); return this; } public DynamicOptionsBuilder addStringArea(String nameKey, Property prop, boolean lazy) { var comp = new TextAreaComp(prop, lazy); - entries.add(new DynamicOptionsComp.Entry(nameKey, I18n.observable(nameKey), comp)); + entries.add(new DynamicOptionsComp.Entry(nameKey, AppI18n.observable(nameKey), comp)); props.add(prop); return this; } public DynamicOptionsBuilder addString(String nameKey, Property prop) { var comp = new TextFieldComp(prop); - entries.add(new DynamicOptionsComp.Entry(nameKey, I18n.observable(nameKey), comp)); + entries.add(new DynamicOptionsComp.Entry(nameKey, AppI18n.observable(nameKey), comp)); props.add(prop); return this; } public DynamicOptionsBuilder addString(String nameKey, Property prop, boolean lazy) { var comp = new TextFieldComp(prop, lazy); - entries.add(new DynamicOptionsComp.Entry(nameKey, I18n.observable(nameKey), comp)); + entries.add(new DynamicOptionsComp.Entry(nameKey, AppI18n.observable(nameKey), comp)); props.add(prop); return this; } @@ -188,7 +188,7 @@ public class DynamicOptionsBuilder { } public DynamicOptionsBuilder addComp(String nameKey, Comp comp, Property prop) { - entries.add(new DynamicOptionsComp.Entry(nameKey, I18n.observable(nameKey), comp)); + entries.add(new DynamicOptionsComp.Entry(nameKey, AppI18n.observable(nameKey), comp)); if (prop != null) { props.add(prop); } @@ -204,7 +204,7 @@ public class DynamicOptionsBuilder { } public DynamicOptionsBuilder addSecret(String nameKey, Property prop) { - return addSecret(I18n.observable(nameKey), prop); + return addSecret(AppI18n.observable(nameKey), prop); } public DynamicOptionsBuilder addSecret(ObservableValue name, Property prop) { @@ -223,7 +223,7 @@ public class DynamicOptionsBuilder { public DynamicOptionsBuilder addInteger(String nameKey, Property prop) { var comp = new IntFieldComp(prop); - entries.add(new DynamicOptionsComp.Entry(nameKey, I18n.observable(nameKey), comp)); + entries.add(new DynamicOptionsComp.Entry(nameKey, AppI18n.observable(nameKey), comp)); props.add(prop); return this; } diff --git a/extension/src/main/java/io/xpipe/extension/util/ExclusiveValidator.java b/app/src/main/java/io/xpipe/app/util/ExclusiveValidator.java similarity index 98% rename from extension/src/main/java/io/xpipe/extension/util/ExclusiveValidator.java rename to app/src/main/java/io/xpipe/app/util/ExclusiveValidator.java index ebe08759e..61debe35b 100644 --- a/extension/src/main/java/io/xpipe/extension/util/ExclusiveValidator.java +++ b/app/src/main/java/io/xpipe/app/util/ExclusiveValidator.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import javafx.beans.Observable; import javafx.beans.binding.Bindings; diff --git a/app/src/main/java/io/xpipe/app/util/ExternalEditor.java b/app/src/main/java/io/xpipe/app/util/ExternalEditor.java index 113b29710..c01997e1a 100644 --- a/app/src/main/java/io/xpipe/app/util/ExternalEditor.java +++ b/app/src/main/java/io/xpipe/app/util/ExternalEditor.java @@ -1,13 +1,15 @@ package io.xpipe.app.util; import io.xpipe.app.core.FileWatchManager; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; -import io.xpipe.core.charsetter.Charsetter; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.util.ThreadHelper; +import io.xpipe.core.impl.FileNames; +import io.xpipe.core.store.FileSystem; import lombok.Getter; import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.function.FailableSupplier; import java.io.*; import java.nio.charset.StandardCharsets; @@ -146,8 +148,8 @@ public class ExternalEditor { String keyName, String fileType, Object key, - Charsetter.FailableSupplier input, - Charsetter.FailableSupplier output) { + FailableSupplier input, + FailableSupplier output) { var ext = getForKey(key); if (ext.isPresent()) { openInEditor(ext.get().file.toString()); @@ -182,6 +184,17 @@ public class ExternalEditor { openInEditor(ext.orElseThrow().file.toString()); } + public void openInEditor(FileSystem fileSystem, String file) { + var editor = AppPrefs.get().externalEditor().getValue(); + if (editor == null || !editor.isSelectable()) { + return; + } + + startEditing(FileNames.getFileName(file), FilenameUtils.getExtension(file), file, () -> { + return fileSystem.openInput(file); + }, () -> fileSystem.openOutput(file)); + } + public void openInEditor(String file) { var editor = AppPrefs.get().externalEditor().getValue(); if (editor == null || !editor.isSelectable()) { diff --git a/extension/src/main/java/io/xpipe/extension/util/HostHelper.java b/app/src/main/java/io/xpipe/app/util/HostHelper.java similarity index 90% rename from extension/src/main/java/io/xpipe/extension/util/HostHelper.java rename to app/src/main/java/io/xpipe/app/util/HostHelper.java index 05780ce7c..f15d4cfcc 100644 --- a/extension/src/main/java/io/xpipe/extension/util/HostHelper.java +++ b/app/src/main/java/io/xpipe/app/util/HostHelper.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import java.util.Locale; diff --git a/extension/src/main/java/io/xpipe/extension/util/HttpHelper.java b/app/src/main/java/io/xpipe/app/util/HttpHelper.java similarity index 98% rename from extension/src/main/java/io/xpipe/extension/util/HttpHelper.java rename to app/src/main/java/io/xpipe/app/util/HttpHelper.java index d589259e9..8fc0af671 100644 --- a/extension/src/main/java/io/xpipe/extension/util/HttpHelper.java +++ b/app/src/main/java/io/xpipe/app/util/HttpHelper.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import java.io.IOException; import java.io.InputStream; diff --git a/app/src/main/java/io/xpipe/app/util/HumanReadableFormat.java b/app/src/main/java/io/xpipe/app/util/HumanReadableFormat.java new file mode 100644 index 000000000..733a678c7 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/util/HumanReadableFormat.java @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: MIT */ + +package io.xpipe.app.util; + +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.time.temporal.WeekFields; +import java.util.Locale; +import java.util.Objects; + +public final class HumanReadableFormat { + + public static final DateTimeFormatter DAY_MONTH_YEAR = DateTimeFormatter.ofPattern("d LLL yyyy"); + public static final DateTimeFormatter DAY_MONTH = DateTimeFormatter.ofPattern("d LLL"); + public static final DateTimeFormatter DAY_OF_WEEK = DateTimeFormatter.ofPattern("EEE"); + public static final DateTimeFormatter HOUR_MINUTE = DateTimeFormatter.ofPattern("HH:mm"); + + public static String byteCount(long bytes) { + if (-1000 < bytes && bytes < 1000) { + return bytes + " B"; + } + CharacterIterator ci = new StringCharacterIterator("kMGTPE"); + while (bytes <= -999_950 || bytes >= 999_950) { + bytes /= 1000; + ci.next(); + } + return String.format("%.1f %cB", bytes / 1000.0, ci.current()); + } + + public static String date(LocalDateTime x) { + Objects.requireNonNull(x); + var now = LocalDateTime.now(ZoneId.systemDefault()); + + // not this year + if (x.getYear() != now.getYear()) { + return DAY_MONTH_YEAR.format(x); + } + + // not this week + if (getWeekNumber(x) != getWeekNumber(now)) { + return DAY_MONTH.format(x); + } + + // not today + int xDay = x.getDayOfWeek().getValue(); + int nowDay = now.getDayOfWeek().getValue(); + if (xDay == nowDay - 1) { + return "Yesterday"; + } + if (xDay != nowDay) { + return DAY_OF_WEEK.format(x); + } + + return HOUR_MINUTE.format(x); + } + + private static int getWeekNumber(LocalDateTime date) { + return date.get(WeekFields.of(Locale.getDefault()).weekOfYear()); + } +} 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 6b6fa0842..c0ecfe4c9 100644 --- a/app/src/main/java/io/xpipe/app/util/Hyperlinks.java +++ b/app/src/main/java/io/xpipe/app/util/Hyperlinks.java @@ -1,7 +1,7 @@ package io.xpipe.app.util; import io.xpipe.app.core.App; -import io.xpipe.extension.event.ErrorEvent; +import io.xpipe.app.issue.ErrorEvent; import java.awt.*; import java.net.URI; 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 cf19b38e2..56db46ce6 100644 --- a/app/src/main/java/io/xpipe/app/util/JfxHelper.java +++ b/app/src/main/java/io/xpipe/app/util/JfxHelper.java @@ -1,7 +1,7 @@ package io.xpipe.app.util; import io.xpipe.app.core.AppFont; -import io.xpipe.extension.fxcomps.impl.PrettyImageComp; +import io.xpipe.app.fxcomps.impl.PrettyImageComp; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleStringProperty; import javafx.geometry.Pos; 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 0c8168a98..8a3d37653 100644 --- a/app/src/main/java/io/xpipe/app/util/JsonConfigHelper.java +++ b/app/src/main/java/io/xpipe/app/util/JsonConfigHelper.java @@ -6,8 +6,8 @@ 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 io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.util.JacksonMapper; -import io.xpipe.extension.event.ErrorEvent; import org.apache.commons.io.FileUtils; import java.io.IOException; diff --git a/app/src/main/java/io/xpipe/app/util/MacOsPermissions.java b/app/src/main/java/io/xpipe/app/util/MacOsPermissions.java index cb339ba24..9deacfd06 100644 --- a/app/src/main/java/io/xpipe/app/util/MacOsPermissions.java +++ b/app/src/main/java/io/xpipe/app/util/MacOsPermissions.java @@ -1,9 +1,8 @@ package io.xpipe.app.util; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppWindowHelper; import io.xpipe.core.store.ShellStore; -import io.xpipe.extension.I18n; -import io.xpipe.extension.util.ThreadHelper; import javafx.application.Platform; import javafx.beans.property.SimpleBooleanProperty; import javafx.scene.control.Alert; @@ -34,9 +33,9 @@ public class MacOsPermissions { AppWindowHelper.showAlert(a -> { a.setAlertType(Alert.AlertType.INFORMATION); - a.setTitle(I18n.get("permissionsAlertTitle")); - a.setHeaderText(I18n.get("permissionsAlertTitleHeader")); - a.getDialogPane().setContent(AppWindowHelper.alertContentText(I18n.get("permissionsAlertTitleContent"))); + a.setTitle(AppI18n.get("permissionsAlertTitle")); + a.setHeaderText(AppI18n.get("permissionsAlertTitleHeader")); + a.getDialogPane().setContent(AppWindowHelper.alertContentText(AppI18n.get("permissionsAlertTitleContent"))); a.getButtonTypes().clear(); alert.set(a); }, buttonType -> { diff --git a/extension/src/main/java/io/xpipe/extension/util/ModuleLayerLoader.java b/app/src/main/java/io/xpipe/app/util/ModuleLayerLoader.java similarity index 91% rename from extension/src/main/java/io/xpipe/extension/util/ModuleLayerLoader.java rename to app/src/main/java/io/xpipe/app/util/ModuleLayerLoader.java index 2276098cd..b6e7cc87d 100644 --- a/extension/src/main/java/io/xpipe/extension/util/ModuleLayerLoader.java +++ b/app/src/main/java/io/xpipe/app/util/ModuleLayerLoader.java @@ -1,6 +1,7 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; -import io.xpipe.extension.event.ErrorEvent; + +import io.xpipe.app.issue.ErrorEvent; import java.util.ServiceLoader; diff --git a/extension/src/main/java/io/xpipe/extension/util/NamedCharacter.java b/app/src/main/java/io/xpipe/app/util/NamedCharacter.java similarity index 98% rename from extension/src/main/java/io/xpipe/extension/util/NamedCharacter.java rename to app/src/main/java/io/xpipe/app/util/NamedCharacter.java index 11875a07b..63a37d8aa 100644 --- a/extension/src/main/java/io/xpipe/extension/util/NamedCharacter.java +++ b/app/src/main/java/io/xpipe/app/util/NamedCharacter.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import io.xpipe.core.dialog.QueryConverter; import lombok.Value; diff --git a/extension/src/main/java/io/xpipe/extension/util/PrettyListView.java b/app/src/main/java/io/xpipe/app/util/PrettyListView.java similarity index 99% rename from extension/src/main/java/io/xpipe/extension/util/PrettyListView.java rename to app/src/main/java/io/xpipe/app/util/PrettyListView.java index 4c9a430e7..f2c687aa0 100644 --- a/extension/src/main/java/io/xpipe/extension/util/PrettyListView.java +++ b/app/src/main/java/io/xpipe/app/util/PrettyListView.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import javafx.collections.FXCollections; import javafx.collections.ObservableList; 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 b91238aa3..fe8eebf39 100644 --- a/app/src/main/java/io/xpipe/app/util/ProxyManagerProviderImpl.java +++ b/app/src/main/java/io/xpipe/app/util/ProxyManagerProviderImpl.java @@ -1,5 +1,6 @@ package io.xpipe.app.util; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppProperties; import io.xpipe.app.core.AppWindowHelper; import io.xpipe.app.prefs.AppPrefs; @@ -10,7 +11,6 @@ import io.xpipe.core.process.ShellProcessControl; import io.xpipe.core.util.ModuleHelper; import io.xpipe.core.util.ProxyManagerProvider; import io.xpipe.core.util.XPipeInstallation; -import io.xpipe.extension.I18n; import javafx.scene.control.Alert; import java.util.Optional; @@ -20,10 +20,10 @@ public class ProxyManagerProviderImpl extends ProxyManagerProvider { private static boolean showAlert() { var okay = AppWindowHelper.showBlockingAlert(alert -> { alert.setAlertType(Alert.AlertType.CONFIRMATION); - alert.setTitle(I18n.get("connectorInstallationTitle")); - alert.setHeaderText(I18n.get("connectorInstallationHeader")); + alert.setTitle(AppI18n.get("connectorInstallationTitle")); + alert.setHeaderText(AppI18n.get("connectorInstallationHeader")); alert.getDialogPane() - .setContent(AppWindowHelper.alertContentText(I18n.get("connectorInstallationContent"))); + .setContent(AppWindowHelper.alertContentText(AppI18n.get("connectorInstallationContent"))); }) .filter(buttonType -> buttonType.getButtonData().isDefaultButton()) .isPresent(); @@ -35,19 +35,19 @@ public class ProxyManagerProviderImpl extends ProxyManagerProvider { var version = ModuleHelper.isImage() ? AppProperties.get().getVersion() : AppDownloads.getLatestVersion(); if (AppPrefs.get().developerDisableConnectorInstallationVersionCheck().get()) { - return Optional.of(I18n.get("versionCheckOverride")); + return Optional.of(AppI18n.get("versionCheckOverride")); } var defaultInstallationExecutable = FileNames.join( XPipeInstallation.getDefaultInstallationBasePath(s, false), XPipeInstallation.getDaemonExecutablePath(s.getOsType())); if (!s.executeBooleanSimpleCommand(s.getShellType().getFileExistsCommand(defaultInstallationExecutable))) { - return Optional.of(I18n.get("noInstallationFound")); + return Optional.of(AppI18n.get("noInstallationFound")); } var installationVersion = XPipeInstallation.queryInstallationVersion(s, defaultInstallationExecutable); if (!version.equals(installationVersion)) { - return Optional.of(I18n.get("installationVersionMismatch", version, installationVersion)); + return Optional.of(AppI18n.get("installationVersionMismatch", version, installationVersion)); } return Optional.empty(); diff --git a/extension/src/main/java/io/xpipe/extension/util/ScriptHelper.java b/app/src/main/java/io/xpipe/app/util/ScriptHelper.java similarity index 98% rename from extension/src/main/java/io/xpipe/extension/util/ScriptHelper.java rename to app/src/main/java/io/xpipe/app/util/ScriptHelper.java index fa0190acb..cd4d210bf 100644 --- a/extension/src/main/java/io/xpipe/extension/util/ScriptHelper.java +++ b/app/src/main/java/io/xpipe/app/util/ScriptHelper.java @@ -1,12 +1,12 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.core.impl.FileNames; import io.xpipe.core.process.ShellProcessControl; import io.xpipe.core.process.ShellType; import io.xpipe.core.process.ShellTypes; import io.xpipe.core.store.ShellStore; import io.xpipe.core.util.SecretValue; -import io.xpipe.extension.event.TrackEvent; import lombok.SneakyThrows; import java.util.Arrays; diff --git a/extension/src/main/java/io/xpipe/extension/util/SimpleValidator.java b/app/src/main/java/io/xpipe/app/util/SimpleValidator.java similarity index 99% rename from extension/src/main/java/io/xpipe/extension/util/SimpleValidator.java rename to app/src/main/java/io/xpipe/app/util/SimpleValidator.java index 2da217117..d3e308c61 100644 --- a/extension/src/main/java/io/xpipe/extension/util/SimpleValidator.java +++ b/app/src/main/java/io/xpipe/app/util/SimpleValidator.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import javafx.beans.binding.Bindings; import javafx.beans.binding.StringBinding; diff --git a/app/src/main/java/io/xpipe/app/util/TerminalHelper.java b/app/src/main/java/io/xpipe/app/util/TerminalHelper.java new file mode 100644 index 000000000..91c306d62 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/util/TerminalHelper.java @@ -0,0 +1,15 @@ +package io.xpipe.app.util; + +import io.xpipe.app.prefs.AppPrefs; + +public class TerminalHelper { + + public static void open(String title, String command) throws Exception { + if (command.contains("\n")) { + command = ScriptHelper.createLocalExecScript(command); + } + + var type = AppPrefs.get().terminalType().getValue(); + type.launch(title, command); + } +} diff --git a/app/src/main/java/io/xpipe/app/util/TerminalProvider.java b/app/src/main/java/io/xpipe/app/util/TerminalProvider.java deleted file mode 100644 index 1db3c1232..000000000 --- a/app/src/main/java/io/xpipe/app/util/TerminalProvider.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.xpipe.app.util; - -import io.xpipe.extension.util.ModuleLayerLoader; -import io.xpipe.extension.util.ScriptHelper; - -import java.util.ServiceLoader; - -public abstract class TerminalProvider { - - private static TerminalProvider INSTANCE; - - public static class Loader implements ModuleLayerLoader { - - @Override - public void init(ModuleLayer layer) { - INSTANCE = ServiceLoader.load(layer, TerminalProvider.class) - .findFirst() - .orElseThrow(); - } - - @Override - public boolean requiresFullDaemon() { - return true; - } - - @Override - public boolean prioritizeLoading() { - return false; - } - } - - public static void open(String title, String command) throws Exception { - if (command.contains("\n")) { - command = ScriptHelper.createLocalExecScript(command); - } - - INSTANCE.openInTerminal(title, command); - } - - protected abstract void openInTerminal(String title, String command) throws Exception; -} diff --git a/extension/src/main/java/io/xpipe/extension/util/ThreadHelper.java b/app/src/main/java/io/xpipe/app/util/ThreadHelper.java similarity index 92% rename from extension/src/main/java/io/xpipe/extension/util/ThreadHelper.java rename to app/src/main/java/io/xpipe/app/util/ThreadHelper.java index 2de7dc6a0..cf4fe89b1 100644 --- a/extension/src/main/java/io/xpipe/extension/util/ThreadHelper.java +++ b/app/src/main/java/io/xpipe/app/util/ThreadHelper.java @@ -1,6 +1,6 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; -import io.xpipe.extension.event.ErrorEvent; +import io.xpipe.app.issue.ErrorEvent; import org.apache.commons.lang3.function.FailableRunnable; public class ThreadHelper { diff --git a/extension/src/main/java/io/xpipe/extension/Translatable.java b/app/src/main/java/io/xpipe/app/util/Translatable.java similarity index 98% rename from extension/src/main/java/io/xpipe/extension/Translatable.java rename to app/src/main/java/io/xpipe/app/util/Translatable.java index 6c4bf83f0..c3ff046ef 100644 --- a/extension/src/main/java/io/xpipe/extension/Translatable.java +++ b/app/src/main/java/io/xpipe/app/util/Translatable.java @@ -1,4 +1,4 @@ -package io.xpipe.extension; +package io.xpipe.app.util; import javafx.beans.binding.StringBinding; import javafx.beans.binding.StringExpression; diff --git a/extension/src/main/java/io/xpipe/extension/util/TypeConverter.java b/app/src/main/java/io/xpipe/app/util/TypeConverter.java similarity index 99% rename from extension/src/main/java/io/xpipe/extension/util/TypeConverter.java rename to app/src/main/java/io/xpipe/app/util/TypeConverter.java index b28c91c0a..985a49593 100644 --- a/extension/src/main/java/io/xpipe/extension/util/TypeConverter.java +++ b/app/src/main/java/io/xpipe/app/util/TypeConverter.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.data.node.ValueNode; diff --git a/extension/src/main/java/io/xpipe/extension/util/UniformDataSourceProvider.java b/app/src/main/java/io/xpipe/app/util/UniformDataSourceProvider.java similarity index 79% rename from extension/src/main/java/io/xpipe/extension/util/UniformDataSourceProvider.java rename to app/src/main/java/io/xpipe/app/util/UniformDataSourceProvider.java index e463c79a4..a6505ee4d 100644 --- a/extension/src/main/java/io/xpipe/extension/util/UniformDataSourceProvider.java +++ b/app/src/main/java/io/xpipe/app/util/UniformDataSourceProvider.java @@ -1,8 +1,8 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; +import io.xpipe.app.ext.DataSourceProvider; import io.xpipe.core.dialog.Dialog; import io.xpipe.core.source.DataSource; -import io.xpipe.extension.DataSourceProvider; public interface UniformDataSourceProvider> extends DataSourceProvider { diff --git a/extension/src/main/java/io/xpipe/extension/util/Validatable.java b/app/src/main/java/io/xpipe/app/util/Validatable.java similarity index 66% rename from extension/src/main/java/io/xpipe/extension/util/Validatable.java rename to app/src/main/java/io/xpipe/app/util/Validatable.java index eff915560..27838d582 100644 --- a/extension/src/main/java/io/xpipe/extension/util/Validatable.java +++ b/app/src/main/java/io/xpipe/app/util/Validatable.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; public interface Validatable { diff --git a/extension/src/main/java/io/xpipe/extension/util/Validator.java b/app/src/main/java/io/xpipe/app/util/Validator.java similarity index 93% rename from extension/src/main/java/io/xpipe/extension/util/Validator.java rename to app/src/main/java/io/xpipe/app/util/Validator.java index 16f67b76f..b464d15ad 100644 --- a/extension/src/main/java/io/xpipe/extension/util/Validator.java +++ b/app/src/main/java/io/xpipe/app/util/Validator.java @@ -1,6 +1,6 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; -import io.xpipe.extension.I18n; +import io.xpipe.app.core.AppI18n; import javafx.beans.binding.StringBinding; import javafx.beans.property.ReadOnlyBooleanProperty; import javafx.beans.property.ReadOnlyObjectProperty; @@ -12,9 +12,8 @@ import org.apache.commons.lang3.function.FailableRunnable; public interface Validator { static Check nonNull(Validator v, ObservableValue name, ObservableValue s) { - return v.createCheck().dependsOn("val", s).withMethod(c -> { - if (c.get("val") == null) { - c.error(I18n.get("extension.mustNotBeEmpty", name.getValue())); + return v.createCheck().dependsOn("val", s).withMethod(c -> { if (c.get("val") == null) { + c.error(AppI18n.get("app.mustNotBeEmpty", name.getValue())); } }); } diff --git a/extension/src/main/java/io/xpipe/extension/util/Validators.java b/app/src/main/java/io/xpipe/app/util/Validators.java similarity index 55% rename from extension/src/main/java/io/xpipe/extension/util/Validators.java rename to app/src/main/java/io/xpipe/app/util/Validators.java index 7ac807927..504340c19 100644 --- a/extension/src/main/java/io/xpipe/extension/util/Validators.java +++ b/app/src/main/java/io/xpipe/app/util/Validators.java @@ -1,37 +1,36 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; +import io.xpipe.app.core.AppI18n; import io.xpipe.core.impl.LocalStore; import io.xpipe.core.store.DataStore; import io.xpipe.core.store.ShellStore; import io.xpipe.core.util.ValidationException; -import io.xpipe.extension.I18n; - -import java.util.function.Predicate; +import org.apache.commons.lang3.function.FailablePredicate; public class Validators { public static void nonNull(Object object, String name) throws ValidationException { if (object == null) { - throw new ValidationException(I18n.get("extension.mustNotBeEmpty", name)); + throw new ValidationException(AppI18n.get("app.mustNotBeEmpty", name)); } } public static void notEmpty(String string, String name) throws ValidationException { if (string.trim().length() == 0) { - throw new ValidationException(I18n.get("extension.mustNotBeEmpty", name)); + throw new ValidationException(AppI18n.get("app.mustNotBeEmpty", name)); } } public static void namedStoreExists(DataStore store, String name) throws ValidationException { if (!XPipeDaemon.getInstance().getNamedStores().contains(store) && !(store instanceof LocalStore)) { - throw new ValidationException(I18n.get("extension.missingStore", name)); + throw new ValidationException(AppI18n.get("app.missingStore", name)); } } - public static void hostFeature(ShellStore host, Predicate predicate, String name) - throws ValidationException { + public static void hostFeature(ShellStore host, FailablePredicate predicate, String name) + throws Exception { if (!predicate.test(host)) { - throw new ValidationException(I18n.get("extension.hostFeatureUnsupported", name)); + throw new ValidationException(AppI18n.get("app.hostFeatureUnsupported", name)); } } } diff --git a/extension/src/main/java/io/xpipe/extension/util/WindowsRegistry.java b/app/src/main/java/io/xpipe/app/util/WindowsRegistry.java similarity index 96% rename from extension/src/main/java/io/xpipe/extension/util/WindowsRegistry.java rename to app/src/main/java/io/xpipe/app/util/WindowsRegistry.java index 1673b0a3d..581cb53b9 100644 --- a/extension/src/main/java/io/xpipe/extension/util/WindowsRegistry.java +++ b/app/src/main/java/io/xpipe/app/util/WindowsRegistry.java @@ -1,4 +1,4 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; import com.sun.jna.platform.win32.Advapi32Util; import com.sun.jna.platform.win32.WinReg; diff --git a/extension/src/main/java/io/xpipe/extension/util/XPipeDaemon.java b/app/src/main/java/io/xpipe/app/util/XPipeDaemon.java similarity index 92% rename from extension/src/main/java/io/xpipe/extension/util/XPipeDaemon.java rename to app/src/main/java/io/xpipe/app/util/XPipeDaemon.java index 7469bf637..0540451ef 100644 --- a/extension/src/main/java/io/xpipe/extension/util/XPipeDaemon.java +++ b/app/src/main/java/io/xpipe/app/util/XPipeDaemon.java @@ -1,12 +1,12 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.fxcomps.Comp; import io.xpipe.core.charsetter.Charsetter; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.fxcomps.Comp; import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; import javafx.scene.image.Image; diff --git a/app/src/main/java/io/xpipe/app/util/XPipeDaemonProvider.java b/app/src/main/java/io/xpipe/app/util/XPipeDaemonProvider.java index c62f8f165..5a107a19a 100644 --- a/app/src/main/java/io/xpipe/app/util/XPipeDaemonProvider.java +++ b/app/src/main/java/io/xpipe/app/util/XPipeDaemonProvider.java @@ -7,6 +7,9 @@ import io.xpipe.app.comp.source.store.NamedStoreChoiceComp; import io.xpipe.app.core.AppImages; import io.xpipe.app.core.AppProperties; import io.xpipe.app.core.AppResources; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.update.AppDownloads; @@ -16,11 +19,6 @@ import io.xpipe.core.source.DataSourceId; import io.xpipe.core.source.DataSourceReference; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.util.Validatable; -import io.xpipe.extension.util.XPipeDaemon; import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; import javafx.scene.image.Image; diff --git a/extension/src/main/java/io/xpipe/extension/util/XPipeDistributionType.java b/app/src/main/java/io/xpipe/app/util/XPipeDistributionType.java similarity index 96% rename from extension/src/main/java/io/xpipe/extension/util/XPipeDistributionType.java rename to app/src/main/java/io/xpipe/app/util/XPipeDistributionType.java index e70ac4a3d..616662d5f 100644 --- a/extension/src/main/java/io/xpipe/extension/util/XPipeDistributionType.java +++ b/app/src/main/java/io/xpipe/app/util/XPipeDistributionType.java @@ -1,9 +1,9 @@ -package io.xpipe.extension.util; +package io.xpipe.app.util; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.core.process.OsType; import io.xpipe.core.util.ModuleHelper; import io.xpipe.core.util.XPipeInstallation; -import io.xpipe.extension.event.TrackEvent; public interface XPipeDistributionType { diff --git a/app/src/main/java/module-info.java b/app/src/main/java/module-info.java index dd995ca6a..f2fbcc1a4 100644 --- a/app/src/main/java/module-info.java +++ b/app/src/main/java/module-info.java @@ -1,21 +1,15 @@ -import io.xpipe.app.core.AppCache; -import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppLogs; import io.xpipe.app.exchange.*; import io.xpipe.app.exchange.api.*; import io.xpipe.app.exchange.cli.*; +import io.xpipe.app.ext.*; +import io.xpipe.app.issue.EventHandler; import io.xpipe.app.issue.EventHandlerImpl; import io.xpipe.app.storage.DataStateProviderImpl; -import io.xpipe.app.util.ProxyManagerProviderImpl; -import io.xpipe.app.util.TerminalProvider; -import io.xpipe.app.util.XPipeDaemonProvider; +import io.xpipe.app.util.*; import io.xpipe.core.util.DataStateProvider; +import io.xpipe.core.util.ProxyFunction; import io.xpipe.core.util.ProxyManagerProvider; -import io.xpipe.extension.Cache; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.EventHandler; -import io.xpipe.extension.util.ModuleLayerLoader; -import io.xpipe.extension.util.XPipeDaemon; import org.slf4j.spi.SLF4JServiceProvider; open module io.xpipe.app { @@ -32,6 +26,12 @@ open module io.xpipe.app { exports io.xpipe.app.update; exports io.xpipe.app.comp.storage; exports io.xpipe.app.comp.storage.collection; + exports io.xpipe.app.ext; + exports io.xpipe.app.fxcomps.impl; + exports io.xpipe.app.fxcomps; + exports io.xpipe.app.fxcomps.util; + exports io.xpipe.app.fxcomps.augment; + exports io.xpipe.app.test; requires com.sun.jna; requires com.sun.jna.platform; @@ -50,16 +50,17 @@ open module io.xpipe.app { requires net.synedra.validatorfx; requires org.fxmisc.undofx; requires org.fxmisc.wellbehavedfx; + requires org.kordamp.ikonli.feather; requires org.reactfx; requires com.dustinredmond.fxtrayicon; requires io.xpipe.modulefs; - requires io.xpipe.extension; requires io.xpipe.core; requires static lombok; requires java.desktop; requires org.apache.commons.io; requires org.apache.commons.lang3; requires javafx.base; + requires static org.junit.jupiter.api; requires javafx.controls; requires javafx.media; requires javafx.web; @@ -99,20 +100,30 @@ open module io.xpipe.app { // For debugging requires jdk.jdwp.agent; + requires org.kordamp.ikonli.core; + requires static io.xpipe.api; uses MessageExchangeImpl; - uses io.xpipe.app.util.TerminalProvider; + uses TerminalHelper; + uses io.xpipe.app.ext.ActionProvider; + + uses DataSourceProvider; + uses DataSourceTarget; + uses EventHandler; + uses PrefsProvider; + uses DataStoreProvider; + uses XPipeDaemon; + uses ProxyFunction; + uses ModuleLayerLoader; provides ModuleLayerLoader with - TerminalProvider.Loader; + DataSourceTarget.Loader, + ActionProvider.Loader, + PrefsProvider.Loader; provides DataStateProvider with DataStateProviderImpl; provides ProxyManagerProvider with ProxyManagerProviderImpl; - provides I18n with - AppI18n; - provides Cache with - AppCache; provides SLF4JServiceProvider with AppLogs.Slf4jProvider; provides EventHandler with 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 172d7b812..bc6cf4436 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 @@ -77,3 +77,18 @@ developerShowHiddenProviders=Show hidden providers developerShowHiddenProvidersDescription=Controls whether hidden and internal connection and data source providers will be shown in the creation dialog. developerDisableConnectorInstallationVersionCheck=Disable Connector Version Check developerDisableConnectorInstallationVersionCheckDescription=Controls whether the update checker will ignore the version number when inspecting the version of an X-Pipe connector installed on a remote machine. +konsole=Konsole +xfce=Xfce +macosTerminal=Terminal.app +iterm2=iTerm2 +warp=Warp +terminal=Terminal +terminalProgram=Default program +terminalProgramDescription=The default terminal to use when opening any kind of shell. +program=Program +customTerminalCommand=Custom terminal command +customTerminalCommandDescription=The command to use to open the custom terminal. The placeholder string $cmd will be replaced by the actual command when called. If you don't specify a placeholder command, the actual command will be appended. +cmd=cmd.exe +powershell=Powershell +windowsTerminal=Windows Terminal +gnomeTerminal=Gnome Terminal \ No newline at end of file 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 da04e603f..f68129fe7 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,3 +1,34 @@ +charset=Charset +newLine=Newline +crlf=CRLF (Windows) +lf=LF (Linux) +none=None +common=Common +other=Other +nullPointer=Null Pointer +mustNotBeEmpty=$NAME$ must not be empty +null=$VALUE$ must be not null +hostFeatureUnsupported=Host does not support the feature $FEATURE$ +missingStore=$NAME$ does not exist +unknown=Unknown +namedHostFeatureUnsupported=$HOST$ does not support this feature +namedHostNotActive=$HOST$ is not active +noInformationAvailable=No information available +localMachine=Local Machine +input=Input +output=Output +inout=Transformation +inputDescription=This store only produces input for data sources to read +outputDescription=This store only accepts output from data sources to write +inoutDescription=This store uses both input and output to essentially create a data transformation +replace=Replace +append=Append +prepend=Prepend +replaceDescription=Replaces all content +appendDescription=Appends the new content to the existing content +prependDescription=Prepends the new content to the existing content +yes=Yes +no=No 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. Note that this operation may take some time. @@ -82,7 +113,6 @@ pluma=Pluma textEdit=Text Edit sublime=Sublime Text newTable=new_table -unknown=Unknown editRaw=Edit Raw file=File # Sidebar @@ -96,6 +126,7 @@ developer=Developer # Comps browseFileTitle=Browse file browse=Browse +browser=Browser selectFileFromComputer=Select a file from this computer # About links=Useful links diff --git a/app/src/main/resources/io/xpipe/app/resources/style/simple-alert.css b/app/src/main/resources/io/xpipe/app/resources/style/alert.css similarity index 76% rename from app/src/main/resources/io/xpipe/app/resources/style/simple-alert.css rename to app/src/main/resources/io/xpipe/app/resources/style/alert.css index 189dcf8fc..27d3fc5a5 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/simple-alert.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/alert.css @@ -11,11 +11,11 @@ .dialog-pane:no-header > *.button-bar > *.container { -fx-border-width: 1px 0 0 0; --fx-border-color:-color-accent-fg; +-fx-border-color: -color-neutral-emphasis; } .dialog-pane:header .header-panel { --fx-background-color: -color-accent-subtle; +-fx-background-color: -color-neutral-muted; } .dialog-pane:header .header-panel .graphic-container { @@ -25,23 +25,23 @@ .dialog-pane:header > .content { -fx-border-width: 2px 0 0 0; -fx-border-color:-color-accent-fg; --fx-background-color: -color-accent-subtle; +-fx-background-color: -color-neutral-muted; -fx-border-insets: 0 1.333em 1em 1em; -fx-padding: 1.333em 0 0 0; } .content-text { - -fx-text-fill: -color-accent-fg; + -fx-text-fill: -color-fg-default; } .dialog-pane:header .content.label { - -fx-text-fill: -color-accent-fg; + -fx-text-fill: -color-fg-default; } .dialog-pane:header .header-panel .label { -fx-font-size: 1.0em; -fx-wrap-text: true; - -fx-text-fill: -color-accent-fg; + -fx-text-fill: -color-fg-default; } .dialog-pane:header { @@ -50,7 +50,7 @@ .dialog-pane:header > *.button-bar > *.container { -fx-border-width: 1px 0 0 0; --fx-border-color: -color-accent-fg; +-fx-border-color: -color-neutral-emphasis; } .dialog-pane:header > *.label.content{ 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 new file mode 100644 index 000000000..0d2324245 --- /dev/null +++ b/app/src/main/resources/io/xpipe/app/resources/style/browser.css @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: MIT */ + +.browser .bookmark-list { + -fx-border-width: 0 0 1 1; +} + +.browser .tool-bar { + -fx-border-width: 1 0 1 0; +} + +.browser .breadcrumbs >.divider { + -fx-padding: 0; +} + +.browser .tab-content-area { -fx-padding: 0; } + +.browser .table-directory-view .table-view { + -color-header-bg: -color-bg-default; + -color-cell-bg-selected: -color-neutral-emphasis; + -color-cell-fg-selected: -color-fg-emphasis; + -fx-border-width: 0; +} + +/* setting opacity directly to the .table-cell or .table-row-cell + leads to incorrect table row height calculation #javafx-bug */ +.browser .table-row-cell:hidden >.table-cell > * { + -fx-opacity: 0.6; +} + +.browser .table-row-cell:drag { + -fx-background-color: -color-neutral-emphasis; +} diff --git a/extension/src/main/resources/io/xpipe/extension/resources/style/code-snippet.css b/app/src/main/resources/io/xpipe/app/resources/style/code-snippet.css similarity index 100% rename from extension/src/main/resources/io/xpipe/extension/resources/style/code-snippet.css rename to app/src/main/resources/io/xpipe/app/resources/style/code-snippet.css diff --git a/app/src/main/resources/io/xpipe/app/resources/style/error-handler-comp.css b/app/src/main/resources/io/xpipe/app/resources/style/error-handler-comp.css index cda3fddb9..cf3afc989 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/error-handler-comp.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/error-handler-comp.css @@ -28,6 +28,6 @@ -fx-border-color:-color-accent-fg; -fx-border-width: 0.1em 0 0 0; -fx-padding: 1.0em 1.5em 1em 1.5em; --fx-background-color: -color-accent-subtle; +-fx-background-color: -color-neutral-muted; -fx-effect: dropshadow(three-pass-box, #333, 6, 0, 0, -1); } 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 9a0b77e19..49f597b78 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 @@ -1,7 +1,7 @@ .bar { -fx-padding: 0.8em 1.0em 0.8em 1.0em; --fx-background-color: -color-accent-subtle; --fx-border-color: -color-accent-emphasis; +-fx-background-color: -color-neutral-muted; +-fx-border-color: -color-neutral-emphasis; } .store-header-bar { @@ -30,7 +30,7 @@ .bar .button-comp { -fx-border-width: 0; --fx-border-color: -color-accent-emphasis; +-fx-border-color: -color-neutral-emphasis; -fx-background-color: transparent; -fx-border-radius: 2px; -fx-background-radius: 2px; @@ -47,7 +47,7 @@ -fx-background-radius: 0 0 2px 2px; -fx-border-radius: 0 0 2px 2px; -fx-border-width: 0 2px 2px 2px; --fx-background-color: -color-accent-subtle; +-fx-background-color: -color-neutral-muted; } .entry-bar .horizontal-comp { @@ -75,7 +75,7 @@ -fx-background-color: -color-bg-default; -fx-border-width: 0.05em; -fx-border-radius: 0.5em; --fx-border-color: -color-accent-emphasis; +-fx-border-color: -color-neutral-emphasis; } .filter-bar .input-line { -fx-opacity: 0.2; diff --git a/app/src/main/resources/io/xpipe/app/resources/style/lazy-text-field-comp.css b/app/src/main/resources/io/xpipe/app/resources/style/lazy-text-field-comp.css index 954e00fdb..c0e3564ff 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/lazy-text-field-comp.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/lazy-text-field-comp.css @@ -6,6 +6,6 @@ -fx-opacity: 0; } -.lazy-text-field-comp.text-field .input-line { --fx-opacity: 0.4; +.lazy-text-field-comp .input-line { +-fx-opacity: 0.0; } \ No newline at end of file diff --git a/app/src/main/resources/io/xpipe/app/resources/style/multi-step-comp.css b/app/src/main/resources/io/xpipe/app/resources/style/multi-step-comp.css index 508daa06f..ffc1ca8da 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/multi-step-comp.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/multi-step-comp.css @@ -9,10 +9,9 @@ } .multi-step-comp > .top { - -fx-border-color: -color-accent-fg; + -fx-border-color: -color-neutral-emphasis; -fx-border-width: 0 0 0.1em 0; --fx-background-color: -color-accent-subtle; --fx-effect: dropshadow(three-pass-box, #333, 6, 0, 0, 2); +-fx-background-color: -color-neutral-muted; } .multi-step-comp > .top .name { @@ -24,11 +23,10 @@ } .multi-step-comp .buttons { --fx-border-color: -color-accent-fg; +-fx-border-color: -color-neutral-emphasis; -fx-border-width: 0.1em 0 0 0; -fx-padding: 1em; --fx-background-color: -color-accent-subtle; --fx-effect: dropshadow(three-pass-box, #333, 6, 0, 0, -1); +-fx-background-color: -color-neutral-muted; } .multi-step-comp .circle { 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 ad883d3a0..fa7da75b6 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 @@ -1,8 +1,8 @@ .sidebar-comp { -fx-pref-width: 7em; --fx-background-color: -color-accent-subtle; +-fx-background-color: -color-neutral-muted; -fx-border-width: 0 0 0 0.05em; --fx-border-color: -color-accent-emphasis; +-fx-border-color: -color-neutral-emphasis; -fx-padding: 0; } 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 index fdba14673..6013dd455 100644 --- 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 @@ -58,19 +58,6 @@ -fx-pref-height: 1px; } -.storage-group-list-comp .list-cell:even { --fx-background-color:transparent; -} - -.storage-group-list-comp .list-cell:odd { --fx-background-color:transparent; -} - -.storage-group-list-comp .list-cell { --fx-padding: 0; --fx-focus-color: transparent; -} - .storage-group-list-comp .list-cell { -fx-padding: 0; -fx-focus-color: transparent; diff --git a/app/src/main/resources/io/xpipe/app/resources/style/tab-pane.css b/app/src/main/resources/io/xpipe/app/resources/style/tab-pane.css index b74c22897..c8f3e5215 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/tab-pane.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/tab-pane.css @@ -8,6 +8,6 @@ -fx-font-size: 1em; } -.tab-content-area { +.jfx-tab-pane .tab-content-area { -fx-padding: 0.5em, 0, 0, 0; } \ No newline at end of file diff --git a/app/src/test/java/test/DataSourceTest.java b/app/src/test/java/test/DataSourceTest.java index f3dfd6875..c30716f60 100644 --- a/app/src/test/java/test/DataSourceTest.java +++ b/app/src/test/java/test/DataSourceTest.java @@ -1,11 +1,11 @@ package test; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceProviders; import io.xpipe.core.data.node.ArrayNode; import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.impl.InMemoryStore; import io.xpipe.core.source.*; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceProviders; import lombok.SneakyThrows; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; diff --git a/app/src/test/java/test/TestSourcesDatabase.java b/app/src/test/java/test/TestSourcesDatabase.java index 90d552dab..fd5b6960c 100644 --- a/app/src/test/java/test/TestSourcesDatabase.java +++ b/app/src/test/java/test/TestSourcesDatabase.java @@ -1,10 +1,10 @@ package test; +import io.xpipe.app.ext.DataSourceProviders; import io.xpipe.core.impl.FileStore; import io.xpipe.core.source.DataSource; import io.xpipe.core.store.DataStore; import io.xpipe.core.store.StreamDataStore; -import io.xpipe.extension.DataSourceProviders; import lombok.SneakyThrows; import java.util.ArrayList; diff --git a/core/src/main/java/io/xpipe/core/impl/FileNames.java b/core/src/main/java/io/xpipe/core/impl/FileNames.java index 2322c2b92..9c943fe45 100644 --- a/core/src/main/java/io/xpipe/core/impl/FileNames.java +++ b/core/src/main/java/io/xpipe/core/impl/FileNames.java @@ -10,7 +10,8 @@ public class FileNames { if (split.length == 0) { return ""; } - return split[split.length - 1]; + var components = Arrays.stream(split).filter(s -> !s.isEmpty()).toList(); + return components.get(components.size() - 1); } public static String join(String... parts) { @@ -38,6 +39,10 @@ public class FileNames { return normalize(file).startsWith(normalize(start)); } + public static String relativize(String from, String to) { + return normalize(to).substring(normalize(from).length()); + } + public static String normalize(String file) { var backslash = file.contains("\\"); return backslash ? toWindows(file) : toUnix(file); diff --git a/core/src/main/java/io/xpipe/core/impl/FileStore.java b/core/src/main/java/io/xpipe/core/impl/FileStore.java index 2a519d8d6..6da25776c 100644 --- a/core/src/main/java/io/xpipe/core/impl/FileStore.java +++ b/core/src/main/java/io/xpipe/core/impl/FileStore.java @@ -72,21 +72,21 @@ public class FileStore extends JacksonizedValue implements FilenameStore, Stream @Override public InputStream openInput() throws Exception { - return fileSystem.openInput(file); + return fileSystem.createFileSystem().open().openInput(file); } @Override public OutputStream openOutput() throws Exception { - if (!fileSystem.mkdirs(getParent())) { + if (!fileSystem.createFileSystem().open().mkdirs(getParent())) { throw new IOException("Unable to create directory: " + getParent()); } - return fileSystem.openOutput(file); + return fileSystem.createFileSystem().open().openOutput(file); } @Override public boolean canOpen() throws Exception { - return fileSystem.exists(file); + return fileSystem.createFileSystem().open().exists(file); } @Override diff --git a/core/src/main/java/io/xpipe/core/impl/LocalStore.java b/core/src/main/java/io/xpipe/core/impl/LocalStore.java index 06f639fb4..2c85aa030 100644 --- a/core/src/main/java/io/xpipe/core/impl/LocalStore.java +++ b/core/src/main/java/io/xpipe/core/impl/LocalStore.java @@ -3,14 +3,16 @@ package io.xpipe.core.impl; import com.fasterxml.jackson.annotation.JsonTypeName; import io.xpipe.core.process.ProcessControlProvider; import io.xpipe.core.process.ShellProcessControl; -import io.xpipe.core.store.FileSystemStore; -import io.xpipe.core.store.MachineStore; +import io.xpipe.core.store.*; import io.xpipe.core.util.JacksonizedValue; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; +import java.util.stream.Stream; @JsonTypeName("local") public class LocalStore extends JacksonizedValue implements FileSystemStore, MachineStore { @@ -21,30 +23,80 @@ public class LocalStore extends JacksonizedValue implements FileSystemStore, Mac } @Override - public boolean exists(String file) { - return Files.exists(Path.of(file)); - } + public FileSystem createFileSystem() { + if (true) return new ConnectionFileSystem(ShellStore.local().create()); + return new FileSystem() { + @Override + public FileSystem open() throws Exception { + return this; + } - @Override - public boolean mkdirs(String file) throws Exception { - try { - Files.createDirectories(Path.of(file)); - return true; - } catch (Exception ex) { - return false; - } - } + @Override + public boolean exists(String file) { + return Files.exists(Path.of(file)); + } - @Override - public InputStream openInput(String file) throws Exception { - var p = Path.of(file); - return Files.newInputStream(p); - } + @Override + public void delete(String file) throws Exception { - @Override - public OutputStream openOutput(String file) throws Exception { - var p = Path.of(file); - return Files.newOutputStream(p); + } + + @Override + public void copy(String file, String newFile) throws Exception { + + } + + @Override + public void move(String file, String newFile) throws Exception { + + } + + @Override + public boolean mkdirs(String file) throws Exception { + try { + Files.createDirectories(Path.of(file)); + return true; + } catch (Exception ex) { + return false; + } + } + + @Override + public void touch(String file) throws Exception { + } + + @Override + public boolean isDirectory(String file) throws Exception { + return Files.isDirectory(Path.of(file)); + } + + @Override + public Stream listFiles(String file) throws Exception { + return null; + } + + @Override + public List listRoots() throws Exception { + return null; + } + + @Override + public InputStream openInput(String file) throws Exception { + var p = Path.of(file); + return Files.newInputStream(p); + } + + @Override + public OutputStream openOutput(String file) throws Exception { + var p = Path.of(file); + return Files.newOutputStream(p); + } + + @Override + public void close() throws IOException { + + } + }; } @Override 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 20803e304..d6c8ce2e5 100644 --- a/core/src/main/java/io/xpipe/core/process/CommandProcessControl.java +++ b/core/src/main/java/io/xpipe/core/process/CommandProcessControl.java @@ -1,5 +1,8 @@ package io.xpipe.core.process; +import io.xpipe.core.charsetter.Charsetter; +import lombok.SneakyThrows; + import java.io.*; import java.nio.charset.Charset; import java.util.concurrent.atomic.AtomicReference; @@ -14,6 +17,10 @@ public interface CommandProcessControl extends ProcessControl { CommandProcessControl complex(); + CommandProcessControl workingDirectory(String directory); + + ShellProcessControl getParent(); + default InputStream startExternalStdout() throws Exception { try { start(); @@ -23,11 +30,13 @@ public interface CommandProcessControl extends ProcessControl { return new FilterInputStream(getStdout()) { @Override + @SneakyThrows public void close() throws IOException { CommandProcessControl.this.close(); if (!err.get().isEmpty()) { throw new IOException(err.get()); } + CommandProcessControl.this.getParent().restart(); } }; } catch (Exception ex) { @@ -43,9 +52,11 @@ public interface CommandProcessControl extends ProcessControl { discardErr(); return new FilterOutputStream(getStdin()) { @Override + @SneakyThrows public void close() throws IOException { closeStdin(); CommandProcessControl.this.close(); + CommandProcessControl.this.getParent().restart(); } }; } catch (Exception ex) { @@ -67,6 +78,7 @@ public interface CommandProcessControl extends ProcessControl { CommandProcessControl exitTimeout(Integer timeout); + public void withStdoutOrThrow(Charsetter.FailableConsumer c) throws Exception; String readOnlyStdout() throws Exception; public void discardOrThrow() throws Exception; @@ -77,14 +89,6 @@ public interface CommandProcessControl extends ProcessControl { public String readOrThrow() throws Exception; - public default boolean startAndCheckExit() { - try (var pc = start()) { - return pc.discardAndCheckExit(); - } catch (Exception e) { - return false; - } - } - public default boolean discardAndCheckExit() { try { discardOrThrow(); diff --git a/core/src/main/java/io/xpipe/core/process/ShellProcessControl.java b/core/src/main/java/io/xpipe/core/process/ShellProcessControl.java index 27b7f403a..6546db066 100644 --- a/core/src/main/java/io/xpipe/core/process/ShellProcessControl.java +++ b/core/src/main/java/io/xpipe/core/process/ShellProcessControl.java @@ -91,6 +91,8 @@ public interface ShellProcessControl extends ProcessControl { void executeLine(String command) throws Exception; + void cd(String directory) throws Exception; + @Override ShellProcessControl start() throws Exception; diff --git a/core/src/main/java/io/xpipe/core/process/ShellType.java b/core/src/main/java/io/xpipe/core/process/ShellType.java index 7eaa602a5..4fe80f389 100644 --- a/core/src/main/java/io/xpipe/core/process/ShellType.java +++ b/core/src/main/java/io/xpipe/core/process/ShellType.java @@ -2,19 +2,29 @@ package io.xpipe.core.process; import com.fasterxml.jackson.annotation.JsonTypeInfo; import io.xpipe.core.charsetter.NewLine; +import io.xpipe.core.store.FileSystem; import java.nio.charset.Charset; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import java.util.stream.Stream; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") public interface ShellType { + default String getCdCommand(String directory){ + return "cd \"" + directory + "\""; + } + String getScriptFileEnding(); String addInlineVariablesToCommand(Map variables, String command); + Stream listFiles(FileSystem fs, ShellProcessControl control, String dir) throws Exception; + + Stream listRoots(ShellProcessControl control) throws Exception; + String getPauseCommand(); String prepareScriptContent(String content); @@ -77,6 +87,12 @@ public interface ShellType { String getFileReadCommand(String file); + String getPrintWorkingDirectoryCommand(); + + String getFileCopyCommand(String oldFile, String newFile); + + String getFileMoveCommand(String oldFile, String newFile); + String getStreamFileWriteCommand(String file); String getTextFileWriteCommand(String content, String file); diff --git a/core/src/main/java/io/xpipe/core/source/CollectionDataSource.java b/core/src/main/java/io/xpipe/core/source/CollectionDataSource.java index 43e9d85b3..3e2910fab 100644 --- a/core/src/main/java/io/xpipe/core/source/CollectionDataSource.java +++ b/core/src/main/java/io/xpipe/core/source/CollectionDataSource.java @@ -1,32 +1,16 @@ package io.xpipe.core.source; import io.xpipe.core.store.DataStore; -import lombok.Singular; import lombok.experimental.SuperBuilder; -import java.util.Map; - @SuperBuilder public abstract class CollectionDataSource extends DataSource { - @Singular - private final Map preferredProviders; - @Override public DataSourceType getType() { return DataSourceType.COLLECTION; } - public CollectionDataSource annotate(String file, String provider) { - preferredProviders.put(file, provider); - return this; - } - - public CollectionDataSource annotate(Map preferredProviders) { - this.preferredProviders.putAll(preferredProviders); - return this; - } - public final CollectionReadConnection openReadConnection() throws Exception { if (!isComplete()) { throw new UnsupportedOperationException(); @@ -46,5 +30,5 @@ public abstract class CollectionDataSource extends DataSou protected abstract CollectionWriteConnection newWriteConnection(WriteMode mode); - protected abstract CollectionReadConnection newReadConnection(); + protected abstract CollectionReadConnection newReadConnection() throws Exception; } diff --git a/core/src/main/java/io/xpipe/core/source/CollectionReadConnection.java b/core/src/main/java/io/xpipe/core/source/CollectionReadConnection.java index f2342999f..cde2e8baf 100644 --- a/core/src/main/java/io/xpipe/core/source/CollectionReadConnection.java +++ b/core/src/main/java/io/xpipe/core/source/CollectionReadConnection.java @@ -1,13 +1,12 @@ package io.xpipe.core.source; -import io.xpipe.core.impl.CollectionEntryDataStore; import lombok.SneakyThrows; import java.util.stream.Stream; public interface CollectionReadConnection extends DataSourceReadConnection { - Stream listEntries() throws Exception; + Stream> listEntries() throws Exception; @SneakyThrows default void forward(DataSourceConnection con) throws Exception { diff --git a/core/src/main/java/io/xpipe/core/store/ConnectionFileSystem.java b/core/src/main/java/io/xpipe/core/store/ConnectionFileSystem.java new file mode 100644 index 000000000..a0e2ded14 --- /dev/null +++ b/core/src/main/java/io/xpipe/core/store/ConnectionFileSystem.java @@ -0,0 +1,115 @@ +package io.xpipe.core.store; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.xpipe.core.process.ShellProcessControl; +import lombok.Getter; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.stream.Stream; + +@Getter +public class ConnectionFileSystem implements FileSystem { + + @JsonIgnore + private final ShellProcessControl shellProcessControl; + + public ConnectionFileSystem(ShellProcessControl shellProcessControl) { + this.shellProcessControl = shellProcessControl; + } + + @Override + public List listRoots() throws Exception { + return shellProcessControl.getShellType().listRoots(shellProcessControl).toList(); + } + + @Override + public boolean isDirectory(String file) throws Exception{return true;} + + @Override + public Stream listFiles(String file) throws Exception { + return shellProcessControl.getShellType().listFiles(this, shellProcessControl, file); + } + + @Override + public FileSystem open() throws Exception { + shellProcessControl.start(); + return this; + } + + @Override + public InputStream openInput(String file) throws Exception { + return shellProcessControl.command(proc -> + proc.getShellType().getFileReadCommand(proc.getOsType().normalizeFileName(file))) + .startExternalStdout(); + } + + @Override + public OutputStream openOutput(String file) throws Exception { + return shellProcessControl.command(proc -> proc.getShellType() + .getStreamFileWriteCommand(proc.getOsType().normalizeFileName(file))) + .startExternalStdin(); + } + + @Override + public boolean exists(String file) throws Exception { + try (var pc = shellProcessControl.command(proc -> proc.getShellType() + .getFileExistsCommand(proc.getOsType().normalizeFileName(file))) + .start()) { + return pc.discardAndCheckExit(); + } + } + + @Override + public void delete(String file) throws Exception { + try (var pc = shellProcessControl.command(proc -> proc.getShellType() + .getFileDeleteCommand(proc.getOsType().normalizeFileName(file))) + .start()) { + pc.discardOrThrow(); + } + } + + @Override + public void copy(String file, String newFile) throws Exception { + try (var pc = shellProcessControl.command(proc -> proc.getShellType() + .getFileCopyCommand(proc.getOsType().normalizeFileName(file), proc.getOsType().normalizeFileName(newFile))).complex() + .start()) { + pc.discardOrThrow(); + } + } + + @Override + public void move(String file, String newFile) throws Exception { + try (var pc = shellProcessControl.command(proc -> proc.getShellType() + .getFileMoveCommand(proc.getOsType().normalizeFileName(file), proc.getOsType().normalizeFileName(newFile))).complex() + .start()) { + pc.discardOrThrow(); + } + } + + @Override + public boolean mkdirs(String file) throws Exception { + try (var pc = shellProcessControl.command(proc -> proc.getShellType() + .flatten(proc.getShellType() + .getMkdirsCommand(proc.getOsType().normalizeFileName(file)))) + .start()) { + return pc.discardAndCheckExit(); + } + } + + @Override + public void touch(String file) throws Exception { + try (var pc = shellProcessControl.command(proc -> proc.getShellType() + .getFileTouchCommand(proc.getOsType().normalizeFileName(file))).complex() + .start()) { + pc.discardOrThrow(); + } + } + + @Override + public void close() throws IOException { + shellProcessControl.close(); + } +} diff --git a/core/src/main/java/io/xpipe/core/store/FileSystem.java b/core/src/main/java/io/xpipe/core/store/FileSystem.java new file mode 100644 index 000000000..370dff011 --- /dev/null +++ b/core/src/main/java/io/xpipe/core/store/FileSystem.java @@ -0,0 +1,61 @@ +package io.xpipe.core.store; + +import lombok.NonNull; +import lombok.Value; + +import java.io.Closeable; +import java.io.InputStream; +import java.io.OutputStream; +import java.time.Instant; +import java.util.List; +import java.util.stream.Stream; + +public interface FileSystem extends Closeable, AutoCloseable { + + @Value + static class FileEntry { + @NonNull + FileSystem fileSystem; + @NonNull + String path; + @NonNull + Instant date; + boolean directory; + boolean hidden; + long size; + } + + FileSystem open() throws Exception; + + InputStream openInput(String file) throws Exception; + + OutputStream openOutput(String file) throws Exception; + + public boolean exists(String file) throws Exception; + + public void delete(String file) throws Exception; + + void copy(String file, String newFile) throws Exception; + + void move(String file, String newFile) throws Exception; + + boolean mkdirs(String file) throws Exception; + + void touch(String file) throws Exception; + + boolean isDirectory(String file) throws Exception; + + Stream listFiles(String file) throws Exception; + + default Stream listFilesRecursively(String file) throws Exception { + return listFiles(file).flatMap(fileEntry -> { + try { + return listFilesRecursively(fileEntry.getPath()); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + List listRoots() throws Exception; +} diff --git a/core/src/main/java/io/xpipe/core/store/FileSystemStore.java b/core/src/main/java/io/xpipe/core/store/FileSystemStore.java index db133990a..1c8f01460 100644 --- a/core/src/main/java/io/xpipe/core/store/FileSystemStore.java +++ b/core/src/main/java/io/xpipe/core/store/FileSystemStore.java @@ -1,15 +1,6 @@ package io.xpipe.core.store; -import java.io.InputStream; -import java.io.OutputStream; - public interface FileSystemStore extends DataStore { - InputStream openInput(String file) throws Exception; - - OutputStream openOutput(String file) throws Exception; - - public boolean exists(String file) throws Exception; - - boolean mkdirs(String file) throws Exception; + FileSystem createFileSystem(); } diff --git a/core/src/main/java/io/xpipe/core/store/MachineStore.java b/core/src/main/java/io/xpipe/core/store/MachineStore.java index e60278886..a9403f987 100644 --- a/core/src/main/java/io/xpipe/core/store/MachineStore.java +++ b/core/src/main/java/io/xpipe/core/store/MachineStore.java @@ -1,8 +1,5 @@ package io.xpipe.core.store; -import java.io.InputStream; -import java.io.OutputStream; - public interface MachineStore extends FileSystemStore, ShellStore { public default boolean isLocal() { @@ -10,35 +7,7 @@ public interface MachineStore extends FileSystemStore, ShellStore { } @Override - public default InputStream openInput(String file) throws Exception { - return create().command(proc -> - proc.getShellType().getFileReadCommand(proc.getOsType().normalizeFileName(file))) - .startExternalStdout(); - } - - @Override - public default OutputStream openOutput(String file) throws Exception { - return create().command(proc -> proc.getShellType() - .getStreamFileWriteCommand(proc.getOsType().normalizeFileName(file))) - .startExternalStdin(); - } - - @Override - public default boolean exists(String file) throws Exception { - try (var pc = create().command(proc -> proc.getShellType() - .getFileExistsCommand(proc.getOsType().normalizeFileName(file))) - .start()) { - return pc.discardAndCheckExit(); - } - } - - @Override - public default boolean mkdirs(String file) throws Exception { - try (var pc = create().command(proc -> proc.getShellType() - .flatten(proc.getShellType() - .getMkdirsCommand(proc.getOsType().normalizeFileName(file)))) - .start()) { - return pc.discardAndCheckExit(); - } + default FileSystem createFileSystem() { + return new ConnectionFileSystem(create()); } } 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 764011a2c..a5945e673 100644 --- a/core/src/main/java/io/xpipe/core/store/ShellStore.java +++ b/core/src/main/java/io/xpipe/core/store/ShellStore.java @@ -8,7 +8,7 @@ import io.xpipe.core.process.ShellType; import java.nio.charset.Charset; -public interface ShellStore extends DataStore, StatefulDataStore, LaunchableStore { +public interface ShellStore extends DataStore, StatefulDataStore, LaunchableStore, FileSystemStore { public static MachineStore local() { return new LocalStore(); @@ -24,6 +24,11 @@ public interface ShellStore extends DataStore, StatefulDataStore, LaunchableStor return s instanceof LocalStore; } + @Override + default FileSystem createFileSystem() { + return new ConnectionFileSystem(create()); + } + @Override default String prepareLaunchCommand() throws Exception { return create().prepareTerminalOpen(); diff --git a/core/src/main/java/io/xpipe/core/util/CoreJacksonModule.java b/core/src/main/java/io/xpipe/core/util/CoreJacksonModule.java index 1bbb83f20..687732229 100644 --- a/core/src/main/java/io/xpipe/core/util/CoreJacksonModule.java +++ b/core/src/main/java/io/xpipe/core/util/CoreJacksonModule.java @@ -40,7 +40,6 @@ public class CoreJacksonModule extends SimpleModule { new NamedType(StdinDataStore.class), new NamedType(StdoutDataStore.class), new NamedType(LocalDirectoryDataStore.class), - new NamedType(CollectionEntryDataStore.class), new NamedType(LocalStore.class), new NamedType(NamedStore.class), new NamedType(ValueType.class), @@ -84,7 +83,7 @@ public class CoreJacksonModule extends SimpleModule { TODO: Find better way to supply a default serializer for data sources */ try { - Class.forName("io.xpipe.extension.ExtensionException"); + Class.forName("io.xpipe.app.core.App"); } catch (ClassNotFoundException e) { addSerializer(DataSource.class, new NullSerializer()); addDeserializer(DataSource.class, new NullDeserializer()); diff --git a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java index 1cb4baf58..15b8b6cc9 100644 --- a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java +++ b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java @@ -34,7 +34,7 @@ public class XPipeInstallation { } @SneakyThrows - public static Path getLocalInstallationBasePath() { + public static Path getCurrentInstallationBasePath() { Path path = Path.of(ProcessHandle.current().info().command().orElseThrow()).toRealPath(); if (!path.isAbsolute()) { @@ -54,7 +54,7 @@ public class XPipeInstallation { } public static boolean isInstallationDistribution() { - var base = getLocalInstallationBasePath(); + var base = getCurrentInstallationBasePath(); if (OsType.getLocal().equals(OsType.MACOS)) { if (!base.toString().equals(getLocalDefaultInstallationBasePath(false))) { return false; @@ -77,7 +77,7 @@ public class XPipeInstallation { } public static Path getLocalDynamicLibraryDirectory() { - Path path = getLocalInstallationBasePath(); + Path path = getCurrentInstallationBasePath(); if (OsType.getLocal().equals(OsType.WINDOWS)) { return path.resolve("app").resolve("runtime").resolve("bin"); } else if (OsType.getLocal().equals(OsType.LINUX)) { @@ -91,8 +91,7 @@ public class XPipeInstallation { } } - public static Path getLocalExtensionsDirectory() { - Path path = getLocalInstallationBasePath(); + public static Path getLocalExtensionsDirectory(Path path) { return OsType.getLocal().equals(OsType.MACOS) ? path.resolve("Contents").resolve("Resources").resolve("extensions") : path.resolve("app").resolve("extensions"); @@ -178,7 +177,7 @@ public class XPipeInstallation { } public static Path getLocalDefaultInstallationIcon() { - Path path = getLocalInstallationBasePath(); + Path path = getCurrentInstallationBasePath(); // Check for development environment if (!ModuleHelper.isImage()) { diff --git a/dist/jpackage.gradle b/dist/jpackage.gradle index 0382655b8..24de511b2 100644 --- a/dist/jpackage.gradle +++ b/dist/jpackage.gradle @@ -7,6 +7,7 @@ def distJvmArgs = new ArrayList(project(':app').application.applicationD def releaseArguments = distJvmArgs + [ '-Dio.xpipe.app.writeLogs=true', "-Dio.xpipe.app.buildId=$rootProject.buildId", + "-Dio.xpipe.app.fullVersion=$rootProject.fullVersion", '-Dio.xpipe.app.sentryUrl=https://fd5f67ff10764b7e8a704bec9558c8fe@o1084459.ingest.sentry.io/6094279' ] diff --git a/dist/licenses/atlantafx.license b/dist/licenses/atlantafx.license new file mode 100644 index 000000000..994d1fc2a --- /dev/null +++ b/dist/licenses/atlantafx.license @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [2022] [mkpaz] + +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/atlantafx.properties b/dist/licenses/atlantafx.properties new file mode 100644 index 000000000..e022ff859 --- /dev/null +++ b/dist/licenses/atlantafx.properties @@ -0,0 +1,4 @@ +name=AtlantaFX +version=1.2.0 +license=MIT License +link=https://github.com/mkpaz/atlantafx \ No newline at end of file diff --git a/ext/base/src/main/java/io/xpipe/ext/base/BinarySourceProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/BinarySourceProvider.java index b4fdde7cf..d91c75aa7 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/BinarySourceProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/BinarySourceProvider.java @@ -1,9 +1,9 @@ package io.xpipe.ext.base; +import io.xpipe.app.util.UniformDataSourceProvider; import io.xpipe.core.impl.BinarySource; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.util.UniformDataSourceProvider; import java.util.LinkedHashMap; import java.util.List; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/FileStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/FileStoreProvider.java index 984dc2c61..a5e88015b 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/FileStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/FileStoreProvider.java @@ -1,15 +1,15 @@ package io.xpipe.ext.base; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.GuiDialog; +import io.xpipe.app.util.DataStoreFormatter; +import io.xpipe.app.util.DialogHelper; +import io.xpipe.app.util.SimpleValidator; +import io.xpipe.app.util.XPipeDaemon; import io.xpipe.core.dialog.Dialog; import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.LocalStore; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.GuiDialog; -import io.xpipe.extension.util.DataStoreFormatter; -import io.xpipe.extension.util.DialogHelper; -import io.xpipe.extension.util.SimpleValidator; -import io.xpipe.extension.util.XPipeDaemon; import javafx.beans.property.Property; import java.util.List; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/HttpStore.java b/ext/base/src/main/java/io/xpipe/ext/base/HttpStore.java index 34f553cef..6ddd7865a 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/HttpStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/HttpStore.java @@ -1,12 +1,12 @@ package io.xpipe.ext.base; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.util.Validators; import io.xpipe.core.charsetter.StreamCharset; import io.xpipe.core.store.DataFlow; import io.xpipe.core.store.StatefulDataStore; import io.xpipe.core.store.StreamDataStore; import io.xpipe.core.util.JacksonizedValue; -import io.xpipe.extension.util.Validators; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/HttpStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/HttpStoreProvider.java index b5dc4427f..0a2cfebff 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/HttpStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/HttpStoreProvider.java @@ -1,17 +1,17 @@ package io.xpipe.ext.base; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.GuiDialog; +import io.xpipe.app.fxcomps.impl.DataStoreFlowChoiceComp; +import io.xpipe.app.util.DataStoreFormatter; +import io.xpipe.app.util.DialogHelper; +import io.xpipe.app.util.DynamicOptionsBuilder; +import io.xpipe.app.util.SimpleValidator; import io.xpipe.core.dialog.Dialog; import io.xpipe.core.dialog.QueryConverter; import io.xpipe.core.store.DataFlow; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.GuiDialog; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.impl.DataStoreFlowChoiceComp; -import io.xpipe.extension.util.DataStoreFormatter; -import io.xpipe.extension.util.DialogHelper; -import io.xpipe.extension.util.DynamicOptionsBuilder; -import io.xpipe.extension.util.SimpleValidator; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; @@ -43,10 +43,10 @@ public class HttpStoreProvider implements DataStoreProvider { Property flowProperty = new SimpleObjectProperty<>(st.getFlow()); - var q = new DynamicOptionsBuilder(I18n.observable("configuration")) - .addString(I18n.observable("base.method"), methodProp) + var q = new DynamicOptionsBuilder(AppI18n.observable("configuration")) + .addString(AppI18n.observable("base.method"), methodProp) .nonNull(val) - .addString(I18n.observable("base.uri"), requestProp) + .addString(AppI18n.observable("base.uri"), requestProp) .nonNull(val) .addComp( "base.usage", diff --git a/ext/base/src/main/java/io/xpipe/ext/base/InMemoryStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/InMemoryStoreProvider.java index e1df0419a..f28245940 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/InMemoryStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/InMemoryStoreProvider.java @@ -1,15 +1,15 @@ package io.xpipe.ext.base; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.GuiDialog; +import io.xpipe.app.util.DynamicOptionsBuilder; +import io.xpipe.app.util.SimpleValidator; import io.xpipe.core.charsetter.StreamCharset; import io.xpipe.core.dialog.Dialog; import io.xpipe.core.dialog.QueryConverter; import io.xpipe.core.impl.InMemoryStore; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.GuiDialog; -import io.xpipe.extension.I18n; -import io.xpipe.extension.util.DynamicOptionsBuilder; -import io.xpipe.extension.util.SimpleValidator; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; @@ -32,7 +32,7 @@ public class InMemoryStoreProvider implements DataStoreProvider { Property valProp = new SimpleObjectProperty<>( st != null ? new String(st.getValue(), charset.getValue().getCharset()) : null); - var q = new DynamicOptionsBuilder(I18n.observable("configuration")) + var q = new DynamicOptionsBuilder(AppI18n.observable("configuration")) .addCharset(charset) .addStringArea((String) null, valProp, false) .bind( @@ -56,7 +56,7 @@ public class InMemoryStoreProvider implements DataStoreProvider { @Override public String toSummaryString(DataStore store, int length) { InMemoryStore s = store.asNeeded(); - return I18n.get("base.bytes", s.getValue().length); + return AppI18n.get("base.bytes", s.getValue().length); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/InternalStreamProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/InternalStreamProvider.java index 0bb406ecc..18a2188de 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/InternalStreamProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/InternalStreamProvider.java @@ -1,9 +1,9 @@ package io.xpipe.ext.base; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.GuiDialog; import io.xpipe.core.impl.InternalStreamStore; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.GuiDialog; import javafx.beans.property.Property; import java.util.List; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/LocalStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/LocalStoreProvider.java index 36e39fd06..4072f4ac4 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/LocalStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/LocalStoreProvider.java @@ -1,14 +1,14 @@ package io.xpipe.ext.base; +import io.xpipe.app.ext.DataStoreProvider; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.StorageElement; +import io.xpipe.app.util.XPipeDaemon; import io.xpipe.core.impl.LocalStore; import io.xpipe.core.process.OsType; import io.xpipe.core.store.DataStore; import io.xpipe.core.store.ShellStore; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.util.XPipeDaemon; import java.util.List; import java.util.UUID; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/MachineRootContainer.java b/ext/base/src/main/java/io/xpipe/ext/base/MachineRootContainer.java new file mode 100644 index 000000000..6d6665d92 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/MachineRootContainer.java @@ -0,0 +1,18 @@ +package io.xpipe.ext.base; + +import io.xpipe.core.source.DataSource; +import io.xpipe.core.store.MachineStore; +import lombok.experimental.SuperBuilder; + +import java.util.List; + +@SuperBuilder +public class MachineRootContainer extends SimpleCollectionSource { + + MachineStore store; + + @Override + protected List> get() throws Exception { + return List.of(); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/ReadOnlyCollectionSource.java b/ext/base/src/main/java/io/xpipe/ext/base/ReadOnlyCollectionSource.java new file mode 100644 index 000000000..dfb8e2b11 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/ReadOnlyCollectionSource.java @@ -0,0 +1,16 @@ +package io.xpipe.ext.base; + +import io.xpipe.core.impl.InMemoryStore; +import io.xpipe.core.source.CollectionDataSource; +import io.xpipe.core.source.CollectionWriteConnection; +import io.xpipe.core.source.WriteMode; +import lombok.experimental.SuperBuilder; + +@SuperBuilder +public abstract class ReadOnlyCollectionSource extends CollectionDataSource { + + @Override + protected CollectionWriteConnection newWriteConnection(WriteMode mode) { + throw new UnsupportedOperationException(); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/SimpleCollectionSource.java b/ext/base/src/main/java/io/xpipe/ext/base/SimpleCollectionSource.java new file mode 100644 index 000000000..a94060a05 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/SimpleCollectionSource.java @@ -0,0 +1,28 @@ +package io.xpipe.ext.base; + +import io.xpipe.core.source.CollectionReadConnection; +import io.xpipe.core.source.DataSource; +import lombok.experimental.SuperBuilder; + +import java.util.List; +import java.util.stream.Stream; + +@SuperBuilder +public abstract class SimpleCollectionSource extends ReadOnlyCollectionSource { + protected abstract List> get() throws Exception; + + @Override + protected CollectionReadConnection newReadConnection() { + return new CollectionReadConnection() { + @Override + public Stream> listEntries() throws Exception { + return get().stream(); + } + + @Override + public boolean canRead() throws Exception { + return true; + } + }; + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/SimpleFileDataSourceProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/SimpleFileDataSourceProvider.java index 972caa337..891551152 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/SimpleFileDataSourceProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/SimpleFileDataSourceProvider.java @@ -1,13 +1,13 @@ package io.xpipe.ext.base; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceProviders; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; import io.xpipe.core.store.FilenameStore; import io.xpipe.core.store.StreamDataStore; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceProviders; -import io.xpipe.extension.I18n; import java.util.LinkedHashMap; import java.util.List; @@ -77,7 +77,7 @@ public interface SimpleFileDataSourceProvider> extends D return new FileProvider() { @Override public String getFileName() { - return I18n.get(getNameI18nKey()); + return AppI18n.get(getNameI18nKey()); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/SinkDrainStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/SinkDrainStoreProvider.java index 43577e820..45859b794 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/SinkDrainStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/SinkDrainStoreProvider.java @@ -1,16 +1,16 @@ package io.xpipe.ext.base; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.GuiDialog; +import io.xpipe.app.util.DialogHelper; +import io.xpipe.app.util.DynamicOptionsBuilder; +import io.xpipe.app.util.SimpleValidator; import io.xpipe.core.charsetter.NewLine; import io.xpipe.core.charsetter.StreamCharset; import io.xpipe.core.dialog.Dialog; import io.xpipe.core.impl.SinkDrainStore; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.GuiDialog; -import io.xpipe.extension.I18n; -import io.xpipe.extension.util.DialogHelper; -import io.xpipe.extension.util.DynamicOptionsBuilder; -import io.xpipe.extension.util.SimpleValidator; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; @@ -26,7 +26,7 @@ public class SinkDrainStoreProvider implements DataStoreProvider { var charset = new SimpleObjectProperty(st.getCharset()); var newLine = new SimpleObjectProperty(st.getNewLine()); - var q = new DynamicOptionsBuilder(I18n.observable("configuration")) + var q = new DynamicOptionsBuilder(AppI18n.observable("configuration")) .addCharset(charset) .addNewLine(newLine) .bind( @@ -56,19 +56,19 @@ public class SinkDrainStoreProvider implements DataStoreProvider { SinkDrainStore st = store.asNeeded(); return switch (st.getState()) { case NONE_CONNECTED -> { - yield I18n.get("unconnected"); + yield AppI18n.get("unconnected"); } case PRODUCER_CONNECTED -> { - yield I18n.get("waitingForConsumer"); + yield AppI18n.get("waitingForConsumer"); } case CONSUMER_CONNECTED -> { - yield I18n.get("waitingForProducer"); + yield AppI18n.get("waitingForProducer"); } case OPEN -> { - yield I18n.get("open"); + yield AppI18n.get("open"); } case CLOSED -> { - yield I18n.get("closed"); + yield AppI18n.get("closed"); } }; } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/TextSourceProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/TextSourceProvider.java index ae3757a7b..a7a14054b 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/TextSourceProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/TextSourceProvider.java @@ -1,5 +1,7 @@ package io.xpipe.ext.base; +import io.xpipe.app.util.DialogHelper; +import io.xpipe.app.util.DynamicOptionsBuilder; import io.xpipe.core.charsetter.Charsetter; import io.xpipe.core.charsetter.NewLine; import io.xpipe.core.charsetter.StreamCharset; @@ -7,8 +9,6 @@ import io.xpipe.core.dialog.Dialog; import io.xpipe.core.impl.TextSource; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.util.DialogHelper; -import io.xpipe.extension.util.DynamicOptionsBuilder; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.scene.layout.Region; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/XpbsProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/XpbsProvider.java index 6fc7979dd..ba8025a6e 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/XpbsProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/XpbsProvider.java @@ -1,9 +1,9 @@ package io.xpipe.ext.base; +import io.xpipe.app.util.UniformDataSourceProvider; import io.xpipe.core.impl.XpbsSource; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.util.UniformDataSourceProvider; import java.util.List; import java.util.Map; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/XpbtProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/XpbtProvider.java index 40b657bdd..099fd7bfa 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/XpbtProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/XpbtProvider.java @@ -1,9 +1,9 @@ package io.xpipe.ext.base; +import io.xpipe.app.util.UniformDataSourceProvider; import io.xpipe.core.impl.XpbtSource; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.util.UniformDataSourceProvider; import java.util.List; import java.util.Map; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/actions/AddStoreAction.java b/ext/base/src/main/java/io/xpipe/ext/base/actions/AddStoreAction.java index e6e68e35d..7025ae27b 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/actions/AddStoreAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/actions/AddStoreAction.java @@ -1,11 +1,11 @@ package io.xpipe.ext.base.actions; import io.xpipe.app.comp.source.store.GuiDsStoreCreator; +import io.xpipe.app.ext.ActionProvider; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.core.store.DataStore; import io.xpipe.core.util.JacksonMapper; import io.xpipe.core.util.SecretValue; -import io.xpipe.extension.util.ActionProvider; import lombok.Value; import java.util.List; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/actions/EditStoreAction.java b/ext/base/src/main/java/io/xpipe/ext/base/actions/EditStoreAction.java index 322102724..6b11d61fe 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/actions/EditStoreAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/actions/EditStoreAction.java @@ -1,11 +1,11 @@ package io.xpipe.ext.base.actions; import io.xpipe.app.comp.source.store.GuiDsStoreCreator; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.ActionProvider; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.I18n; -import io.xpipe.extension.util.ActionProvider; import javafx.beans.value.ObservableValue; import lombok.Value; @@ -58,7 +58,7 @@ public class EditStoreAction implements ActionProvider { @Override public ObservableValue getName(DataStore store) { - return I18n.observable("base.edit"); + return AppI18n.observable("base.edit"); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/actions/FileBrowseAction.java b/ext/base/src/main/java/io/xpipe/ext/base/actions/FileBrowseAction.java index 17fd83020..ad627ab3d 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/actions/FileBrowseAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/actions/FileBrowseAction.java @@ -1,10 +1,10 @@ package io.xpipe.ext.base.actions; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.util.DesktopHelper; import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.LocalStore; -import io.xpipe.extension.I18n; -import io.xpipe.extension.util.ActionProvider; -import io.xpipe.extension.util.DesktopHelper; import javafx.beans.value.ObservableValue; import lombok.Value; @@ -50,7 +50,7 @@ public class FileBrowseAction implements ActionProvider { @Override public ObservableValue getName(FileStore store) { - return I18n.observable("base.browseFile"); + return AppI18n.observable("base.browseFile"); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/actions/FileEditAction.java b/ext/base/src/main/java/io/xpipe/ext/base/actions/FileEditAction.java index 077f7f25f..b554c5b72 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/actions/FileEditAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/actions/FileEditAction.java @@ -1,11 +1,11 @@ package io.xpipe.ext.base.actions; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.ActionProvider; import io.xpipe.app.util.ExternalEditor; import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.LocalStore; import io.xpipe.core.store.DataFlow; -import io.xpipe.extension.I18n; -import io.xpipe.extension.util.ActionProvider; import javafx.beans.value.ObservableValue; import lombok.Value; @@ -58,7 +58,7 @@ public class FileEditAction implements ActionProvider { @Override public ObservableValue getName(FileStore store) { - return I18n.observable("base.editFile"); + return AppI18n.observable("base.editFile"); } @Override 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 7541654e5..ad9757101 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,11 +1,11 @@ package io.xpipe.ext.base.actions; import io.xpipe.app.core.AppActionLinkDetector; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.ext.DataStoreProviders; import io.xpipe.core.store.DataStore; import io.xpipe.core.util.SecretValue; -import io.xpipe.extension.DataStoreProviders; -import io.xpipe.extension.I18n; -import io.xpipe.extension.util.ActionProvider; import javafx.beans.value.ObservableValue; import lombok.Value; @@ -65,7 +65,7 @@ public class ShareStoreAction implements ActionProvider { @Override public ObservableValue getName(DataStore store) { - return I18n.observable("base.copyShareLink"); + return AppI18n.observable("base.copyShareLink"); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/actions/StreamExportAction.java b/ext/base/src/main/java/io/xpipe/ext/base/actions/StreamExportAction.java index c8cfa9d6a..a257c17b4 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/actions/StreamExportAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/actions/StreamExportAction.java @@ -1,11 +1,11 @@ package io.xpipe.ext.base.actions; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.util.DesktopHelper; +import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.store.StreamDataStore; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.util.ActionProvider; -import io.xpipe.extension.util.DesktopHelper; -import io.xpipe.extension.util.ThreadHelper; import javafx.beans.value.ObservableValue; import javafx.stage.FileChooser; import lombok.Value; @@ -29,8 +29,8 @@ public class StreamExportAction implements ActionProvider { @Override public void execute() throws Exception { FileChooser fileChooser = new FileChooser(); - fileChooser.setTitle(I18n.get("browseFileTitle")); - fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(I18n.get("anyFile"), ".")); + fileChooser.setTitle(AppI18n.get("browseFileTitle")); + fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(AppI18n.get("anyFile"), ".")); var outputFile = fileChooser.showSaveDialog(null); if (outputFile == null) { return; @@ -70,7 +70,7 @@ public class StreamExportAction implements ActionProvider { @Override public ObservableValue getName(StreamDataStore store) { - return I18n.observable("base.exportStream"); + return AppI18n.observable("base.exportStream"); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/apps/CommandLineTarget.java b/ext/base/src/main/java/io/xpipe/ext/base/apps/CommandLineTarget.java index f19fa4237..2d20972c4 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/apps/CommandLineTarget.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/apps/CommandLineTarget.java @@ -1,13 +1,13 @@ package io.xpipe.ext.base.apps; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceTarget; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.impl.CodeSnippet; +import io.xpipe.app.fxcomps.impl.CodeSnippetComp; +import io.xpipe.app.util.DynamicOptionsBuilder; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceId; -import io.xpipe.extension.DataSourceTarget; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.Comp; -import io.xpipe.extension.fxcomps.impl.CodeSnippet; -import io.xpipe.extension.fxcomps.impl.CodeSnippetComp; -import io.xpipe.extension.util.DynamicOptionsBuilder; import javafx.beans.binding.Bindings; import javafx.beans.value.ObservableValue; @@ -42,7 +42,7 @@ public class CommandLineTarget implements DataSourceTarget { @Override public ObservableValue getName() { - return I18n.observable("base.commandLine"); + return AppI18n.observable("base.commandLine"); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/apps/DataSourceOutputTarget.java b/ext/base/src/main/java/io/xpipe/ext/base/apps/DataSourceOutputTarget.java index 28272923d..fe2271e35 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/apps/DataSourceOutputTarget.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/apps/DataSourceOutputTarget.java @@ -1,17 +1,17 @@ package io.xpipe.ext.base.apps; import io.xpipe.app.comp.source.GuiDsTableMappingConfirmation; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceProviders; +import io.xpipe.app.ext.DataSourceTarget; +import io.xpipe.app.fxcomps.impl.WriteModeChoiceComp; +import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.util.ChainedValidator; +import io.xpipe.app.util.DynamicOptionsBuilder; +import io.xpipe.app.util.XPipeDaemon; import io.xpipe.core.source.*; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceProviders; -import io.xpipe.extension.DataSourceTarget; -import io.xpipe.extension.I18n; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.impl.WriteModeChoiceComp; -import io.xpipe.extension.fxcomps.util.BindingsHelper; -import io.xpipe.extension.util.ChainedValidator; -import io.xpipe.extension.util.DynamicOptionsBuilder; -import io.xpipe.extension.util.XPipeDaemon; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -96,7 +96,7 @@ public class DataSourceOutputTarget implements DataSourceTarget { @Override public ObservableValue getName() { - return I18n.observable("base.dataSourceOutput"); + return AppI18n.observable("base.dataSourceOutput"); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/apps/FileOutputTarget.java b/ext/base/src/main/java/io/xpipe/ext/base/apps/FileOutputTarget.java index 8838f4a48..c6d074ab3 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/apps/FileOutputTarget.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/apps/FileOutputTarget.java @@ -1,18 +1,22 @@ package io.xpipe.ext.base.apps; +import io.xpipe.app.core.AppCache; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceProviders; +import io.xpipe.app.ext.DataSourceTarget; +import io.xpipe.app.fxcomps.augment.GrowAugment; +import io.xpipe.app.fxcomps.impl.WriteModeChoiceComp; +import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.util.ChainedValidator; +import io.xpipe.app.util.DynamicOptionsBuilder; +import io.xpipe.app.util.XPipeDaemon; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceId; import io.xpipe.core.source.WriteMode; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.*; -import io.xpipe.extension.event.ErrorEvent; -import io.xpipe.extension.fxcomps.augment.GrowAugment; -import io.xpipe.extension.fxcomps.impl.WriteModeChoiceComp; -import io.xpipe.extension.fxcomps.util.BindingsHelper; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; -import io.xpipe.extension.util.ChainedValidator; -import io.xpipe.extension.util.DynamicOptionsBuilder; -import io.xpipe.extension.util.XPipeDaemon; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -37,7 +41,7 @@ public class FileOutputTarget implements DataSourceTarget { var target = new SimpleObjectProperty(); var provider = new SimpleObjectProperty>(); - var defaultProvider = Cache.getIfPresent("lastStreamOutputProvider", String.class) + var defaultProvider = AppCache.getIfPresent("lastStreamOutputProvider", String.class) .flatMap(DataSourceProviders::byName) .orElse(null); provider.set(defaultProvider); @@ -108,7 +112,7 @@ public class FileOutputTarget implements DataSourceTarget { @Override public void run() { try { - Cache.update( + AppCache.update( "lastStreamOutputProvider", provider.get().getId()); try (var connection = targetSource.getValue().openWriteConnection(mode.get())) { connection.init(); @@ -127,7 +131,7 @@ public class FileOutputTarget implements DataSourceTarget { @Override public ObservableValue getName() { - return I18n.observable("base.fileOutput"); + return AppI18n.observable("base.fileOutput"); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/apps/JavaTarget.java b/ext/base/src/main/java/io/xpipe/ext/base/apps/JavaTarget.java index c96e296f4..3bd1734f5 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/apps/JavaTarget.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/apps/JavaTarget.java @@ -1,11 +1,11 @@ package io.xpipe.ext.base.apps; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceTarget; +import io.xpipe.app.fxcomps.impl.CodeSnippet; +import io.xpipe.app.fxcomps.impl.CodeSnippetComp; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceId; -import io.xpipe.extension.DataSourceTarget; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.impl.CodeSnippet; -import io.xpipe.extension.fxcomps.impl.CodeSnippetComp; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ObservableValue; @@ -98,7 +98,7 @@ public class JavaTarget implements DataSourceTarget { @Override public ObservableValue getName() { - return I18n.observable("base.java"); + return AppI18n.observable("base.java"); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/apps/RawFileOutputTarget.java b/ext/base/src/main/java/io/xpipe/ext/base/apps/RawFileOutputTarget.java index c3f23bf7d..9bf5a0fe5 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/apps/RawFileOutputTarget.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/apps/RawFileOutputTarget.java @@ -1,14 +1,14 @@ package io.xpipe.ext.base.apps; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceTarget; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.fxcomps.augment.GrowAugment; +import io.xpipe.app.util.DynamicOptionsBuilder; +import io.xpipe.app.util.XPipeDaemon; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceId; import io.xpipe.core.store.StreamDataStore; -import io.xpipe.extension.DataSourceTarget; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.augment.GrowAugment; -import io.xpipe.extension.util.DynamicOptionsBuilder; -import io.xpipe.extension.util.XPipeDaemon; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import javafx.scene.layout.GridPane; @@ -66,7 +66,7 @@ public class RawFileOutputTarget implements DataSourceTarget { @Override public ObservableValue getName() { - return I18n.observable("base.rawFileOutput"); + return AppI18n.observable("base.rawFileOutput"); } @Override 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 b80b1e215..f28d461b3 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 @@ -3,16 +3,16 @@ package io.xpipe.ext.base.apps; import io.xpipe.app.comp.source.DsStorageTargetComp; import io.xpipe.app.comp.storage.collection.SourceCollectionViewState; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.DataSourceTarget; +import io.xpipe.app.fxcomps.impl.VerticalComp; +import io.xpipe.app.fxcomps.util.SimpleChangeListener; import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.util.SimpleValidator; import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceId; -import io.xpipe.extension.DataSourceTarget; -import io.xpipe.extension.I18n; -import io.xpipe.extension.fxcomps.impl.VerticalComp; -import io.xpipe.extension.fxcomps.util.SimpleChangeListener; -import io.xpipe.extension.util.SimpleValidator; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -68,7 +68,7 @@ public class SaveSourceTarget implements DataSourceTarget { @Override public ObservableValue getName() { - return I18n.observable("base.saveSource"); + return AppI18n.observable("base.saveSource"); } @Override diff --git a/ext/base/src/main/java/module-info.java b/ext/base/src/main/java/module-info.java index a75e590f6..f675389f4 100644 --- a/ext/base/src/main/java/module-info.java +++ b/ext/base/src/main/java/module-info.java @@ -1,10 +1,10 @@ +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.ext.DataSourceProvider; +import io.xpipe.app.ext.DataSourceTarget; +import io.xpipe.app.ext.DataStoreProvider; import io.xpipe.ext.base.*; import io.xpipe.ext.base.actions.*; import io.xpipe.ext.base.apps.*; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceTarget; -import io.xpipe.extension.DataStoreProvider; -import io.xpipe.extension.util.ActionProvider; open module io.xpipe.ext.base { exports io.xpipe.ext.base; @@ -13,13 +13,13 @@ open module io.xpipe.ext.base { requires java.desktop; requires io.xpipe.core; - requires io.xpipe.extension; requires com.fasterxml.jackson.databind; requires java.net.http; requires static lombok; requires static javafx.controls; requires static net.synedra.validatorfx; requires static io.xpipe.app; + requires org.apache.commons.lang3; provides ActionProvider with AddStoreAction, diff --git a/ext/collections/build.gradle b/ext/collections/build.gradle index 35414a445..335ec359c 100644 --- a/ext/collections/build.gradle +++ b/ext/collections/build.gradle @@ -12,5 +12,6 @@ configurations { } dependencies { + compileOnly project(':app') implementation 'org.apache.commons:commons-compress:1.21' } diff --git a/core/src/main/java/io/xpipe/core/impl/CollectionEntryDataStore.java b/ext/collections/src/main/java/io/xpipe/ext/collections/ArchiveEntryDataStore.java similarity index 76% rename from core/src/main/java/io/xpipe/core/impl/CollectionEntryDataStore.java rename to ext/collections/src/main/java/io/xpipe/ext/collections/ArchiveEntryDataStore.java index 7708f0bcc..cb96387e3 100644 --- a/core/src/main/java/io/xpipe/core/impl/CollectionEntryDataStore.java +++ b/ext/collections/src/main/java/io/xpipe/ext/collections/ArchiveEntryDataStore.java @@ -1,16 +1,16 @@ -package io.xpipe.core.impl; +package io.xpipe.ext.collections; import io.xpipe.core.store.DataStore; import io.xpipe.core.store.FilenameStore; import io.xpipe.core.store.StreamDataStore; -public abstract class CollectionEntryDataStore implements FilenameStore, StreamDataStore { +public abstract class ArchiveEntryDataStore implements FilenameStore, StreamDataStore { private final boolean directory; private final String name; private final DataStore collectionStore; - public CollectionEntryDataStore(boolean directory, String name, DataStore collectionStore) { + public ArchiveEntryDataStore(boolean directory, String name, DataStore collectionStore) { this.directory = directory; this.name = name; this.collectionStore = collectionStore; diff --git a/ext/collections/src/main/java/io/xpipe/ext/collections/ArchiveEntryStore.java b/ext/collections/src/main/java/io/xpipe/ext/collections/ArchiveEntryStore.java index c3c7fd6ca..a44489230 100644 --- a/ext/collections/src/main/java/io/xpipe/ext/collections/ArchiveEntryStore.java +++ b/ext/collections/src/main/java/io/xpipe/ext/collections/ArchiveEntryStore.java @@ -1,12 +1,11 @@ package io.xpipe.ext.collections; -import io.xpipe.core.impl.CollectionEntryDataStore; import io.xpipe.core.store.StreamDataStore; import java.io.InputStream; import java.io.OutputStream; -public class ArchiveEntryStore extends CollectionEntryDataStore { +public class ArchiveEntryStore extends ArchiveEntryDataStore { private final ArchiveReadConnection con; diff --git a/ext/collections/src/main/java/io/xpipe/ext/collections/ArchiveReadConnection.java b/ext/collections/src/main/java/io/xpipe/ext/collections/ArchiveReadConnection.java index 689b7292f..19428baf9 100644 --- a/ext/collections/src/main/java/io/xpipe/ext/collections/ArchiveReadConnection.java +++ b/ext/collections/src/main/java/io/xpipe/ext/collections/ArchiveReadConnection.java @@ -1,7 +1,8 @@ package io.xpipe.ext.collections; -import io.xpipe.core.impl.CollectionEntryDataStore; +import io.xpipe.app.ext.DataSourceProviders; import io.xpipe.core.source.CollectionReadConnection; +import io.xpipe.core.source.DataSource; import io.xpipe.core.store.StreamDataStore; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveInputStream; @@ -24,7 +25,7 @@ public class ArchiveReadConnection implements CollectionReadConnection { } @Override - public Stream listEntries() throws Exception { + public Stream> listEntries() throws Exception { var ar = inputStream.getNextEntry(); AtomicReference entry = new AtomicReference<>( ar != null ? new ArchiveEntryStore(store, ar.isDirectory(), this, ar.getName()) : null); @@ -52,7 +53,14 @@ public class ArchiveReadConnection implements CollectionReadConnection { }, e -> { return entry.get(); - }); + }).map(archiveEntryStore -> { + var preferred = DataSourceProviders.byPreferredStore(archiveEntryStore, null); + try { + return preferred.isPresent() ? preferred.get().createDefaultSource(archiveEntryStore).asNeeded() : null; + } catch (Exception e) { + throw new RuntimeException(e); + } + }); } @Override diff --git a/ext/collections/src/main/java/io/xpipe/ext/collections/DirectoryProvider.java b/ext/collections/src/main/java/io/xpipe/ext/collections/DirectoryProvider.java index e6aac13ea..1df22b4e1 100644 --- a/ext/collections/src/main/java/io/xpipe/ext/collections/DirectoryProvider.java +++ b/ext/collections/src/main/java/io/xpipe/ext/collections/DirectoryProvider.java @@ -1,10 +1,10 @@ package io.xpipe.ext.collections; -import io.xpipe.core.impl.CollectionEntryDataStore; +import io.xpipe.app.ext.DataSourceProviders; +import io.xpipe.app.util.UniformDataSourceProvider; import io.xpipe.core.impl.LocalDirectoryDataStore; import io.xpipe.core.source.*; import io.xpipe.core.store.DataStore; -import io.xpipe.extension.util.UniformDataSourceProvider; import lombok.experimental.SuperBuilder; import java.io.IOException; @@ -88,15 +88,15 @@ public class DirectoryProvider implements UniformDataSourceProvider listEntries() throws Exception { - var entries = new ArrayList(); + public Stream> listEntries() throws Exception { + var entries = new ArrayList(); Files.walkFileTree(store.getPath(), new SimpleFileVisitor<>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { var rel = store.getPath().relativize(file); var name = rel.toString(); var dir = Files.isDirectory(file); - var e = new CollectionEntryDataStore(dir, name, store) { + var e = new ArchiveEntryDataStore(dir, name, store) { @Override public InputStream openInput() throws Exception { return Files.newInputStream(file); @@ -116,7 +116,7 @@ public class DirectoryProvider implements UniformDataSourceProvider DataSourceProviders.createDefault(archiveEntryDataStore)); } }; } diff --git a/ext/collections/src/main/java/module-info.java b/ext/collections/src/main/java/module-info.java index f23a5c177..f23de239d 100644 --- a/ext/collections/src/main/java/module-info.java +++ b/ext/collections/src/main/java/module-info.java @@ -1,9 +1,9 @@ +import io.xpipe.app.ext.DataSourceProvider; import io.xpipe.ext.collections.ZipFileProvider; -import io.xpipe.extension.DataSourceProvider; module io.xpipe.ext.collections { requires io.xpipe.core; - requires io.xpipe.extension; + requires io.xpipe.app; requires org.apache.commons.compress; requires static lombok; requires com.fasterxml.jackson.databind; diff --git a/ext/csv/build.gradle b/ext/csv/build.gradle index 0e94fa031..44e031cde 100644 --- a/ext/csv/build.gradle +++ b/ext/csv/build.gradle @@ -9,3 +9,7 @@ apply from: "$rootDir/gradle/gradle_scripts/extension.gradle" configurations { compileOnly.extendsFrom(dep) } + +dependencies { + compileOnly project(':app') +} diff --git a/ext/csv/src/main/java/io/xpipe/ext/csv/CsvDelimiter.java b/ext/csv/src/main/java/io/xpipe/ext/csv/CsvDelimiter.java index 2492e9b35..053c2c616 100644 --- a/ext/csv/src/main/java/io/xpipe/ext/csv/CsvDelimiter.java +++ b/ext/csv/src/main/java/io/xpipe/ext/csv/CsvDelimiter.java @@ -1,7 +1,7 @@ package io.xpipe.ext.csv; -import io.xpipe.extension.event.TrackEvent; -import io.xpipe.extension.util.NamedCharacter; +import io.xpipe.app.issue.TrackEvent; +import io.xpipe.app.util.NamedCharacter; import lombok.Value; import java.util.Comparator; diff --git a/ext/csv/src/main/java/io/xpipe/ext/csv/CsvDetector.java b/ext/csv/src/main/java/io/xpipe/ext/csv/CsvDetector.java index 761e405db..2ac5a9b72 100644 --- a/ext/csv/src/main/java/io/xpipe/ext/csv/CsvDetector.java +++ b/ext/csv/src/main/java/io/xpipe/ext/csv/CsvDetector.java @@ -1,8 +1,8 @@ package io.xpipe.ext.csv; +import io.xpipe.app.issue.TrackEvent; import io.xpipe.core.charsetter.Charsetter; import io.xpipe.core.store.StreamDataStore; -import io.xpipe.extension.event.TrackEvent; import java.io.BufferedReader; import java.util.ArrayList; diff --git a/ext/csv/src/main/java/io/xpipe/ext/csv/CsvQuoteChar.java b/ext/csv/src/main/java/io/xpipe/ext/csv/CsvQuoteChar.java index 2f21fd53c..67009a5bc 100644 --- a/ext/csv/src/main/java/io/xpipe/ext/csv/CsvQuoteChar.java +++ b/ext/csv/src/main/java/io/xpipe/ext/csv/CsvQuoteChar.java @@ -1,6 +1,6 @@ package io.xpipe.ext.csv; -import io.xpipe.extension.util.NamedCharacter; +import io.xpipe.app.util.NamedCharacter; import lombok.experimental.UtilityClass; import java.util.ArrayList; diff --git a/ext/csv/src/main/java/io/xpipe/ext/csv/CsvSource.java b/ext/csv/src/main/java/io/xpipe/ext/csv/CsvSource.java index aeb67cad9..04d6955f8 100644 --- a/ext/csv/src/main/java/io/xpipe/ext/csv/CsvSource.java +++ b/ext/csv/src/main/java/io/xpipe/ext/csv/CsvSource.java @@ -1,6 +1,7 @@ package io.xpipe.ext.csv; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.util.Validators; import io.xpipe.core.charsetter.Charsettable; import io.xpipe.core.charsetter.Charsetter; import io.xpipe.core.charsetter.NewLine; @@ -11,7 +12,6 @@ import io.xpipe.core.source.TableWriteConnection; import io.xpipe.core.source.WriteMode; import io.xpipe.core.store.DataStore; import io.xpipe.core.store.StreamDataStore; -import io.xpipe.extension.util.Validators; import lombok.Getter; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; diff --git a/ext/csv/src/main/java/io/xpipe/ext/csv/CsvSourceProvider.java b/ext/csv/src/main/java/io/xpipe/ext/csv/CsvSourceProvider.java index c82140028..e9fc302be 100644 --- a/ext/csv/src/main/java/io/xpipe/ext/csv/CsvSourceProvider.java +++ b/ext/csv/src/main/java/io/xpipe/ext/csv/CsvSourceProvider.java @@ -1,5 +1,9 @@ package io.xpipe.ext.csv; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.util.DialogHelper; +import io.xpipe.app.util.DynamicOptionsBuilder; +import io.xpipe.app.util.NamedCharacter; import io.xpipe.core.charsetter.NewLine; import io.xpipe.core.dialog.Dialog; import io.xpipe.core.impl.TextSource; @@ -8,10 +12,6 @@ import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; import io.xpipe.core.store.StreamDataStore; import io.xpipe.ext.base.SimpleFileDataSourceProvider; -import io.xpipe.extension.I18n; -import io.xpipe.extension.util.DialogHelper; -import io.xpipe.extension.util.DynamicOptionsBuilder; -import io.xpipe.extension.util.NamedCharacter; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -57,30 +57,30 @@ public class CsvSourceProvider implements SimpleFileDataSourceProvider(s.getHeaderState()); var headerStateNames = new LinkedHashMap>(); - headerStateNames.put(CsvHeaderState.INCLUDED, I18n.observable("csv.included")); - headerStateNames.put(CsvHeaderState.OMITTED, I18n.observable("csv.omitted")); + headerStateNames.put(CsvHeaderState.INCLUDED, AppI18n.observable("csv.included")); + headerStateNames.put(CsvHeaderState.OMITTED, AppI18n.observable("csv.omitted")); var delimiter = new SimpleObjectProperty(s.getDelimiter()); var delimiterNames = new LinkedHashMap>(); CsvDelimiter.ALL.forEach(d -> { delimiterNames.put( d.getNamedCharacter().getCharacter(), - I18n.observable(d.getNamedCharacter().getTranslationKey())); + AppI18n.observable(d.getNamedCharacter().getTranslationKey())); }); - ObservableValue delimiterCustom = I18n.observable("csv.custom"); + ObservableValue delimiterCustom = AppI18n.observable("csv.custom"); var quote = new SimpleObjectProperty(s.getQuote()); var quoteNames = new LinkedHashMap>(); CsvQuoteChar.CHARS.forEach(d -> { - quoteNames.put(d.getCharacter(), I18n.observable(d.getTranslationKey())); + quoteNames.put(d.getCharacter(), AppI18n.observable(d.getTranslationKey())); }); return new DynamicOptionsBuilder() .addCharset(charset) .addNewLine(newLine) - .addToggle(headerState, I18n.observable("csv.header"), headerStateNames) - .addCharacter(delimiter, I18n.observable("csv.delimiter"), delimiterNames, delimiterCustom) - .addCharacter(quote, I18n.observable("csv.quote"), quoteNames) + .addToggle(headerState, AppI18n.observable("csv.header"), headerStateNames) + .addCharacter(delimiter, AppI18n.observable("csv.delimiter"), delimiterNames, delimiterCustom) + .addCharacter(quote, AppI18n.observable("csv.quote"), quoteNames) .bind( () -> { return CsvSource.builder() diff --git a/ext/csv/src/main/java/module-info.java b/ext/csv/src/main/java/module-info.java index 1a35fcc4c..e111b1cf7 100644 --- a/ext/csv/src/main/java/module-info.java +++ b/ext/csv/src/main/java/module-info.java @@ -1,5 +1,5 @@ +import io.xpipe.app.ext.DataSourceProvider; import io.xpipe.ext.csv.CsvSourceProvider; -import io.xpipe.extension.DataSourceProvider; module io.xpipe.ext.csv { exports io.xpipe.ext.csv; @@ -11,7 +11,7 @@ module io.xpipe.ext.csv { requires static org.apache.commons.io; requires com.fasterxml.jackson.core; requires com.fasterxml.jackson.databind; - requires io.xpipe.extension; + requires io.xpipe.app; requires static javafx.base; requires static javafx.graphics; requires io.xpipe.ext.base; diff --git a/ext/jackson/build.gradle b/ext/jackson/build.gradle index d5bb76750..bc6a4315e 100644 --- a/ext/jackson/build.gradle +++ b/ext/jackson/build.gradle @@ -13,6 +13,7 @@ configurations { } dependencies { + compileOnly project(':app') implementation(group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: "2.13.0") { exclude group: 'com.fasterxml.jackson.core', module: 'jackson-core' exclude group: 'com.fasterxml.jackson.core', module: 'jackson-annotations' diff --git a/ext/jackson/src/main/java/io/xpipe/ext/jackson/json/JsonProvider.java b/ext/jackson/src/main/java/io/xpipe/ext/jackson/json/JsonProvider.java index a36d0f2f9..4e3eb3ba7 100644 --- a/ext/jackson/src/main/java/io/xpipe/ext/jackson/json/JsonProvider.java +++ b/ext/jackson/src/main/java/io/xpipe/ext/jackson/json/JsonProvider.java @@ -1,6 +1,9 @@ package io.xpipe.ext.jackson.json; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.util.DialogHelper; +import io.xpipe.app.util.DynamicOptionsBuilder; +import io.xpipe.app.util.UniformDataSourceProvider; import io.xpipe.core.charsetter.Charsetter; import io.xpipe.core.charsetter.NewLine; import io.xpipe.core.charsetter.StreamCharset; @@ -11,9 +14,6 @@ import io.xpipe.core.store.DataStore; import io.xpipe.core.store.StreamDataStore; import io.xpipe.ext.base.SimpleFileDataSourceProvider; import io.xpipe.ext.jackson.json_table.JsonTableProvider; -import io.xpipe.extension.util.DialogHelper; -import io.xpipe.extension.util.DynamicOptionsBuilder; -import io.xpipe.extension.util.UniformDataSourceProvider; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.scene.layout.Region; diff --git a/ext/jackson/src/main/java/io/xpipe/ext/jackson/json_table/JsonTableProvider.java b/ext/jackson/src/main/java/io/xpipe/ext/jackson/json_table/JsonTableProvider.java index 1085e09bf..5ac662ee4 100644 --- a/ext/jackson/src/main/java/io/xpipe/ext/jackson/json_table/JsonTableProvider.java +++ b/ext/jackson/src/main/java/io/xpipe/ext/jackson/json_table/JsonTableProvider.java @@ -1,6 +1,9 @@ package io.xpipe.ext.jackson.json_table; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.util.DialogHelper; +import io.xpipe.app.util.DynamicOptionsBuilder; +import io.xpipe.app.util.UniformDataSourceProvider; import io.xpipe.core.charsetter.Charsetter; import io.xpipe.core.charsetter.NewLine; import io.xpipe.core.charsetter.StreamCharset; @@ -11,9 +14,6 @@ import io.xpipe.core.store.DataStore; import io.xpipe.core.store.StreamDataStore; import io.xpipe.ext.base.SimpleFileDataSourceProvider; import io.xpipe.ext.jackson.json.JsonProvider; -import io.xpipe.extension.util.DialogHelper; -import io.xpipe.extension.util.DynamicOptionsBuilder; -import io.xpipe.extension.util.UniformDataSourceProvider; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.scene.layout.Region; @@ -27,7 +27,7 @@ import java.util.Map; public class JsonTableProvider implements UniformDataSourceProvider, - SimpleFileDataSourceProvider { + SimpleFileDataSourceProvider { @Override public boolean supportsConversion(JsonTableProvider.Source in, DataSourceType t) { diff --git a/ext/jackson/src/main/java/io/xpipe/ext/jackson/xml/XmlProvider.java b/ext/jackson/src/main/java/io/xpipe/ext/jackson/xml/XmlProvider.java index dee0cee07..9c1253630 100644 --- a/ext/jackson/src/main/java/io/xpipe/ext/jackson/xml/XmlProvider.java +++ b/ext/jackson/src/main/java/io/xpipe/ext/jackson/xml/XmlProvider.java @@ -1,6 +1,8 @@ package io.xpipe.ext.jackson.xml; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.util.DialogHelper; +import io.xpipe.app.util.DynamicOptionsBuilder; import io.xpipe.core.charsetter.Charsetter; import io.xpipe.core.charsetter.NewLine; import io.xpipe.core.charsetter.StreamCharset; @@ -11,8 +13,6 @@ import io.xpipe.core.store.DataStore; import io.xpipe.core.store.StreamDataStore; import io.xpipe.ext.base.SimpleFileDataSourceProvider; import io.xpipe.ext.jackson.xml_table.XmlTableProvider; -import io.xpipe.extension.util.DialogHelper; -import io.xpipe.extension.util.DynamicOptionsBuilder; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.scene.layout.Region; diff --git a/ext/jackson/src/main/java/io/xpipe/ext/jackson/xml_table/XmlTableProvider.java b/ext/jackson/src/main/java/io/xpipe/ext/jackson/xml_table/XmlTableProvider.java index 22e28bbfc..a28bef938 100644 --- a/ext/jackson/src/main/java/io/xpipe/ext/jackson/xml_table/XmlTableProvider.java +++ b/ext/jackson/src/main/java/io/xpipe/ext/jackson/xml_table/XmlTableProvider.java @@ -1,6 +1,9 @@ package io.xpipe.ext.jackson.xml_table; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.util.DialogHelper; +import io.xpipe.app.util.DynamicOptionsBuilder; +import io.xpipe.app.util.UniformDataSourceProvider; import io.xpipe.core.charsetter.Charsetter; import io.xpipe.core.charsetter.NewLine; import io.xpipe.core.charsetter.StreamCharset; @@ -12,9 +15,6 @@ import io.xpipe.core.store.DataStore; import io.xpipe.core.store.StreamDataStore; import io.xpipe.ext.base.SimpleFileDataSourceProvider; import io.xpipe.ext.jackson.xml.XmlProvider; -import io.xpipe.extension.util.DialogHelper; -import io.xpipe.extension.util.DynamicOptionsBuilder; -import io.xpipe.extension.util.UniformDataSourceProvider; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; @@ -29,7 +29,7 @@ import java.util.Map; public class XmlTableProvider implements UniformDataSourceProvider, - SimpleFileDataSourceProvider { + SimpleFileDataSourceProvider { @Override public boolean shouldShow(DataSourceType type) { diff --git a/ext/jackson/src/main/java/module-info.java b/ext/jackson/src/main/java/module-info.java index c7c1ad780..0fdcb8784 100644 --- a/ext/jackson/src/main/java/module-info.java +++ b/ext/jackson/src/main/java/module-info.java @@ -1,12 +1,12 @@ +import io.xpipe.app.ext.DataSourceProvider; import io.xpipe.ext.jackson.json.JsonProvider; import io.xpipe.ext.jackson.json_table.JsonTableProvider; import io.xpipe.ext.jackson.xml.XmlProvider; import io.xpipe.ext.jackson.xml_table.XmlTableProvider; -import io.xpipe.extension.DataSourceProvider; module io.xpipe.ext.jackson { requires io.xpipe.core; - requires io.xpipe.extension; + requires io.xpipe.app; requires com.fasterxml.jackson.databind; requires static lombok; requires com.fasterxml.jackson.dataformat.xml; diff --git a/ext/pdx/build.gradle b/ext/pdx/build.gradle index 649c78e61..a629df931 100644 --- a/ext/pdx/build.gradle +++ b/ext/pdx/build.gradle @@ -10,3 +10,7 @@ apply from: "$rootDir/gradle/gradle_scripts/extension.gradle" configurations { compileOnly.extendsFrom(dep) } + +dependencies { + compileOnly project(':app') +} diff --git a/ext/pdx/src/main/java/io/xpipe/ext/pdx/Eu4FileProvider.java b/ext/pdx/src/main/java/io/xpipe/ext/pdx/Eu4FileProvider.java index f594ba1f7..e22073a28 100644 --- a/ext/pdx/src/main/java/io/xpipe/ext/pdx/Eu4FileProvider.java +++ b/ext/pdx/src/main/java/io/xpipe/ext/pdx/Eu4FileProvider.java @@ -1,10 +1,10 @@ package io.xpipe.ext.pdx; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.ext.DataSourceProviders; import io.xpipe.core.store.DataFlow; import io.xpipe.core.store.DataStore; import io.xpipe.ext.pdx.savegame.SavegameType; -import io.xpipe.extension.DataSourceProviders; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; diff --git a/ext/pdx/src/main/java/io/xpipe/ext/pdx/PdxFileProvider.java b/ext/pdx/src/main/java/io/xpipe/ext/pdx/PdxFileProvider.java index 409e9643f..751cbcbb4 100644 --- a/ext/pdx/src/main/java/io/xpipe/ext/pdx/PdxFileProvider.java +++ b/ext/pdx/src/main/java/io/xpipe/ext/pdx/PdxFileProvider.java @@ -1,12 +1,12 @@ package io.xpipe.ext.pdx; +import io.xpipe.app.ext.DataSourceProviders; +import io.xpipe.app.util.UniformDataSourceProvider; import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.source.*; import io.xpipe.core.store.StreamDataStore; import io.xpipe.ext.base.SimpleFileDataSourceProvider; import io.xpipe.ext.pdx.savegame.SavegameType; -import io.xpipe.extension.DataSourceProviders; -import io.xpipe.extension.util.UniformDataSourceProvider; import lombok.experimental.SuperBuilder; import java.util.LinkedHashMap; @@ -31,7 +31,6 @@ public abstract class PdxFileProvider> CollectionDataSource ds = DataSourceProviders.byId("zip") .createDefaultSource(in.getStore()) .asNeeded(); - ds.annotate(d.annotateContents()); return ds; } diff --git a/ext/pdx/src/main/java/io/xpipe/ext/pdx/PdxTextFileProvider.java b/ext/pdx/src/main/java/io/xpipe/ext/pdx/PdxTextFileProvider.java index efe7da74e..79086b337 100644 --- a/ext/pdx/src/main/java/io/xpipe/ext/pdx/PdxTextFileProvider.java +++ b/ext/pdx/src/main/java/io/xpipe/ext/pdx/PdxTextFileProvider.java @@ -1,6 +1,7 @@ package io.xpipe.ext.pdx; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.util.UniformDataSourceProvider; import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.source.*; import io.xpipe.core.store.DataFlow; @@ -8,7 +9,6 @@ import io.xpipe.core.store.DataStore; import io.xpipe.core.store.StreamDataStore; import io.xpipe.ext.base.SimpleFileDataSourceProvider; import io.xpipe.ext.pdx.parser.TextFormatParser; -import io.xpipe.extension.util.UniformDataSourceProvider; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; @@ -18,7 +18,7 @@ import java.util.Map; public class PdxTextFileProvider implements UniformDataSourceProvider, - SimpleFileDataSourceProvider { + SimpleFileDataSourceProvider { @Override public Source createDefaultSource(DataStore input) throws Exception { diff --git a/ext/pdx/src/main/java/module-info.java b/ext/pdx/src/main/java/module-info.java index e53ed832d..d0294da59 100644 --- a/ext/pdx/src/main/java/module-info.java +++ b/ext/pdx/src/main/java/module-info.java @@ -1,12 +1,12 @@ +import io.xpipe.app.ext.DataSourceProvider; import io.xpipe.ext.pdx.Eu4FileProvider; import io.xpipe.ext.pdx.PdxTextFileProvider; -import io.xpipe.extension.DataSourceProvider; module io.xpipe.ext.pdx { requires io.xpipe.core; - requires io.xpipe.extension; requires org.apache.commons.lang3; requires static lombok; + requires io.xpipe.app; requires io.xpipe.ext.base; requires com.fasterxml.jackson.databind; diff --git a/extension/LICENSE.md b/extension/LICENSE.md deleted file mode 100644 index 4fe3f425e..000000000 --- a/extension/LICENSE.md +++ /dev/null @@ -1,7 +0,0 @@ -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/README.md b/extension/README.md deleted file mode 100644 index 4df54afec..000000000 --- a/extension/README.md +++ /dev/null @@ -1,7 +0,0 @@ -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.xpipe/xpipe-extension/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.xpipe/xpipe-extension) -[![javadoc](https://javadoc.io/badge2/io.xpipe/xpipe-extension/javadoc.svg)](https://javadoc.io/doc/io.xpipe/xpipe-extension) - -## X-Pipe Extension API - -The X-Pipe extension API allows you to create extensions of any kind for X-Pipe. -For more information, see [X-Pipe extension development](https://xpipe-io.readthedocs.io/en/latest/dev/extensions/index.html). diff --git a/extension/build.gradle b/extension/build.gradle deleted file mode 100644 index 9d80a7485..000000000 --- a/extension/build.gradle +++ /dev/null @@ -1,48 +0,0 @@ -plugins { - id 'java-library' - id 'maven-publish' - id 'signing' - id "org.moditect.gradleplugin" version "1.0.0-rc3" -} - -apply from: "$rootDir/gradle/gradle_scripts/java.gradle" -apply from: "$rootDir/gradle/gradle_scripts/javafx.gradle" -apply from: "$rootDir/gradle/gradle_scripts/lombok.gradle" - -configurations { - compileOnly.extendsFrom(dep) -} - -version = rootProject.versionString -group = 'io.xpipe' -archivesBaseName = 'xpipe-extension' - -dependencies { - api project(':core') - api project(':beacon') - api project(':api') - api group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "2.13.0" - api group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: "2.13.0" - - compileOnly 'org.hamcrest:hamcrest:2.2' - compileOnly 'net.java.dev.jna:jna-jpms:5.12.1' - compileOnly 'net.java.dev.jna:jna-platform-jpms:5.12.1' - compileOnly group: 'org.kordamp.ikonli', name: 'ikonli-javafx', version: "12.2.0" - compileOnly group: 'org.fxmisc.richtext', name: 'richtextfx', version: '0.10.9' - compileOnly 'net.synedra:validatorfx:0.3.1' - compileOnly 'org.junit.jupiter:junit-jupiter-api:5.9.0' - compileOnly 'org.junit.jupiter:junit-jupiter-params:5.9.0' - compileOnly 'com.jfoenix:jfoenix:9.0.10' - compileOnly 'org.controlsfx:controlsfx:11.1.2' - compileOnly 'org.apache.commons:commons-lang3:3.12.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) { - from jar.archiveFile - into "${project(':dist').buildDir}/dist/libraries" -} - -apply from: 'publish.gradle' -apply from: "$rootDir/gradle/gradle_scripts/publish-base.gradle" diff --git a/extension/publish.gradle b/extension/publish.gradle deleted file mode 100644 index 4fd51e4d8..000000000 --- a/extension/publish.gradle +++ /dev/null @@ -1,33 +0,0 @@ -publishing { - publications { - mavenJava(MavenPublication) { - artifactId = project.archivesBaseName - - from components.java - - pom { - name = 'X-Pipe Extension Base' - description = 'Classes required to create X-Pipe extensions.' - url = 'https://github.com/xpipe-io/xpipe/extension' - licenses { - license { - name = 'The MIT License (MIT)' - url = 'https://github.com/xpipe-io/xpipe/LICENSE.md' - } - } - developers { - developer { - id = 'crschnick' - name = 'Christopher Schnick' - email = 'crschnick@xpipe.io' - } - } - scm { - connection = 'scm:git:git://github.com/xpipe-io/xpipe.git' - developerConnection = 'scm:git:ssh://github.com/xpipe-io/xpipe.git' - url = 'https://github.com/xpipe-io/xpipe' - } - } - } - } -} diff --git a/extension/src/main/java/io/xpipe/extension/Cache.java b/extension/src/main/java/io/xpipe/extension/Cache.java deleted file mode 100644 index 31680234b..000000000 --- a/extension/src/main/java/io/xpipe/extension/Cache.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.xpipe.extension; - -import java.util.Optional; -import java.util.ServiceLoader; -import java.util.function.Supplier; - -public interface Cache { - - Cache INSTANCE = ServiceLoader.load(Cache.class).findFirst().orElseThrow(); - - @SuppressWarnings("unchecked") - public static V get(String key, Class type, Supplier notPresent) { - return (V) INSTANCE.getValue(key, type, notPresent); - } - - public static Optional getIfPresent(String key, Class type) { - return Optional.ofNullable(get(key, type, () -> null)); - } - - public static void update(String key, T val) { - INSTANCE.updateValue(key, val); - } - - public T getValue(String key, Class type, Supplier notPresent); - - public void updateValue(String key, T val); -} diff --git a/extension/src/main/java/io/xpipe/extension/I18n.java b/extension/src/main/java/io/xpipe/extension/I18n.java deleted file mode 100644 index b300c980e..000000000 --- a/extension/src/main/java/io/xpipe/extension/I18n.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.xpipe.extension; - -import javafx.beans.binding.Bindings; -import javafx.beans.value.ObservableValue; - -import java.util.ServiceLoader; - -public interface I18n { - - I18n INSTANCE = ServiceLoader.load(I18n.class).findFirst().orElseThrow(); - - public static ObservableValue observable(String s, Object... vars) { - if (s == null) { - return null; - } - - var key = INSTANCE.getKey(s); - return Bindings.createStringBinding(() -> { - return get(key, vars); - }); - } - - public static String get(String s, Object... vars) { - return INSTANCE.getLocalised(s, vars); - } - - String getKey(String s); - - String getLocalised(String s, Object... vars); - - boolean isLoaded(); -} diff --git a/extension/src/main/java/io/xpipe/extension/event/ExceptionConverter.java b/extension/src/main/java/io/xpipe/extension/event/ExceptionConverter.java deleted file mode 100644 index 744949a6d..000000000 --- a/extension/src/main/java/io/xpipe/extension/event/ExceptionConverter.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.xpipe.extension.event; - -import io.xpipe.extension.I18n; - -import java.io.FileNotFoundException; - -public class ExceptionConverter { - - public static String convertMessage(Throwable ex) { - var msg = ex.getLocalizedMessage(); - - if (!I18n.INSTANCE.isLoaded()) { - return msg; - } - - return switch (ex) { - case StackOverflowError e -> I18n.get("extension.stackOverflow"); - case OutOfMemoryError e -> I18n.get("extension.outOfMemory"); - case FileNotFoundException e -> I18n.get("extension.fileNotFound", msg); - case NullPointerException e -> I18n.get("extension.nullPointer"); - case UnsupportedOperationException e -> I18n.get("extension.unsupportedOperation", msg); - case ClassNotFoundException e -> I18n.get("extension.classNotFound", msg); - default -> { - if (msg == null || msg.trim().length() == 0) { - yield I18n.get("extension.noInformationAvailable"); - } - - yield msg; - } - }; - } -} diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/augment/Augment.java b/extension/src/main/java/io/xpipe/extension/fxcomps/augment/Augment.java deleted file mode 100644 index 9fea1d605..000000000 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/augment/Augment.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.xpipe.extension.fxcomps.augment; - -import io.xpipe.extension.fxcomps.CompStructure; - -public interface Augment> { - - void augment(S struc); -} diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/PrettyImageComp.java b/extension/src/main/java/io/xpipe/extension/fxcomps/impl/PrettyImageComp.java deleted file mode 100644 index de4b55f1e..000000000 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/PrettyImageComp.java +++ /dev/null @@ -1,96 +0,0 @@ -package io.xpipe.extension.fxcomps.impl; - -import io.xpipe.extension.fxcomps.SimpleComp; -import io.xpipe.extension.fxcomps.util.PlatformThread; -import io.xpipe.extension.util.XPipeDaemon; -import javafx.beans.binding.Bindings; -import javafx.beans.property.SimpleDoubleProperty; -import javafx.beans.value.ObservableValue; -import javafx.geometry.Pos; -import javafx.scene.Node; -import javafx.scene.image.ImageView; -import javafx.scene.layout.Region; -import javafx.scene.layout.StackPane; -import javafx.scene.web.WebView; - -public class PrettyImageComp extends SimpleComp { - - private final ObservableValue value; - private final double width; - private final double height; - - public PrettyImageComp(ObservableValue value, double width, double height) { - this.value = value; - this.width = width; - this.height = height; - } - - @Override - protected Region createSimple() { - var aspectRatioProperty = new SimpleDoubleProperty(1); - var widthProperty = Bindings.createDoubleBinding( - () -> { - boolean widthLimited = width / height < aspectRatioProperty.doubleValue(); - if (widthLimited) { - return width; - } else { - return height * aspectRatioProperty.doubleValue(); - } - }, - aspectRatioProperty); - var heightProperty = Bindings.createDoubleBinding( - () -> { - boolean widthLimited = width / height < aspectRatioProperty.doubleValue(); - if (widthLimited) { - return width / aspectRatioProperty.doubleValue(); - } else { - return height; - } - }, - aspectRatioProperty); - - Node node; - - if (value.getValue().endsWith(".svg")) { - var storeIcon = SvgComp.create( - Bindings.createStringBinding(() -> XPipeDaemon.getInstance().svgImage(value.getValue()), value)); - aspectRatioProperty.bind(Bindings.createDoubleBinding( - () -> { - return storeIcon.getWidth().getValue().doubleValue() - / storeIcon.getHeight().getValue().doubleValue(); - }, - storeIcon.getWidth(), - storeIcon.getHeight())); - node = storeIcon.createWebview(); - ((WebView) node).prefWidthProperty().bind(widthProperty); - ((WebView) node).maxWidthProperty().bind(widthProperty); - ((WebView) node).minWidthProperty().bind(widthProperty); - ((WebView) node).prefHeightProperty().bind(heightProperty); - ((WebView) node).maxHeightProperty().bind(heightProperty); - ((WebView) node).minHeightProperty().bind(heightProperty); - } else { - var storeIcon = new ImageView(); - storeIcon - .imageProperty() - .bind(Bindings.createObjectBinding( - () -> { - var image = XPipeDaemon.getInstance().image(value.getValue()); - aspectRatioProperty.set(image.getWidth() / image.getHeight()); - return image; - }, - PlatformThread.sync(value))); - storeIcon.fitWidthProperty().bind(widthProperty); - storeIcon.fitHeightProperty().bind(heightProperty); - storeIcon.setSmooth(true); - node = storeIcon; - } - - var stack = new StackPane(node); - stack.setPrefWidth(width); - stack.setMinWidth(width); - stack.setPrefHeight(height); - stack.setMinHeight(height); - stack.setAlignment(Pos.CENTER); - return stack; - } -} diff --git a/extension/src/main/java/module-info.java b/extension/src/main/java/module-info.java deleted file mode 100644 index ba7fa4c04..000000000 --- a/extension/src/main/java/module-info.java +++ /dev/null @@ -1,61 +0,0 @@ -import io.xpipe.core.util.ProxyFunction; -import io.xpipe.extension.DataSourceProvider; -import io.xpipe.extension.DataSourceTarget; -import io.xpipe.extension.prefs.PrefsProvider; -import io.xpipe.extension.util.ActionProvider; -import io.xpipe.extension.util.ModuleLayerLoader; -import io.xpipe.extension.util.XPipeDaemon; - -open module io.xpipe.extension { - exports io.xpipe.extension; - exports io.xpipe.extension.event; - exports io.xpipe.extension.prefs; - exports io.xpipe.extension.util; - exports io.xpipe.extension.fxcomps; - exports io.xpipe.extension.fxcomps.impl; - exports io.xpipe.extension.fxcomps.util; - exports io.xpipe.extension.fxcomps.augment; - exports io.xpipe.extension.test; - - requires transitive io.xpipe.core; - requires io.xpipe.beacon; - requires io.xpipe.api; - requires static org.hamcrest; - requires com.fasterxml.jackson.databind; - requires static com.sun.jna; - requires static com.sun.jna.platform; - requires static org.junit.jupiter.api; - requires static org.junit.jupiter.params; - requires static org.apache.commons.lang3; - requires static javafx.base; - requires static javafx.graphics; - requires static javafx.controls; - requires static javafx.web; - requires static lombok; - requires static org.controlsfx.controls; - requires static java.desktop; - requires static org.fxmisc.richtext; - requires static net.synedra.validatorfx; - requires static org.fxmisc.flowless; - requires static org.kordamp.ikonli.javafx; - requires static com.jfoenix; - requires static com.dlsc.preferencesfx; - requires static com.dlsc.formsfx; - - uses DataSourceProvider; - uses DataSourceTarget; - uses io.xpipe.extension.I18n; - uses io.xpipe.extension.event.EventHandler; - uses io.xpipe.extension.prefs.PrefsProvider; - uses io.xpipe.extension.DataStoreProvider; - uses XPipeDaemon; - uses io.xpipe.extension.Cache; - uses ProxyFunction; - uses ActionProvider; - uses io.xpipe.extension.util.ModuleLayerLoader; - - provides ModuleLayerLoader with - DataSourceTarget.Loader, - ActionProvider.Loader, - PrefsProvider.Loader; -} diff --git a/extension/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module b/extension/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module deleted file mode 100644 index d4caa9b68..000000000 --- a/extension/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module +++ /dev/null @@ -1 +0,0 @@ -io.xpipe.beacon.BeaconJacksonModule \ No newline at end of file diff --git a/extension/src/main/resources/io/xpipe/extension/resources/lang/translations_de.properties b/extension/src/main/resources/io/xpipe/extension/resources/lang/translations_de.properties deleted file mode 100644 index d86dcac53..000000000 --- a/extension/src/main/resources/io/xpipe/extension/resources/lang/translations_de.properties +++ /dev/null @@ -1,3 +0,0 @@ -displayName=Mein Dateiformat -description=Meine Dateiformat-Beschreibung -fileName=Mein Dateiformat Datei \ No newline at end of file diff --git a/extension/src/main/resources/io/xpipe/extension/resources/lang/translations_en.properties b/extension/src/main/resources/io/xpipe/extension/resources/lang/translations_en.properties deleted file mode 100644 index 0cdbcca39..000000000 --- a/extension/src/main/resources/io/xpipe/extension/resources/lang/translations_en.properties +++ /dev/null @@ -1,31 +0,0 @@ -charset=Charset -newLine=Newline -crlf=CRLF (Windows) -lf=LF (Linux) -none=None -common=Common -other=Other -nullPointer=Null Pointer -mustNotBeEmpty=$NAME$ must not be empty -null=$VALUE$ must be not null -hostFeatureUnsupported=Host does not support the feature $FEATURE$ -missingStore=$NAME$ does not exist -unknown=Unknown -namedHostFeatureUnsupported=$HOST$ does not support this feature -namedHostNotActive=$HOST$ is not active -noInformationAvailable=No information available -localMachine=Local Machine -input=Input -output=Output -inout=Transformation -inputDescription=This store only produces input for data sources to read -outputDescription=This store only accepts output from data sources to write -inoutDescription=This store uses both input and output to essentially create a data transformation -replace=Replace -append=Append -prepend=Prepend -replaceDescription=Replaces all content -appendDescription=Appends the new content to the existing content -prependDescription=Prepends the new content to the existing content -yes=Yes -no=No \ No newline at end of file diff --git a/gradle/gradle_scripts/extension.gradle b/gradle/gradle_scripts/extension.gradle index 6c878ebb4..c804f1d6e 100644 --- a/gradle/gradle_scripts/extension.gradle +++ b/gradle/gradle_scripts/extension.gradle @@ -8,42 +8,25 @@ copyRuntimeLibs.dependsOn(addDependenciesModuleInfo) jar.dependsOn(copyRuntimeLibs) def dev = tasks.register('createDevOutput', Copy) { - def base = project.name.substring(0, project.name.length() - 1) - def isX = project.name.endsWith("x") && findProject(":$base") != null var source = "${project.jar.destinationDirectory.get()}" - if (isX) { - from source - into "${project(':' + base).jar.destinationDirectory.get()}_dev" - } else { - from source - into "${project.jar.destinationDirectory.get()}_dev" - } + from source + into "${project.rootDir}/app/build/ext_dev/$project.name" } jar.finalizedBy(dev) tasks.register('createExtOutput', Copy) { - def base = project.name.substring(0, project.name.length() - 1) - def isX = project.name.endsWith("x") && findProject(":$base") != null - - doFirst { - if (!file("${project.jar.destinationDirectory.get()}_prod").exists()) { - copy { - from "${project.jar.destinationDirectory.get()}" - into "${project.jar.destinationDirectory.get()}_prod" - } + if (!file("${project.jar.destinationDirectory.get()}_prod").exists()) { + copy { + from "${project.jar.destinationDirectory.get()}" + into "${project.jar.destinationDirectory.get()}_prod" } } def shouldObfuscate = rootProject.obfuscate && rootProject.privateExtensions.contains(project.name) var source = shouldObfuscate ? "${project.jar.destinationDirectory.get()}_prod" : "${project.jar.destinationDirectory.get()}" - if (isX) { - from source - into "${project(':' + base).jar.destinationDirectory.get()}_ext" - } else { - from source - into "${project.jar.destinationDirectory.get()}_ext" - } + from source + into "${project.jar.destinationDirectory.get()}_ext" } apply from: "$rootDir/gradle/gradle_scripts/java.gradle" @@ -53,13 +36,15 @@ apply from: "$rootDir/gradle/gradle_scripts/extension_test.gradle" dependencies { compileOnly group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "2.13.0" - compileOnly project(':extension') + compileOnly project(':core') + compileOnly project(':beacon') + compileOnly project(':app') compileOnly 'net.synedra:validatorfx:0.3.1' if (project != project(':base')) { compileOnly project(':base') } - testImplementation project(':extension') + testImplementation project(':app') } diff --git a/gradle/gradle_scripts/extension_test.gradle b/gradle/gradle_scripts/extension_test.gradle index 049b1a7f8..60da50e8d 100644 --- a/gradle/gradle_scripts/extension_test.gradle +++ b/gradle/gradle_scripts/extension_test.gradle @@ -7,7 +7,6 @@ def useExtension = System.getProperty('excludeExtensionLibrary') == null dependencies { testImplementation project(':api') testImplementation project(':core') - testImplementation project(':extension') testImplementation "org.openjfx:javafx-base:19:win" testImplementation "org.openjfx:javafx-controls:19:win" diff --git a/settings.gradle b/settings.gradle index 1bc888afe..99499971a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,7 +3,6 @@ rootProject.name = 'xpipe' include 'api' include 'core' include 'beacon' -include 'extension' for (def ext : file("ext").list()) { include "$ext"