flea-qml 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +511 -2
- package/THIRD-PARTY-NOTICES.md +29 -0
- package/demos/App.java +5 -0
- package/demos/Dockerfile +4 -0
- package/demos/Main.kt +3 -0
- package/demos/Program.cs +1 -0
- package/demos/README.md +12 -0
- package/demos/app.dart +3 -0
- package/demos/app.deb +0 -0
- package/demos/app.js +1 -0
- package/demos/backup.tar +0 -0
- package/demos/budget.xlsx +0 -0
- package/demos/build.sh +2 -0
- package/demos/bundle.zip +0 -0
- package/demos/clip.mp4 +0 -0
- package/demos/data.sqlite +0 -0
- package/demos/disk.iso +0 -0
- package/demos/engine.cpp +5 -0
- package/demos/firmware.bin +0 -0
- package/demos/flake.nix +4 -0
- package/demos/folder/inside.txt +1 -0
- package/demos/font.ttf +0 -0
- package/demos/index.html +5 -0
- package/demos/index.php +2 -0
- package/demos/init.lua +1 -0
- package/demos/letter.docx +0 -0
- package/demos/lib.rs +3 -0
- package/demos/main.c +6 -0
- package/demos/main.h +3 -0
- package/demos/math-and-diagrams.md +200 -0
- package/demos/notes.tar.gz +0 -0
- package/demos/notes.txt +3 -0
- package/demos/photo.png +0 -0
- package/demos/program +2 -0
- package/demos/report.pdf +32 -0
- package/demos/script.py +1 -0
- package/demos/server.go +7 -0
- package/demos/settings.json +4 -0
- package/demos/slides.pptx +0 -0
- package/demos/song.mp3 +0 -0
- package/demos/style.css +4 -0
- package/demos/tool.rb +1 -0
- package/demos/types.ts +2 -0
- package/docs/pele.md +23 -0
- package/docs/protocol.md +3420 -0
- package/docs/temml.md +63 -0
- package/index.js +107 -0
- package/package.json +34 -4
- package/src/archive.js +407 -0
- package/src/archiveops.js +728 -0
- package/src/backend.js +369 -0
- package/src/bulkrename.js +95 -0
- package/src/clip-host.js +76 -0
- package/src/clip.js +462 -0
- package/src/code.js +168 -0
- package/src/compare.js +74 -0
- package/src/create.js +128 -0
- package/src/dirsize.js +147 -0
- package/src/figure-svg.js +530 -0
- package/src/figure-thread.js +23 -0
- package/src/figure.js +132 -0
- package/src/find.js +55 -0
- package/src/flea.js +39 -0
- package/src/fsinfo.js +39 -0
- package/src/highlight.js +141 -0
- package/src/html.js +52 -0
- package/src/kinds.js +89 -0
- package/src/listing.js +130 -0
- package/src/markdown-html.js +317 -0
- package/src/mathml.js +186 -0
- package/src/menu.js +180 -0
- package/src/meta.js +135 -0
- package/src/office.js +810 -0
- package/src/order.js +100 -0
- package/src/peek.js +49 -0
- package/src/pele-wrapper.js +695 -0
- package/src/permissions.js +180 -0
- package/src/places.js +313 -0
- package/src/preview-language.js +10 -0
- package/src/terminal-server.js +95 -0
- package/src/terminal-shell.js +26 -0
- package/src/transfer.js +669 -0
- package/src/trash-record.js +41 -0
- package/src/trash.js +210 -0
- package/src/trashbrowse.js +327 -0
- package/src/uistate.js +393 -0
- package/src/uistore.js +168 -0
- package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
- package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
- package/src/vendor/LICENSES/MIT-katex.txt +21 -0
- package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
- package/src/vendor/LICENSES/MIT-pele.txt +40 -0
- package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
- package/src/vendor/LICENSES/MIT-temml.txt +21 -0
- package/src/vendor/pele.js +145 -0
- package/src/vendor/temml.mjs +14708 -0
- package/src/watch.js +98 -0
- package/src/wayland/client.js +109 -0
- package/src/wayland/protocol.js +55 -0
- package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
- package/src/wayland/protocols/wayland.xml +3248 -0
- package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
- package/src/wayland/resource-io.js +6 -0
- package/src/wayland/socket-discovery.js +26 -0
- package/src/wayland/transport-posix.js +120 -0
- package/src/wayland/transport-win32.js +11 -0
- package/src/wayland/transport.js +3 -0
- package/src/wayland/win32-resources.js +80 -0
- package/src/wayland/win32-wire.js +62 -0
- package/test/archive.test.js +80 -0
- package/test/bench-markdown-scroll.mjs +190 -0
- package/test/clip-host.test.js +113 -0
- package/test/code-preview.test.js +35 -0
- package/test/compare-ui-paths.test.js +24 -0
- package/test/compare.test.js +54 -0
- package/test/delete-trash.test.js +67 -0
- package/test/dirsize.test.js +138 -0
- package/test/file-ops.test.js +307 -0
- package/test/file-url.test.js +24 -0
- package/test/find-contents.test.js +161 -0
- package/test/find-input.test.js +66 -0
- package/test/fixtures/pele-parity.json +1006 -0
- package/test/highlight-launcher.test.js +35 -0
- package/test/html-preview.test.js +22 -0
- package/test/input.test.js +15 -0
- package/test/keymap.test.js +26 -0
- package/test/language-icons.test.js +36 -0
- package/test/launcher.test.js +51 -0
- package/test/manual-archive-here-ui.mjs +47 -0
- package/test/manual-code-scroll.mjs +28 -0
- package/test/manual-column-scroll.mjs +24 -0
- package/test/manual-compare-ui.mjs +20 -0
- package/test/manual-find-status.mjs +37 -0
- package/test/manual-folder-focus.mjs +63 -0
- package/test/manual-html-security.mjs +23 -0
- package/test/manual-html-ui.mjs +30 -0
- package/test/manual-syntax-preview.mjs +26 -0
- package/test/manual-terminal-lifecycle.mjs +42 -0
- package/test/manual-terminal-navigation.mjs +48 -0
- package/test/manual-terminal-ui.mjs +47 -0
- package/test/manual-trash-ui.mjs +86 -0
- package/test/markdown-diagrams.test.js +93 -0
- package/test/markdown-html.test.js +105 -0
- package/test/mathml.test.js +92 -0
- package/test/menu-transfer.test.js +57 -0
- package/test/office-preview.test.js +154 -0
- package/test/pele-parity.test.js +28 -0
- package/test/places.test.js +134 -0
- package/test/preview-keys.test.js +60 -0
- package/test/preview-language.test.js +22 -0
- package/test/status-filename.test.js +20 -0
- package/test/transfer-replace-merge.test.js +187 -0
- package/test/trash-address.test.js +23 -0
- package/test/trash-view.test.js +37 -0
- package/test/trashbrowse.test.js +135 -0
- package/ui/AboutFacts.qml +78 -0
- package/ui/ArchiveCards.qml +95 -0
- package/ui/ArchiveCompressDialog.qml +378 -0
- package/ui/ArchiveHereConfirm.qml +127 -0
- package/ui/ArchivePasswordDialog.qml +257 -0
- package/ui/Backend.qml +775 -0
- package/ui/BulkOldNames.qml +47 -0
- package/ui/BulkRenameDialog.qml +380 -0
- package/ui/CardFrame.qml +67 -0
- package/ui/CardScroll.qml +79 -0
- package/ui/CheckBox.qml +73 -0
- package/ui/ChromeBar.qml +360 -0
- package/ui/ChromeButton.qml +131 -0
- package/ui/ChromeModes.qml +43 -0
- package/ui/CodeLines.qml +256 -0
- package/ui/CodeRefusal.qml +52 -0
- package/ui/CollideConfirm.qml +147 -0
- package/ui/CollideHost.qml +167 -0
- package/ui/ColumnPane.qml +525 -0
- package/ui/ColumnRow.qml +380 -0
- package/ui/ColumnsArea.qml +594 -0
- package/ui/ColumnsLanding.qml +147 -0
- package/ui/CompareView.qml +321 -0
- package/ui/ContextMenu.qml +743 -0
- package/ui/ConvertDialog.qml +456 -0
- package/ui/CountedWorker.qml +7 -0
- package/ui/Crumb.qml +64 -0
- package/ui/CrumbDrop.qml +25 -0
- package/ui/CsvTable.qml +394 -0
- package/ui/CursorMark.qml +41 -0
- package/ui/DefaultClaim.qml +130 -0
- package/ui/DeviceLock.qml +47 -0
- package/ui/DeviceMounts.qml +540 -0
- package/ui/DialogButton.qml +150 -0
- package/ui/DialogField.qml +147 -0
- package/ui/DialogHeader.qml +31 -0
- package/ui/DialogScrim.qml +20 -0
- package/ui/DialogTitle.qml +37 -0
- package/ui/Divider.qml +9 -0
- package/ui/DropInto.qml +126 -0
- package/ui/DropTarget.qml +35 -0
- package/ui/DropboxMark.qml +60 -0
- package/ui/EmptyState.qml +150 -0
- package/ui/EscapeHint.qml +11 -0
- package/ui/FactsTable.qml +54 -0
- package/ui/FastScrollHandler.qml +476 -0
- package/ui/FatNamesConfirm.qml +157 -0
- package/ui/Favourites.qml +143 -0
- package/ui/FigureService.qml +120 -0
- package/ui/FileDrag.qml +267 -0
- package/ui/FilterStrip.qml +133 -0
- package/ui/FitMetrics.qml +22 -0
- package/ui/FlashDriveRows.qml +137 -0
- package/ui/FlashHost.qml +72 -0
- package/ui/FlashImageRow.qml +104 -0
- package/ui/FlashRunner.qml +119 -0
- package/ui/FlashStepRow.qml +172 -0
- package/ui/FlashStrip.qml +38 -0
- package/ui/FlashView.qml +397 -0
- package/ui/FleaMark.qml +88 -0
- package/ui/FlyoutFade.qml +23 -0
- package/ui/FontPane.qml +170 -0
- package/ui/Glass.qml +114 -0
- package/ui/GlassTagger.qml +59 -0
- package/ui/Glyph.qml +64 -0
- package/ui/GlyphSolid.qml +22 -0
- package/ui/GridArea.qml +664 -0
- package/ui/GridTile.qml +325 -0
- package/ui/GvfsBridge.qml +164 -0
- package/ui/Header.qml +433 -0
- package/ui/HoverTimers.qml +39 -0
- package/ui/HtmlClip.qml +30 -0
- package/ui/HtmlPane.qml +63 -0
- package/ui/HyprlandMark.qml +45 -0
- package/ui/Ipc.qml +1005 -0
- package/ui/IpcControls.qml +7 -0
- package/ui/IpcMenuState.qml +48 -0
- package/ui/IpcPreviewState.qml +185 -0
- package/ui/JumpPath.qml +51 -0
- package/ui/KeymapSheet.qml +561 -0
- package/ui/KeymapSheetResult.qml +89 -0
- package/ui/KindStack.qml +40 -0
- package/ui/LangMark.qml +51 -0
- package/ui/LangMarkLoader.qml +26 -0
- package/ui/List.qml +480 -0
- package/ui/LoadingState.qml +54 -0
- package/ui/LocalSend.qml +56 -0
- package/ui/LocalSendMark.qml +73 -0
- package/ui/MarkdownBlockView.qml +311 -0
- package/ui/MarkdownBlocks.qml +35 -0
- package/ui/MarkdownFigure.qml +254 -0
- package/ui/MarkdownImages.qml +72 -0
- package/ui/MarkdownList.qml +81 -0
- package/ui/MarkdownMathsText.qml +97 -0
- package/ui/MarkdownPane.qml +83 -0
- package/ui/MarkdownPictures.qml +41 -0
- package/ui/MarkdownQuote.qml +52 -0
- package/ui/MarkdownRemote.qml +82 -0
- package/ui/MarkdownSource.qml +155 -0
- package/ui/MarkdownTable.qml +222 -0
- package/ui/MarkdownTableScroll.qml +64 -0
- package/ui/MarkdownTableWheel.qml +126 -0
- package/ui/MarkdownText.qml +87 -0
- package/ui/MarkdownWorker.js +132 -0
- package/ui/MatchText.qml +99 -0
- package/ui/MediaSession.qml +38 -0
- package/ui/MediaSound.qml +26 -0
- package/ui/MediaStrip.qml +191 -0
- package/ui/MediaTrack.qml +36 -0
- package/ui/MediaVolume.qml +54 -0
- package/ui/MenuActionDialog.qml +396 -0
- package/ui/MenuEdgeFade.qml +24 -0
- package/ui/MenuHost.qml +227 -0
- package/ui/MenuRow.qml +351 -0
- package/ui/MountListing.qml +100 -0
- package/ui/NetworkDialog.qml +435 -0
- package/ui/NetworkForm.qml +426 -0
- package/ui/NetworkMounts.qml +913 -0
- package/ui/NetworkPlaces.qml +127 -0
- package/ui/OpenWithDialog.qml +613 -0
- package/ui/Opener.qml +95 -0
- package/ui/Pane.qml +1320 -0
- package/ui/PaneMenuActions.qml +527 -0
- package/ui/PanePath.qml +90 -0
- package/ui/PaneRail.qml +268 -0
- package/ui/PaneStates.qml +88 -0
- package/ui/PaneSwap.qml +339 -0
- package/ui/PaneWire.qml +601 -0
- package/ui/ParkedWait.qml +9 -0
- package/ui/PathEntry.qml +186 -0
- package/ui/PathJump.qml +400 -0
- package/ui/PdfViewer.qml +297 -0
- package/ui/PermissionsDialog.qml +658 -0
- package/ui/PermissionsHeadings.qml +31 -0
- package/ui/PhoneMounts.qml +67 -0
- package/ui/PickerAnswers.qml +75 -0
- package/ui/PickerBox.qml +26 -0
- package/ui/PickerChrome.qml +295 -0
- package/ui/PickerFilter.qml +97 -0
- package/ui/PickerGrid.qml +308 -0
- package/ui/PickerHeader.qml +28 -0
- package/ui/PickerLifecycle.qml +27 -0
- package/ui/PickerList.qml +218 -0
- package/ui/PickerListing.qml +149 -0
- package/ui/PickerPathBar.qml +127 -0
- package/ui/PickerPlaces.qml +189 -0
- package/ui/PickerRecent.qml +92 -0
- package/ui/PickerSave.qml +101 -0
- package/ui/PickerSelection.qml +155 -0
- package/ui/PickerWindow.qml +846 -0
- package/ui/PowerSectorsReader.qml +10 -0
- package/ui/PrebuildDriver.qml +146 -0
- package/ui/Preview.qml +1005 -0
- package/ui/PreviewAnimation.qml +24 -0
- package/ui/PreviewArchive.qml +91 -0
- package/ui/PreviewColumn.qml +553 -0
- package/ui/PreviewEdge.qml +63 -0
- package/ui/PreviewFacts.qml +30 -0
- package/ui/PreviewFactsLine.qml +34 -0
- package/ui/PreviewHtml.qml +233 -0
- package/ui/PreviewImage.qml +253 -0
- package/ui/PreviewImagePan.qml +13 -0
- package/ui/PreviewImageSharp.qml +32 -0
- package/ui/PreviewLines.qml +106 -0
- package/ui/PreviewMarkdown.qml +706 -0
- package/ui/PreviewMedia.qml +250 -0
- package/ui/PreviewPdf.qml +482 -0
- package/ui/PreviewScroll.qml +201 -0
- package/ui/PreviewSwap.qml +335 -0
- package/ui/PreviewText.qml +149 -0
- package/ui/ProtocolChip.qml +18 -0
- package/ui/QuickLookArchive.qml +41 -0
- package/ui/QuickLookBar.qml +103 -0
- package/ui/QuickLookPrepare.qml +355 -0
- package/ui/QuickLookSwap.qml +10 -0
- package/ui/QuickLookWarm.qml +65 -0
- package/ui/RailDrop.qml +155 -0
- package/ui/RailHeading.qml +19 -0
- package/ui/RailPlaces.qml +38 -0
- package/ui/RailTrashRow.qml +67 -0
- package/ui/RenameField.qml +353 -0
- package/ui/RendererRetry.qml +11 -0
- package/ui/ResizeHandle.qml +52 -0
- package/ui/Reveal.qml +54 -0
- package/ui/Row.qml +476 -0
- package/ui/RowDrag.qml +213 -0
- package/ui/RowDropTarget.qml +27 -0
- package/ui/RunCard.qml +286 -0
- package/ui/Scripts.qml +65 -0
- package/ui/SearchStrip.qml +232 -0
- package/ui/SelectionBand.qml +140 -0
- package/ui/SelectionPreview.qml +370 -0
- package/ui/SettingsFavourite.qml +122 -0
- package/ui/SettingsGroup.qml +96 -0
- package/ui/SettingsHint.qml +12 -0
- package/ui/SettingsMetrics.qml +29 -0
- package/ui/SettingsPane.qml +178 -0
- package/ui/SettingsPanel.qml +547 -0
- package/ui/SettingsRail.qml +128 -0
- package/ui/SettingsRow.qml +409 -0
- package/ui/SettingsRuler.qml +85 -0
- package/ui/SettingsSegment.qml +85 -0
- package/ui/ShareBrowser.qml +113 -0
- package/ui/ShareLink.qml +67 -0
- package/ui/ShelfPins.qml +101 -0
- package/ui/Sidebar.qml +728 -0
- package/ui/SidebarRow.qml +358 -0
- package/ui/Spinner.qml +60 -0
- package/ui/StableModel.qml +89 -0
- package/ui/StateMessage.qml +84 -0
- package/ui/StatusBar.qml +512 -0
- package/ui/StatusFileName.qml +27 -0
- package/ui/TabBar.qml +673 -0
- package/ui/TabDragGeometry.qml +60 -0
- package/ui/TagMenuMark.qml +52 -0
- package/ui/TagRailSection.qml +53 -0
- package/ui/TagSlot.qml +40 -0
- package/ui/TagState.qml +150 -0
- package/ui/TagSwatch.qml +28 -0
- package/ui/Taildrop.qml +86 -0
- package/ui/TailscaleMark.qml +50 -0
- package/ui/TerminalService.qml +69 -0
- package/ui/TerminalTab.qml +48 -0
- package/ui/TerminalTabs.qml +27 -0
- package/ui/Theme.qml +460 -0
- package/ui/ThemeColors.qml +43 -0
- package/ui/TransferCard.qml +239 -0
- package/ui/TrashConfirm.qml +129 -0
- package/ui/TrashDropHandler.qml +11 -0
- package/ui/TrashHost.qml +202 -0
- package/ui/TrashMonitor.qml +30 -0
- package/ui/TrashToolbar.qml +19 -0
- package/ui/TrashView.qml +492 -0
- package/ui/UnlockDialog.qml +450 -0
- package/ui/UnlockHost.qml +206 -0
- package/ui/UpdateCheck.qml +97 -0
- package/ui/UserDirs.qml +25 -0
- package/ui/ViewState.qml +565 -0
- package/ui/ViewportScrollBar.qml +195 -0
- package/ui/ViewportScrollBars.qml +25 -0
- package/ui/WebPreview.qml +33 -0
- package/ui/WebPreviewView.qml +26 -0
- package/ui/WindowBody.qml +829 -0
- package/ui/WindowDrag.qml +35 -0
- package/ui/boot/Commons/AudioNodes.qml +50 -0
- package/ui/boot/Commons/AudioNodesModel.js +96 -0
- package/ui/boot/Commons/Border.qml +243 -0
- package/ui/boot/Commons/BorderGeometry.js +373 -0
- package/ui/boot/Commons/Color.qml +258 -0
- package/ui/boot/Commons/I18n.qml +118 -0
- package/ui/boot/Commons/InputDevices.qml +112 -0
- package/ui/boot/Commons/InputMethodState.qml +38 -0
- package/ui/boot/Commons/IpcRegistry.qml +77 -0
- package/ui/boot/Commons/Numbers.js +19 -0
- package/ui/boot/Commons/Plural.js +91 -0
- package/ui/boot/Commons/ShellIpc.qml +12 -0
- package/ui/boot/Commons/Style.qml +561 -0
- package/ui/boot/Commons/Translations.qml +100 -0
- package/ui/boot/Commons/UntypedInput.qml +152 -0
- package/ui/boot/Commons/Util.qml +188 -0
- package/ui/boot/Commons/qmldir +13 -0
- package/ui/boot/LICENSE-omarchy +20 -0
- package/ui/boot/Ui/BackgroundMedia.qml +49 -0
- package/ui/boot/Ui/BarIconButton.qml +106 -0
- package/ui/boot/Ui/BarIconContent.qml +38 -0
- package/ui/boot/Ui/BarIndicator.qml +53 -0
- package/ui/boot/Ui/BarWidget.qml +50 -0
- package/ui/boot/Ui/BorderOverlay.qml +54 -0
- package/ui/boot/Ui/BorderSurface.qml +40 -0
- package/ui/boot/Ui/Button.qml +224 -0
- package/ui/boot/Ui/ButtonGroup.qml +131 -0
- package/ui/boot/Ui/ConfirmDialog.qml +134 -0
- package/ui/boot/Ui/CursorSurface.qml +42 -0
- package/ui/boot/Ui/Dropdown.qml +245 -0
- package/ui/boot/Ui/FilterInput.qml +26 -0
- package/ui/boot/Ui/IconContentBounds.qml +141 -0
- package/ui/boot/Ui/KeyboardPanel.qml +453 -0
- package/ui/boot/Ui/MultiSelect.qml +624 -0
- package/ui/boot/Ui/NumberField.qml +86 -0
- package/ui/boot/Ui/OpticalGlyph.qml +68 -0
- package/ui/boot/Ui/OverlayWindow.qml +102 -0
- package/ui/boot/Ui/Panel.qml +60 -0
- package/ui/boot/Ui/PanelActionButton.qml +105 -0
- package/ui/boot/Ui/PanelController.qml +16 -0
- package/ui/boot/Ui/PanelHero.qml +112 -0
- package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
- package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
- package/ui/boot/Ui/PanelSeparator.qml +19 -0
- package/ui/boot/Ui/PanelSlider.qml +156 -0
- package/ui/boot/Ui/PanelToolTip.qml +50 -0
- package/ui/boot/Ui/PluginBarApi.qml +89 -0
- package/ui/boot/Ui/PointerMoveGate.qml +54 -0
- package/ui/boot/Ui/PopupCard.qml +181 -0
- package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
- package/ui/boot/Ui/SearchableDropdown.qml +354 -0
- package/ui/boot/Ui/SizedImage.qml +125 -0
- package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
- package/ui/boot/Ui/TextField.qml +58 -0
- package/ui/boot/Ui/Toggle.qml +118 -0
- package/ui/boot/Ui/ToggleSwitch.qml +115 -0
- package/ui/boot/Ui/WidgetButton.qml +172 -0
- package/ui/boot/Ui/qmldir +41 -0
- package/ui/boot/fleatab.qml +50 -0
- package/ui/boot/picker.qml +39 -0
- package/ui/boot/shell.qml +131 -0
- package/ui/boot/tabtearoff.qml +51 -0
- package/ui/js/Anchor.js +379 -0
- package/ui/js/AnchorHold.js +162 -0
- package/ui/js/Archive.js +157 -0
- package/ui/js/ArchiveCard.js +44 -0
- package/ui/js/ArchiveOps.js +44 -0
- package/ui/js/BackReturn.js +118 -0
- package/ui/js/BulkRename.js +100 -0
- package/ui/js/Buttons.js +54 -0
- package/ui/js/ChromeKeys.js +116 -0
- package/ui/js/ClipMarks.js +73 -0
- package/ui/js/ClipSelection.js +67 -0
- package/ui/js/Clipboard.js +179 -0
- package/ui/js/Cloud.js +97 -0
- package/ui/js/CodeRuns.js +72 -0
- package/ui/js/Collide.js +212 -0
- package/ui/js/ColumnFit.js +28 -0
- package/ui/js/ColumnMenu.js +111 -0
- package/ui/js/Columns.js +298 -0
- package/ui/js/ColumnsCarry.js +103 -0
- package/ui/js/Compare.js +74 -0
- package/ui/js/Contrast.js +157 -0
- package/ui/js/ControlReader.js +42 -0
- package/ui/js/Convert.js +52 -0
- package/ui/js/CopyAs.js +52 -0
- package/ui/js/Crumbs.js +178 -0
- package/ui/js/Csv.js +231 -0
- package/ui/js/Density.js +44 -0
- package/ui/js/Devices.js +440 -0
- package/ui/js/DirSizes.js +180 -0
- package/ui/js/Drag.js +360 -0
- package/ui/js/DragOut.js +166 -0
- package/ui/js/DropDev.js +52 -0
- package/ui/js/Dropbox.js +41 -0
- package/ui/js/Eject.js +217 -0
- package/ui/js/Errors.js +188 -0
- package/ui/js/ExtThumbs.js +115 -0
- package/ui/js/Facts.js +402 -0
- package/ui/js/FigureDate.js +14 -0
- package/ui/js/Filter.js +285 -0
- package/ui/js/Find.js +46 -0
- package/ui/js/Flash.js +184 -0
- package/ui/js/FlashCard.js +79 -0
- package/ui/js/FlashEndings.js +125 -0
- package/ui/js/FlashPane.js +116 -0
- package/ui/js/FleaBin.js +12 -0
- package/ui/js/Focus.js +504 -0
- package/ui/js/FolderSorts.js +108 -0
- package/ui/js/FolderViews.js +44 -0
- package/ui/js/Format.js +314 -0
- package/ui/js/Fuzzy.js +141 -0
- package/ui/js/GlassTag.js +72 -0
- package/ui/js/Grid.js +33 -0
- package/ui/js/GridGeometry.js +90 -0
- package/ui/js/GridNames.js +153 -0
- package/ui/js/GvfsBridge.js +200 -0
- package/ui/js/HostClipboard.js +29 -0
- package/ui/js/Icons.js +218 -0
- package/ui/js/Input.js +50 -0
- package/ui/js/Jump.js +200 -0
- package/ui/js/KeyName.js +64 -0
- package/ui/js/Keymap.js +401 -0
- package/ui/js/Kinds.js +164 -0
- package/ui/js/LICENSES/ISC-lucide.txt +43 -0
- package/ui/js/LangMarkPaths.js +47 -0
- package/ui/js/LangMarks.js +120 -0
- package/ui/js/Lists.js +11 -0
- package/ui/js/LocalSend.js +39 -0
- package/ui/js/LockedMenu.js +63 -0
- package/ui/js/MakeDefault.js +186 -0
- package/ui/js/MarkBox.js +7 -0
- package/ui/js/Markdown.js +119 -0
- package/ui/js/MarkdownLists.js +86 -0
- package/ui/js/MarkdownMaths.js +58 -0
- package/ui/js/MarkdownPictures.js +32 -0
- package/ui/js/MarkdownPrepared.js +139 -0
- package/ui/js/MarkdownTableFit.js +34 -0
- package/ui/js/Marks.js +148 -0
- package/ui/js/Marquee.js +96 -0
- package/ui/js/Match.js +93 -0
- package/ui/js/Material.js +109 -0
- package/ui/js/MdBlocks.js +437 -0
- package/ui/js/MdBreak.js +71 -0
- package/ui/js/MdChunks.js +70 -0
- package/ui/js/MdContainer.js +137 -0
- package/ui/js/MdDocument.js +337 -0
- package/ui/js/MdEmph.js +97 -0
- package/ui/js/MdEntity.js +108 -0
- package/ui/js/MdEntityTable.js +223 -0
- package/ui/js/MdEscape.js +59 -0
- package/ui/js/MdFront.js +37 -0
- package/ui/js/MdHold.js +32 -0
- package/ui/js/MdHtml.js +307 -0
- package/ui/js/MdHtmlBlock.js +290 -0
- package/ui/js/MdHtmlHeading.js +53 -0
- package/ui/js/MdHtmlImage.js +179 -0
- package/ui/js/MdInline.js +154 -0
- package/ui/js/MdItems.js +212 -0
- package/ui/js/MdLeaf.js +309 -0
- package/ui/js/MdLink.js +196 -0
- package/ui/js/MdMath.js +67 -0
- package/ui/js/MdParagraphs.js +138 -0
- package/ui/js/MdRefs.js +232 -0
- package/ui/js/MdResolve.js +226 -0
- package/ui/js/MdRun.js +300 -0
- package/ui/js/MdUrl.js +226 -0
- package/ui/js/Menu.js +514 -0
- package/ui/js/MenuContext.js +85 -0
- package/ui/js/MenuFit.js +13 -0
- package/ui/js/MenuRefresh.js +74 -0
- package/ui/js/MenuWheel.js +35 -0
- package/ui/js/Messages.js +186 -0
- package/ui/js/Motion.js +16 -0
- package/ui/js/Mounts.js +320 -0
- package/ui/js/MouseNav.js +13 -0
- package/ui/js/Nav.js +329 -0
- package/ui/js/NetFs.js +26 -0
- package/ui/js/OpenWith.js +83 -0
- package/ui/js/Ops.js +585 -0
- package/ui/js/Palette.js +33 -0
- package/ui/js/PathBar.js +260 -0
- package/ui/js/Permissions.js +179 -0
- package/ui/js/Phones.js +112 -0
- package/ui/js/Picker.js +353 -0
- package/ui/js/PlaceMenu.js +96 -0
- package/ui/js/Places.js +265 -0
- package/ui/js/PreviewAsk.js +21 -0
- package/ui/js/PreviewKeys.js +155 -0
- package/ui/js/PreviewSettle.js +29 -0
- package/ui/js/PreviewSwap.js +101 -0
- package/ui/js/PropertyFacts.js +144 -0
- package/ui/js/Protocols.js +296 -0
- package/ui/js/QuickLookKinds.js +27 -0
- package/ui/js/QuickLookRect.js +24 -0
- package/ui/js/RailDrop.js +51 -0
- package/ui/js/RailKeys.js +87 -0
- package/ui/js/RailMenu.js +133 -0
- package/ui/js/Recent.js +135 -0
- package/ui/js/RecentMode.js +156 -0
- package/ui/js/Reload.js +60 -0
- package/ui/js/Renderer.js +9 -0
- package/ui/js/RunFile.js +143 -0
- package/ui/js/Scripts.js +28 -0
- package/ui/js/Scroll.js +304 -0
- package/ui/js/ScrollOff.js +69 -0
- package/ui/js/Search.js +478 -0
- package/ui/js/Selection.js +97 -0
- package/ui/js/Settings.js +476 -0
- package/ui/js/SettingsAbout.js +97 -0
- package/ui/js/SettingsShelf.js +52 -0
- package/ui/js/SheetKeys.js +42 -0
- package/ui/js/SheetQuery.js +281 -0
- package/ui/js/ShelfPile.js +27 -0
- package/ui/js/SlowClick.js +53 -0
- package/ui/js/SlowOp.js +6 -0
- package/ui/js/Sort.js +134 -0
- package/ui/js/Startup.js +63 -0
- package/ui/js/StateWords.js +17 -0
- package/ui/js/Status.js +238 -0
- package/ui/js/Swap.js +166 -0
- package/ui/js/TabMove.js +39 -0
- package/ui/js/Tabs.js +751 -0
- package/ui/js/Tags.js +134 -0
- package/ui/js/Taildrop.js +128 -0
- package/ui/js/Tap.js +180 -0
- package/ui/js/TextSize.js +107 -0
- package/ui/js/Thumbs.js +158 -0
- package/ui/js/Transfer.js +172 -0
- package/ui/js/Trash.js +84 -0
- package/ui/js/TrashDates.js +47 -0
- package/ui/js/TrashDrop.js +64 -0
- package/ui/js/UiState.js +438 -0
- package/ui/js/Unlock.js +152 -0
- package/ui/js/Update.js +130 -0
- package/ui/js/UserDirs.js +56 -0
- package/ui/qmldir +230 -0
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import Quickshell
|
|
3
|
+
import Quickshell.Io
|
|
4
|
+
import "." as Flea
|
|
5
|
+
import "js/LocalSend.js" as LocalSendJs
|
|
6
|
+
import "js/CopyAs.js" as CopyAs
|
|
7
|
+
import "js/Archive.js" as Archive
|
|
8
|
+
import "js/Menu.js" as Menu
|
|
9
|
+
import "js/Format.js" as Format
|
|
10
|
+
import "js/Ops.js" as Ops
|
|
11
|
+
import "js/Search.js" as Search
|
|
12
|
+
|
|
13
|
+
Loader {
|
|
14
|
+
id: root
|
|
15
|
+
required property var pane
|
|
16
|
+
|
|
17
|
+
// Directive 71: the only thing that knows about LocalSend, the way ui/Taildrop.qml is for the
|
|
18
|
+
// other one. The work is the backend's, which drives localsend-cli on a pty of its own.
|
|
19
|
+
readonly property alias localSend: localSend
|
|
20
|
+
|
|
21
|
+
Flea.LocalSend {
|
|
22
|
+
id: localSend
|
|
23
|
+
backend: root.pane.backend
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
Connections {
|
|
27
|
+
target: root.pane.backend
|
|
28
|
+
function onLocalSendPeers(peers, reason) {
|
|
29
|
+
localSend.answered(peers, reason)
|
|
30
|
+
root.pane.contextMenu().refreshProviderRows()
|
|
31
|
+
}
|
|
32
|
+
function onLocalSendSent(ok, reason) { root.pane.message(LocalSendJs.verdict(ok, reason), !ok) }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// A menu opened without a selection carries no paths, so a row action means the row under the
|
|
36
|
+
// cursor, joined against the listing's base: on a search the scope or the folder, never the pane's path.
|
|
37
|
+
function targets(paths) {
|
|
38
|
+
if (paths && paths.length) return paths
|
|
39
|
+
return root.pane.cursorRow ? [root.pane.join(Search.baseOf(root.pane), root.pane.cursorRow.n)] : []
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Actions rule 1: every shelf action is a `flea shelf` call, so the menu row makes the same one
|
|
43
|
+
// a drop onto the card makes and nothing here knows the pile's shape.
|
|
44
|
+
function shelve(paths) {
|
|
45
|
+
if (paths.length === 0) { root.pane.message("There is nothing to put on the shelf.", true); return }
|
|
46
|
+
if (shelver.running) {
|
|
47
|
+
// A second add while one runs waits its turn, so each exit reports its own count.
|
|
48
|
+
shelver.pendingAdds = shelver.pendingAdds.concat([paths])
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
shelver.startAdd(paths)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
Process {
|
|
55
|
+
id: shelver
|
|
56
|
+
property int count: 0
|
|
57
|
+
property var pendingAdds: []
|
|
58
|
+
stderr: StdioCollector { waitForEnd: true }
|
|
59
|
+
function startAdd(paths) {
|
|
60
|
+
shelver.count = paths.length
|
|
61
|
+
shelver.command = [Quickshell.env("FLEA_BIN") || "flea", "shelf", "add"].concat(paths)
|
|
62
|
+
shelver.running = true
|
|
63
|
+
}
|
|
64
|
+
onExited: function (code, status) {
|
|
65
|
+
if (code === 0) {
|
|
66
|
+
root.pane.message(shelver.count === 1 ? Ops.WORDS.shelfOne
|
|
67
|
+
: Format.fill(Ops.WORDS.shelfMany, shelver.count), false)
|
|
68
|
+
} else {
|
|
69
|
+
var said = shelver.stderr.text.trim().split("\n").pop().replace(/^flea: /, "")
|
|
70
|
+
root.pane.message(said.length > 0 ? said : "The shelf did not take that.", true)
|
|
71
|
+
}
|
|
72
|
+
if (shelver.pendingAdds.length > 0) {
|
|
73
|
+
var next = shelver.pendingAdds[0]
|
|
74
|
+
shelver.pendingAdds = shelver.pendingAdds.slice(1)
|
|
75
|
+
shelver.startAdd(next)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Copy as covers the whole selection, one path per line, as plain text; the leaves read the snapshot, whose paths a window cannot hold.
|
|
81
|
+
property var copyKinds: ({ copyPath: "path", copyName: "name", copyStem: "stem",
|
|
82
|
+
copydirpath: "dirpath", copyUri: "uri", copyQuoted: "quoted" })
|
|
83
|
+
function copyVariant(action, paths) {
|
|
84
|
+
var leaf = action.indexOf("copyAs:") === 0 ? action.substring("copyAs:".length) : action
|
|
85
|
+
var kind = copyKinds[leaf]
|
|
86
|
+
if (kind === undefined) return false
|
|
87
|
+
var taken = root.targets(paths)
|
|
88
|
+
if (taken.length === 0) return true
|
|
89
|
+
root.pane.opener.copyText(CopyAs.lines(taken, kind))
|
|
90
|
+
return true
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function perform(action, menuId, paths) {
|
|
94
|
+
if (action.indexOf("runScript:") === 0) { Flea.Scripts.run(action.substring("runScript:".length), paths || []); return }
|
|
95
|
+
if (action.indexOf("localsend:") === 0) { LocalSendJs.send(root.pane, localSend, root.pane.backend.providers.localsend, action.substring("localsend:".length), root.targets(paths)); return }
|
|
96
|
+
if (action.indexOf("taildrop:") === 0) { root.pane.sendTaildrop(action.substring("taildrop:".length), root.targets(paths).length === 1 ? root.targets(paths)[0] : ""); return }
|
|
97
|
+
if (action === "addToShelf") { root.shelve(root.targets(paths)); return }
|
|
98
|
+
if (action === "sharelink") { root.pane.copyShareLink(paths && paths.length === 1 ? paths[0] : ""); return }
|
|
99
|
+
// The Places and Locked menus still send the Copy path alias.
|
|
100
|
+
if (action === "copypath") { root.pane.opener.copyText(paths && paths.length ? paths[0] : root.pane.join(Search.baseOf(root.pane), root.pane.cursorRow.n)); return }
|
|
101
|
+
if (copyVariant(action, paths)) return
|
|
102
|
+
// Show original reveals the link target in its own folder.
|
|
103
|
+
if (action === "showOriginal") {
|
|
104
|
+
var taken = root.targets(paths)
|
|
105
|
+
if (taken.length > 0) root.pane.requestLinkTarget(taken[0])
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
// Paste as links through the collision card; the source is the file clipboard, never the menu snapshot.
|
|
109
|
+
if (action.indexOf("pasteAs:") === 0) {
|
|
110
|
+
var leaf = action.substring("pasteAs:".length)
|
|
111
|
+
var kind = leaf === "pasteAbsoluteLink" ? "absolute" : leaf === "pasteHardLink" ? "hard" : "relative"
|
|
112
|
+
root.pane.pasteLink(kind, null)
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
if (action === "invertSelection") { root.pane.invertSelection(); return }
|
|
116
|
+
if (action.indexOf("col:") === 0) { ViewState.toggleColumn(action.substring("col:".length)); return }
|
|
117
|
+
root.pane.act(action, menuId, paths)
|
|
118
|
+
}
|
|
119
|
+
// A script's own non-zero exit is its last stderr line, said once in the status centre.
|
|
120
|
+
Connections {
|
|
121
|
+
target: Flea.Scripts
|
|
122
|
+
function onSaid(text, isError) { root.pane.message(text, isError) }
|
|
123
|
+
}
|
|
124
|
+
anchors.fill: parent
|
|
125
|
+
z: 2
|
|
126
|
+
active: false
|
|
127
|
+
// OpenWith.html rule 4: Open with owns its own card, so the shared dialog is not asked to be one.
|
|
128
|
+
property string dialogFor: ""
|
|
129
|
+
source: root.dialogFor === "openWith" ? "OpenWithDialog.qml" : "MenuActionDialog.qml"
|
|
130
|
+
readonly property bool opened: item !== null && item.opened
|
|
131
|
+
readonly property bool deleting: item !== null && item.deletionActive
|
|
132
|
+
property int requestId: 0
|
|
133
|
+
property string identity: ""
|
|
134
|
+
property string folder: ""
|
|
135
|
+
property bool ready: false
|
|
136
|
+
property var selectedKinds: []
|
|
137
|
+
property string pendingAction: ""
|
|
138
|
+
property bool pendingActivation: false
|
|
139
|
+
// Tag toggles chosen while the first still awaits its snapshot, kept in press order; any other pending action drops them.
|
|
140
|
+
property var queuedTags: []
|
|
141
|
+
// A tag activate sent and not yet answered; the backend's menu slot holds one job, so the next queued tag waits for this reply.
|
|
142
|
+
property bool tagInFlight: false
|
|
143
|
+
property bool activationUsed: false
|
|
144
|
+
// The request a keymap sheet activation runs under, which lists hidden rows; the next snapshot moves requestId past it.
|
|
145
|
+
property int sheetRequest: 0
|
|
146
|
+
// Which row a keyboard rename was asked for, so its reply cannot open the editor over another.
|
|
147
|
+
property int pendingRenameIndex: -1
|
|
148
|
+
// The pointer rename's own reveal context beside it, so a slow click never scrolls; false keeps the keyboard's.
|
|
149
|
+
property bool pendingRenameStill: false
|
|
150
|
+
property int launchingId: 0
|
|
151
|
+
// OpenWith.html's flyout: the registry for the cursor row, asked for as the menu opens so the
|
|
152
|
+
// submenu is populated by the time the row is reached. The flyout writes nothing; the dialog
|
|
153
|
+
// stays the only place a default is written, which is Douglas de Moura's architecture kept whole.
|
|
154
|
+
property var openWithApps: []
|
|
155
|
+
property bool openWithLoaded: false
|
|
156
|
+
property var survivors: []
|
|
157
|
+
property int survivorId: 0
|
|
158
|
+
property string survivorFolder: ""
|
|
159
|
+
property string survivorListing: ""
|
|
160
|
+
property string backgroundFolder: ""
|
|
161
|
+
property bool providersRefreshing: false
|
|
162
|
+
property int providerFormatsId: 0
|
|
163
|
+
property bool providerQueriesStarted: false
|
|
164
|
+
property bool providerDestinationPending: false
|
|
165
|
+
property bool providerValidated: false
|
|
166
|
+
property var providerFacts: ({})
|
|
167
|
+
property bool taildropRefreshWaiting: false
|
|
168
|
+
property bool dropboxRefreshWaiting: false
|
|
169
|
+
property bool refreshingTaildrop: false
|
|
170
|
+
property bool refreshingDropbox: false
|
|
171
|
+
|
|
172
|
+
function providerAction(action) {
|
|
173
|
+
return action.indexOf("taildrop:") === 0 || action === "dropbox" || action === "sharelink"
|
|
174
|
+
}
|
|
175
|
+
function refreshProviders(action) {
|
|
176
|
+
providersRefreshing = true
|
|
177
|
+
refreshingTaildrop = !action || action.indexOf("taildrop:") === 0
|
|
178
|
+
refreshingDropbox = !action || action === "dropbox" || action === "sharelink"
|
|
179
|
+
providerQueriesStarted = false
|
|
180
|
+
providerDestinationPending = false
|
|
181
|
+
taildropRefreshWaiting = false
|
|
182
|
+
dropboxRefreshWaiting = false
|
|
183
|
+
providerFormatsId = pane.backend.askFormats()
|
|
184
|
+
pane.contextMenu().refreshProviderRows()
|
|
185
|
+
}
|
|
186
|
+
function finishProviders() {
|
|
187
|
+
if (!providersRefreshing || !providerQueriesStarted || providerDestinationPending || !ready
|
|
188
|
+
|| taildropRefreshWaiting || dropboxRefreshWaiting
|
|
189
|
+
|| (refreshingTaildrop && pane.taildropService.checking)
|
|
190
|
+
|| (refreshingDropbox && pane.dropboxService && pane.dropboxService.dropboxChecking)) return
|
|
191
|
+
if (!pendingActivation && pane.dropboxService && pane.dropboxService.dropboxReady) {
|
|
192
|
+
providerDestinationPending = true
|
|
193
|
+
pane.backend.send({c: "menuaction", op: "providerDestination", id: requestId, dest: pane.dropboxService.dropboxPath})
|
|
194
|
+
return
|
|
195
|
+
}
|
|
196
|
+
providersFinished()
|
|
197
|
+
}
|
|
198
|
+
function providersFinished() {
|
|
199
|
+
providersRefreshing = false
|
|
200
|
+
pane.contextMenu().providersSettled()
|
|
201
|
+
if (pendingActivation && providerAction(pendingAction)) {
|
|
202
|
+
providerValidated = true
|
|
203
|
+
validateActivation()
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// rows, when the caller has one: a keyboard rename acts on the cursor, and Ops.targetIndices
|
|
208
|
+
// answers with the selection whenever there is one, so the snapshot covered rows the rename was
|
|
209
|
+
// never going to touch and the backend refused the cursor's own path as "not in the selection".
|
|
210
|
+
function snapshot(rows) {
|
|
211
|
+
if (deleting || survivorId) return
|
|
212
|
+
requestId++
|
|
213
|
+
ready = false
|
|
214
|
+
selectedKinds = []
|
|
215
|
+
pendingAction = ""
|
|
216
|
+
pendingActivation = false
|
|
217
|
+
queuedTags = []
|
|
218
|
+
tagInFlight = false
|
|
219
|
+
activationUsed = false
|
|
220
|
+
identity = pane.menuSelectionIdentity()
|
|
221
|
+
folder = pane.path
|
|
222
|
+
// The registry belongs to the row that was snapshotted. Carrying the last row's answer over
|
|
223
|
+
// offered one file's applications for another, and kept the self-hide rule from ever firing.
|
|
224
|
+
openWithApps = []
|
|
225
|
+
openWithLoaded = false
|
|
226
|
+
pane.backend.send({c: "menuaction", op: "snapshot", id: requestId,
|
|
227
|
+
rows: rows !== undefined ? rows : Ops.targetIndices(pane), cursor: pane.cursorIndex})
|
|
228
|
+
}
|
|
229
|
+
// A ready snapshot over the same selection opens the editor at once, one still in flight takes the F2 route, and a moved selection refuses as activate does.
|
|
230
|
+
function openRenameFromMenu() {
|
|
231
|
+
if (pane.renamePending) { pane.message("Rename is still finishing.", false); return }
|
|
232
|
+
if (deleting || survivorId) { pane.message("The deletion is still finishing.", false); return }
|
|
233
|
+
var route = Ops.menuRenameRoute(ready, identity, pane.menuSelectionIdentity())
|
|
234
|
+
if (route === "stale") { pane.message("Selected items changed; reopen the menu.", true); return }
|
|
235
|
+
if (route === "now" && pane.contextMenu().validateChoice("rename", "")) {
|
|
236
|
+
show("rename")
|
|
237
|
+
return
|
|
238
|
+
}
|
|
239
|
+
open("rename")
|
|
240
|
+
}
|
|
241
|
+
function open(action, menuId, context) {
|
|
242
|
+
if (opened) return
|
|
243
|
+
if (action === "rename" && pane.renamePending) { pane.message("Rename is still finishing.", false); return }
|
|
244
|
+
if (deleting || survivorId) { pane.message("The deletion is still finishing.", false); return }
|
|
245
|
+
if (action === "newFile") {
|
|
246
|
+
requestId++
|
|
247
|
+
folder = pane.path
|
|
248
|
+
show(action)
|
|
249
|
+
return
|
|
250
|
+
}
|
|
251
|
+
// The row the editor will open over, captured now: the cursor can move between this request
|
|
252
|
+
// and its reply, and the editor used to open over wherever it had got to by then.
|
|
253
|
+
if (action === "rename" && !menuId) {
|
|
254
|
+
pendingRenameIndex = pane.cursorIndex
|
|
255
|
+
pendingRenameStill = context === 0
|
|
256
|
+
}
|
|
257
|
+
if (!requestId || identity !== pane.menuSelectionIdentity() || (action === "rename" && !menuId))
|
|
258
|
+
snapshot(action === "rename" && !menuId ? [pane.cursorIndex] : undefined)
|
|
259
|
+
pendingAction = action
|
|
260
|
+
pendingActivation = false
|
|
261
|
+
if (ready) show(action)
|
|
262
|
+
}
|
|
263
|
+
function activate(action, selected) {
|
|
264
|
+
// Flash to drive re-reads what the menu showed: the snapshot already proved the selection names it.
|
|
265
|
+
if (action === "flashDrive") {
|
|
266
|
+
var flashIdx = Ops.targetIndices(pane)
|
|
267
|
+
var flashRow = flashIdx.length === 1 ? pane.rowFor(flashIdx[0]) : null
|
|
268
|
+
if (!requestId || identity !== pane.menuSelectionIdentity() || !flashRow
|
|
269
|
+
|| !Archive.isDiskImage(flashRow.n, pane.flashZipMember)) {
|
|
270
|
+
pane.message("Selected items changed; reopen the menu.", true)
|
|
271
|
+
return
|
|
272
|
+
}
|
|
273
|
+
activationUsed = true
|
|
274
|
+
pane.openFlashImage(pane.join(Search.baseOf(pane), flashRow.n))
|
|
275
|
+
return
|
|
276
|
+
}
|
|
277
|
+
if (!selected) {
|
|
278
|
+
if (action === "addFavourite") {
|
|
279
|
+
if (backgroundFolder !== pane.path) { pane.message("Folder changed; reopen the menu.", true); return }
|
|
280
|
+
addFavourite(backgroundFolder)
|
|
281
|
+
} else pane.performMenu(action, 0, null)
|
|
282
|
+
return
|
|
283
|
+
}
|
|
284
|
+
if (activationUsed) return
|
|
285
|
+
if (deleting || survivorId) { pane.message("The deletion is still finishing.", false); return }
|
|
286
|
+
if (!requestId || identity !== pane.menuSelectionIdentity()) {
|
|
287
|
+
pane.message("Selected items changed; reopen the menu.", true)
|
|
288
|
+
return
|
|
289
|
+
}
|
|
290
|
+
// A tag toggle repeats inside one open menu; every other choice closes it, so one activation is all it gets.
|
|
291
|
+
if (action.indexOf("tags:") === 0 && (tagInFlight || (pendingActivation && pendingAction.indexOf("tags:") === 0))) {
|
|
292
|
+
queuedTags = queuedTags.concat([action])
|
|
293
|
+
return
|
|
294
|
+
}
|
|
295
|
+
queuedTags = []
|
|
296
|
+
activationUsed = action.indexOf("tags:") !== 0
|
|
297
|
+
providerValidated = false
|
|
298
|
+
pendingAction = action
|
|
299
|
+
pendingActivation = true
|
|
300
|
+
if (ready) validateActivation()
|
|
301
|
+
}
|
|
302
|
+
function validateActivation() {
|
|
303
|
+
if (providerAction(pendingAction) && !providerValidated) { refreshProviders(pendingAction); return }
|
|
304
|
+
var action = pendingAction
|
|
305
|
+
pendingAction = ""
|
|
306
|
+
pendingActivation = false
|
|
307
|
+
var split = action.indexOf(":")
|
|
308
|
+
if (providerAction(action) && !pane.contextMenu().validateChoice(split < 0 ? action : action.substring(0, split),
|
|
309
|
+
split < 0 ? "" : action.substring(split + 1), sheetRequest === requestId)) return
|
|
310
|
+
// OpenWith.html rule 2: the flyout is a one-off override that writes nothing, so a chosen
|
|
311
|
+
// application launches through the same registry op the dialog submits, and the tail row is
|
|
312
|
+
// the only way into the dialog, which stays the one place a default is written.
|
|
313
|
+
if (action.indexOf("openWith:") === 0) {
|
|
314
|
+
var chosen = action.substring("openWith:".length)
|
|
315
|
+
if (chosen === Menu.OPEN_WITH_OTHER) { root.show("openWith"); return }
|
|
316
|
+
root.launchingId = requestId
|
|
317
|
+
pane.backend.send({c: "menuaction", op: "openWith", id: requestId, application: chosen})
|
|
318
|
+
return
|
|
319
|
+
}
|
|
320
|
+
pane.backend.send({c: "menuaction", op: "activate", id: requestId, action: action,
|
|
321
|
+
dest: pane.dropboxService ? pane.dropboxService.dropboxPath : ""})
|
|
322
|
+
tagInFlight = action.indexOf("tags:") === 0
|
|
323
|
+
}
|
|
324
|
+
// The answer to a tag activate frees the menu slot, so the next queued tag goes out now.
|
|
325
|
+
function sendNextTag() {
|
|
326
|
+
tagInFlight = false
|
|
327
|
+
if (queuedTags.length === 0) return
|
|
328
|
+
pendingAction = queuedTags[0]
|
|
329
|
+
queuedTags = queuedTags.slice(1)
|
|
330
|
+
pendingActivation = true
|
|
331
|
+
validateActivation()
|
|
332
|
+
}
|
|
333
|
+
function show(action) {
|
|
334
|
+
pendingAction = ""
|
|
335
|
+
if (action === "rename") {
|
|
336
|
+
Ops.startRename(pane, requestId, pendingRenameIndex, pendingRenameStill ? 0 : undefined)
|
|
337
|
+
pendingRenameIndex = -1
|
|
338
|
+
pendingRenameStill = false
|
|
339
|
+
return
|
|
340
|
+
}
|
|
341
|
+
dialogFor = action
|
|
342
|
+
active = true
|
|
343
|
+
item.open(action, requestId, folder, pane.listArea)
|
|
344
|
+
}
|
|
345
|
+
function addFavourite(path) {
|
|
346
|
+
Favourites.add(path, path.split("/").filter(function (part) { return part.length > 0 }).pop() || "/")
|
|
347
|
+
}
|
|
348
|
+
function locateSurvivors() {
|
|
349
|
+
if (!survivorId || pane.listInFlight) return
|
|
350
|
+
if (pane.path !== survivorFolder) { survivorId = 0; survivors = []; return }
|
|
351
|
+
survivorListing = pane.menuSelectionIdentity()
|
|
352
|
+
pane.backend.send({c: "locate", paths: survivors, id: survivorId, menuId: survivorId})
|
|
353
|
+
}
|
|
354
|
+
Connections {
|
|
355
|
+
target: root.pane.contextMenu()
|
|
356
|
+
function onOpenedChanged() {
|
|
357
|
+
var menu = root.pane.contextMenu()
|
|
358
|
+
if (menu.opened && !menu.hasRow && !menu.forRail && !menu.forHeader)
|
|
359
|
+
root.backgroundFolder = root.pane.path
|
|
360
|
+
if (menu.opened && menu.hasRow && !menu.forRail && !menu.forHeader) root.refreshProviders()
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
Connections {
|
|
364
|
+
target: root.pane.taildropService
|
|
365
|
+
function onRefreshed() {
|
|
366
|
+
if (root.providersRefreshing && root.taildropRefreshWaiting) root.taildropRefreshWaiting = !root.pane.taildropService.refresh(root.providerFacts)
|
|
367
|
+
root.finishProviders()
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
Connections {
|
|
371
|
+
target: root.pane.dropboxService
|
|
372
|
+
function onDropboxRefreshed() {
|
|
373
|
+
if (root.providersRefreshing && root.dropboxRefreshWaiting) root.dropboxRefreshWaiting = !root.pane.dropboxService.refreshDropbox(root.providerFacts)
|
|
374
|
+
root.finishProviders()
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
Connections {
|
|
378
|
+
target: root.pane
|
|
379
|
+
function onListInFlightChanged() { if (!root.pane.listInFlight) root.locateSurvivors() }
|
|
380
|
+
}
|
|
381
|
+
Connections {
|
|
382
|
+
target: root.pane.backend
|
|
383
|
+
function onFormatsResult(message) {
|
|
384
|
+
if (!root.providersRefreshing || message.id !== root.providerFormatsId) return
|
|
385
|
+
root.providerFacts = message.providers || {}
|
|
386
|
+
root.taildropRefreshWaiting = root.refreshingTaildrop && !root.pane.taildropService.refresh(root.providerFacts)
|
|
387
|
+
root.dropboxRefreshWaiting = root.refreshingDropbox && root.pane.dropboxService
|
|
388
|
+
? !root.pane.dropboxService.refreshDropbox(root.providerFacts) : false
|
|
389
|
+
root.providerQueriesStarted = true
|
|
390
|
+
root.localSend.refresh((root.providerFacts.localsend || {}).installed === true)
|
|
391
|
+
root.finishProviders()
|
|
392
|
+
}
|
|
393
|
+
function onChanged(path) { if (path === root.folder && root.item) root.item.sourceChanged() }
|
|
394
|
+
function onLocated(message) {
|
|
395
|
+
if (!root.survivorId || message.id !== root.survivorId) return
|
|
396
|
+
root.survivorId = 0
|
|
397
|
+
root.survivors = []
|
|
398
|
+
if (message.directory !== root.pane.path || root.pane.path !== root.survivorFolder
|
|
399
|
+
|| root.survivorListing !== root.pane.menuSelectionIdentity()) return
|
|
400
|
+
if (!message.ok) { root.pane.message(message.error, true); return }
|
|
401
|
+
var matches = message.matches || []
|
|
402
|
+
root.pane.selection.clear()
|
|
403
|
+
for (var i = 0; i < matches.length; i++) root.pane.selection.toggle(matches[i].index)
|
|
404
|
+
root.pane.selectionVersion++
|
|
405
|
+
if (matches.length) root.pane.setCursor(matches[0].index)
|
|
406
|
+
}
|
|
407
|
+
function onMenuResult(message) {
|
|
408
|
+
if (message.op === "openWith" && message.id === root.launchingId) {
|
|
409
|
+
root.launchingId = 0
|
|
410
|
+
if (!root.opened || message.id !== root.requestId) {
|
|
411
|
+
if (!message.ok && !message.cancelled) root.pane.message(message.error || "The application could not be opened.", true)
|
|
412
|
+
return
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (message.id !== root.requestId) return
|
|
416
|
+
if (message.op === "applications") {
|
|
417
|
+
// Both readers want it: the flyout's registry, and an open dialog that asked for it.
|
|
418
|
+
if (root.item) root.item.receive(message)
|
|
419
|
+
root.openWithApps = message.applications || []
|
|
420
|
+
root.openWithLoaded = true
|
|
421
|
+
root.pane.contextMenu().refreshProviderRows()
|
|
422
|
+
return
|
|
423
|
+
}
|
|
424
|
+
if (message.op === "providerDestination") {
|
|
425
|
+
root.providerDestinationPending = false
|
|
426
|
+
if (!message.ok && root.pane.dropboxService) {
|
|
427
|
+
root.pane.dropboxService.dropboxReason = message.error
|
|
428
|
+
root.pane.dropboxService.dropboxCode = ""
|
|
429
|
+
}
|
|
430
|
+
root.providersFinished()
|
|
431
|
+
return
|
|
432
|
+
}
|
|
433
|
+
if (message.op === "snapshot") {
|
|
434
|
+
root.selectedKinds = message.kinds || []
|
|
435
|
+
root.ready = message.ok === true && root.identity === root.pane.menuSelectionIdentity()
|
|
436
|
+
if (!root.ready) {
|
|
437
|
+
// A late snapshot answers no dismissed menu with nothing awaiting it; an open one keeps its refusal.
|
|
438
|
+
var retired = message.ok === true && !root.pane.contextMenu().opened && !root.opened
|
|
439
|
+
&& !root.pendingAction && !root.pendingActivation
|
|
440
|
+
root.pendingAction = ""
|
|
441
|
+
root.pendingActivation = false
|
|
442
|
+
root.queuedTags = []
|
|
443
|
+
root.tagInFlight = false
|
|
444
|
+
root.providersRefreshing = false
|
|
445
|
+
root.identity = ""
|
|
446
|
+
if (!retired)
|
|
447
|
+
root.pane.message(message.error || "Selected items changed; reopen the menu.", true)
|
|
448
|
+
} else if (root.pendingAction) {
|
|
449
|
+
if (root.pendingActivation) root.validateActivation()
|
|
450
|
+
else root.show(root.pendingAction)
|
|
451
|
+
}
|
|
452
|
+
// Multi-selection has no registry: the backend refuses it, so discovery stays single-item.
|
|
453
|
+
if (root.ready && message.count === 1 && root.pane.contextMenu().opened && root.pane.contextMenu().hasRow)
|
|
454
|
+
// No installed flag: the flyout draws the registry alone, and asking for the
|
|
455
|
+
// whole catalogue here walked every applications directory on every right-click.
|
|
456
|
+
root.pane.backend.send({c: "menuaction", op: "applications", id: root.requestId})
|
|
457
|
+
root.pane.contextMenu().refreshProviderRows()
|
|
458
|
+
root.finishProviders()
|
|
459
|
+
return
|
|
460
|
+
}
|
|
461
|
+
if (message.op === "activate") {
|
|
462
|
+
if (!message.ok || root.identity !== root.pane.menuSelectionIdentity()) {
|
|
463
|
+
root.queuedTags = []
|
|
464
|
+
root.tagInFlight = false
|
|
465
|
+
root.pane.message(message.error || "Selected items changed; reopen the menu.", true)
|
|
466
|
+
return
|
|
467
|
+
}
|
|
468
|
+
var split = message.action.indexOf(":")
|
|
469
|
+
var action = split < 0 ? message.action : message.action.substring(0, split)
|
|
470
|
+
var subId = split < 0 ? "" : message.action.substring(split + 1)
|
|
471
|
+
if (root.pane.contextMenu().validateChoice(action, subId, root.sheetRequest === message.id)) {
|
|
472
|
+
if (action === "addFavourite") {
|
|
473
|
+
if (!message.paths || message.paths.length !== 1) { root.pane.message("The selected folder could not be read.", true); return }
|
|
474
|
+
root.addFavourite(message.paths[0])
|
|
475
|
+
} else root.pane.performMenu(message.action, message.id, message.paths)
|
|
476
|
+
}
|
|
477
|
+
if (action === "tags") root.sendNextTag()
|
|
478
|
+
return
|
|
479
|
+
}
|
|
480
|
+
if (root.item) root.item.receive(message)
|
|
481
|
+
}
|
|
482
|
+
function onFailed(where, input, message, mode) {
|
|
483
|
+
if (where !== "backend") return
|
|
484
|
+
root.survivorId = 0
|
|
485
|
+
root.survivors = []
|
|
486
|
+
root.ready = false
|
|
487
|
+
root.identity = ""
|
|
488
|
+
root.pendingAction = ""
|
|
489
|
+
root.pendingActivation = false
|
|
490
|
+
root.queuedTags = []
|
|
491
|
+
root.tagInFlight = false
|
|
492
|
+
root.providersRefreshing = false
|
|
493
|
+
if (root.opened || root.deleting) root.item.receive({id: root.requestId, op: root.deleting ? "delete" : "", ok: false, error: message})
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
Connections {
|
|
497
|
+
target: root.item
|
|
498
|
+
// Two dialogs load here and only one of them creates files or deletes them, so the handlers
|
|
499
|
+
// the other never raises are absent by design rather than misspelled.
|
|
500
|
+
ignoreUnknownSignals: true
|
|
501
|
+
function onRequested(message) {
|
|
502
|
+
if (message.op === "openWith") root.launchingId = message.id
|
|
503
|
+
root.pane.backend.send(message)
|
|
504
|
+
}
|
|
505
|
+
function onApproved(message) {
|
|
506
|
+
root.pane.asks().ask({c: "transfer", op: message.action === "moveTo" ? "move" : "copy",
|
|
507
|
+
menuId: message.id, dest: message.dest})
|
|
508
|
+
}
|
|
509
|
+
function onCreated(path) { root.pane.refresh(path); root.pane.message(Ops.createdLine(path), false) }
|
|
510
|
+
function onDeleted(message) {
|
|
511
|
+
var text = Ops.deletedLine(message)
|
|
512
|
+
root.pane.operationResult(text, message.error || "", message.failed > 0)
|
|
513
|
+
if (root.pane.path !== root.folder) return
|
|
514
|
+
root.survivors = message.remaining || []
|
|
515
|
+
root.survivorId = root.survivors.length ? message.id : 0
|
|
516
|
+
root.survivorFolder = root.folder
|
|
517
|
+
root.pane.refresh()
|
|
518
|
+
}
|
|
519
|
+
function onClosed() {
|
|
520
|
+
root.ready = false
|
|
521
|
+
root.identity = ""
|
|
522
|
+
// The close op kills the launcher this id was waiting on, so its error is the cancellation
|
|
523
|
+
// the user asked for and not something to raise at them.
|
|
524
|
+
root.launchingId = 0
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
package/ui/PanePath.qml
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import "." as Flea
|
|
3
|
+
import "js/Crumbs.js" as Crumbs
|
|
4
|
+
|
|
5
|
+
// A dual pane's own path, drawn with the chrome's crumbs so issue 45's one tap on a parent reaches either pane.
|
|
6
|
+
Rectangle {
|
|
7
|
+
id: root
|
|
8
|
+
|
|
9
|
+
property string path: ""
|
|
10
|
+
property string home: ""
|
|
11
|
+
property var pathAlias: null
|
|
12
|
+
property bool focused: false
|
|
13
|
+
// ui/ChromeBar.qml's inputLive: false while Quick Look covers the strip, so a press on it stays Quick Look's.
|
|
14
|
+
property bool inputLive: true
|
|
15
|
+
// Drops callout 4: the pane whose collide sends a drop on a crumb.
|
|
16
|
+
property var pane: null
|
|
17
|
+
readonly property alias crumbItems: crumbs
|
|
18
|
+
readonly property alias crumbSlot: slot
|
|
19
|
+
|
|
20
|
+
signal chosen(string path)
|
|
21
|
+
signal editRequested()
|
|
22
|
+
|
|
23
|
+
color: root.focused ? Glass.surface : Glass.background
|
|
24
|
+
|
|
25
|
+
// Where no crumb is, the strip keeps the one gesture it had before issue 45: a double click types the path.
|
|
26
|
+
component TypeArea: Item {
|
|
27
|
+
HoverHandler {
|
|
28
|
+
enabled: root.inputLive
|
|
29
|
+
cursorShape: Qt.IBeamCursor
|
|
30
|
+
}
|
|
31
|
+
TapHandler {
|
|
32
|
+
enabled: root.inputLive
|
|
33
|
+
acceptedButtons: Qt.LeftButton
|
|
34
|
+
onDoubleTapped: root.editRequested()
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// One glyph's advance is every glyph's advance in this face, the same fit ui/ChromeBar.qml makes.
|
|
39
|
+
TextMetrics {
|
|
40
|
+
id: metrics
|
|
41
|
+
font.family: Theme.font.family
|
|
42
|
+
font.pixelSize: Theme.font.caption
|
|
43
|
+
text: "0"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
Item {
|
|
47
|
+
id: slot
|
|
48
|
+
anchors.fill: parent
|
|
49
|
+
clip: true
|
|
50
|
+
|
|
51
|
+
Row {
|
|
52
|
+
id: row
|
|
53
|
+
x: Theme.spacing.rowPaddingX
|
|
54
|
+
height: slot.height
|
|
55
|
+
|
|
56
|
+
Repeater {
|
|
57
|
+
id: crumbs
|
|
58
|
+
// Empty while the strip is hidden, because the single view keeps it at height 0 and would rebuild its crumbs on every move.
|
|
59
|
+
model: root.visible
|
|
60
|
+
? Crumbs.fitCrumbs(Crumbs.crumbs(root.path, root.home, root.pathAlias),
|
|
61
|
+
Math.floor((slot.width - 2 * Theme.spacing.rowPaddingX) / metrics.advanceWidth))
|
|
62
|
+
: []
|
|
63
|
+
|
|
64
|
+
delegate: Flea.Crumb {
|
|
65
|
+
height: slot.height
|
|
66
|
+
restColor: Theme.color.foreground
|
|
67
|
+
inputLive: root.inputLive
|
|
68
|
+
dropPane: root.pane
|
|
69
|
+
onChosen: function (path) { root.chosen(path) }
|
|
70
|
+
onEditRequested: root.editRequested()
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
TypeArea {
|
|
76
|
+
anchors { left: parent.left; top: parent.top; bottom: parent.bottom }
|
|
77
|
+
width: Theme.spacing.rowPaddingX
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
TypeArea {
|
|
81
|
+
anchors { left: row.right; right: parent.right; top: parent.top; bottom: parent.bottom }
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
Rectangle {
|
|
86
|
+
anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
|
|
87
|
+
height: Theme.spacing.hairline
|
|
88
|
+
color: Theme.color.mutedFrame
|
|
89
|
+
}
|
|
90
|
+
}
|