flea-qml 0.0.0-stage → 0.1.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 +478 -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 +402 -0
- package/src/archiveops.js +697 -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 +129 -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/transfer.js +669 -0
- package/src/trash-record.js +41 -0
- package/src/trash.js +210 -0
- package/src/trashbrowse.js +326 -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 +241 -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-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-html-security.mjs +23 -0
- package/test/manual-html-ui.mjs +30 -0
- package/test/manual-syntax-preview.mjs +26 -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 +68 -0
- package/ui/ArchiveCompressDialog.qml +378 -0
- package/ui/ArchivePasswordDialog.qml +257 -0
- package/ui/Backend.qml +771 -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 +523 -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 +115 -0
- package/ui/Pane.qml +1296 -0
- package/ui/PaneMenuActions.qml +527 -0
- package/ui/PanePath.qml +90 -0
- package/ui/PaneRail.qml +239 -0
- package/ui/PaneStates.qml +88 -0
- package/ui/PaneSwap.qml +339 -0
- package/ui/PaneWire.qml +605 -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 +1004 -0
- package/ui/PreviewAnimation.qml +24 -0
- package/ui/PreviewArchive.qml +66 -0
- package/ui/PreviewColumn.qml +551 -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 +38 -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 +732 -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/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 +827 -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 +122 -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 +364 -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 +502 -0
- package/ui/js/FolderSorts.js +108 -0
- package/ui/js/FolderViews.js +44 -0
- package/ui/js/Format.js +305 -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 +736 -0
- package/ui/js/Tags.js +134 -0
- package/ui/js/Taildrop.js +128 -0
- package/ui/js/Tap.js +174 -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 +81 -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 +228 -0
package/ui/PaneWire.qml
ADDED
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import "." as Flea
|
|
3
|
+
import "js/DirSizes.js" as DirSizes
|
|
4
|
+
import "js/DragOut.js" as DragOut
|
|
5
|
+
import "js/Errors.js" as Errors
|
|
6
|
+
import "js/Anchor.js" as Anchor
|
|
7
|
+
import "js/Archive.js" as Archive
|
|
8
|
+
import "js/BackReturn.js" as BackReturn
|
|
9
|
+
import "js/Nav.js" as Nav
|
|
10
|
+
import "js/Format.js" as Format
|
|
11
|
+
import "js/Ops.js" as Ops
|
|
12
|
+
import "js/Clipboard.js" as Clipboard
|
|
13
|
+
import "js/Permissions.js" as Permissions
|
|
14
|
+
import "js/Status.js" as Status
|
|
15
|
+
import "js/Search.js" as Search
|
|
16
|
+
import "js/SlowOp.js" as SlowOp
|
|
17
|
+
import "js/Swap.js" as Swap
|
|
18
|
+
import "js/Tabs.js" as Tabs
|
|
19
|
+
import "js/ExtThumbs.js" as ExtThumbs
|
|
20
|
+
import "js/Transfer.js" as Transfer
|
|
21
|
+
|
|
22
|
+
// Every reply from outside the window lands here: the backend's, and those of the three foreign
|
|
23
|
+
// programs the pane runs (the opener, the Dropbox share link, Taildrop). Split out of ui/Pane.qml
|
|
24
|
+
// the way ui/List.qml was; it owns no state of its own and writes only through the pane handed in.
|
|
25
|
+
Item {
|
|
26
|
+
id: root
|
|
27
|
+
|
|
28
|
+
property var pane: null
|
|
29
|
+
|
|
30
|
+
// The listing's floor as a drop target, under the rows: a drop past the last row, or one a file
|
|
31
|
+
// row refused, lands in the directory being shown. Declared first in ui/Pane.qml, so it sits below.
|
|
32
|
+
// Columns owns its narrower active floor; a search listing's base is the walk scope.
|
|
33
|
+
// Recent stands on the root, so its floor takes no drop: a row's own folder still does.
|
|
34
|
+
Flea.DropInto {
|
|
35
|
+
x: root.pane ? root.pane.listSlot.x : 0
|
|
36
|
+
y: root.pane ? root.pane.listSlot.y : 0
|
|
37
|
+
width: root.pane ? root.pane.listSlot.width : 0
|
|
38
|
+
height: root.pane ? root.pane.listSlot.height : 0
|
|
39
|
+
enabled: root.pane !== null && !root.pane.trash.opened && !root.pane.flashActive && root.pane.searchMode === ""
|
|
40
|
+
&& root.pane.recentMode === ""
|
|
41
|
+
&& (root.pane.viewMode === "list" || root.pane.viewMode === "grid")
|
|
42
|
+
pane: root.pane
|
|
43
|
+
scrolls: true
|
|
44
|
+
dest: root.pane ? root.pane.dropPath : ""
|
|
45
|
+
refuseLoading: DragOut.refuseLoading(root.pane && root.pane.listInFlight, false, false)
|
|
46
|
+
// Unknown until the listed reply lands, because dirDev is still the directory being left.
|
|
47
|
+
destDev: root.pane && root.pane.backend && !root.pane.listInFlight ? root.pane.backend.dirDev : 0
|
|
48
|
+
}
|
|
49
|
+
// The new folder has no row until the refresh lands, so the editor is opened on the rows reply
|
|
50
|
+
// that carries it rather than on the made line that asked for it. Holds that folder's full path.
|
|
51
|
+
property string renameOnArrival: ""
|
|
52
|
+
// A watched change landed while one of the states below owned the rows, so the re-read is owed.
|
|
53
|
+
property bool stale: false
|
|
54
|
+
// What the cursor sat on across a re-read, or null; ui/js/Anchor.js owns both ends of it.
|
|
55
|
+
property var anchor: null
|
|
56
|
+
property int retryId: 0
|
|
57
|
+
property var retryPaths: []
|
|
58
|
+
property string retryFolder: ""
|
|
59
|
+
property string retryListing: ""
|
|
60
|
+
property string retrySelectionText: ""
|
|
61
|
+
// The selection identity the retry line was written for: the line goes when the identity moves off it.
|
|
62
|
+
property string retrySelectionIdentity: ""
|
|
63
|
+
// One burst of writes is one re-read: the timer absorbs later notifications instead of being
|
|
64
|
+
// restarted by them, so a directory under continuous change settles rather than never firing.
|
|
65
|
+
readonly property int watchMs: 400
|
|
66
|
+
// Interactions and unfinished anchors hold the re-read; bare selections carry across by file identity.
|
|
67
|
+
readonly property bool watchBusy: Anchor.busy(pane, root.anchor)
|
|
68
|
+
// ui/Pane.qml reaches the three through these: openCursor takes the opener, the menu reads the
|
|
69
|
+
// Taildrop peers, and the two share actions call the other two.
|
|
70
|
+
readonly property alias opener: opener
|
|
71
|
+
readonly property alias shareLink: shareLink
|
|
72
|
+
readonly property alias taildrop: taildrop
|
|
73
|
+
readonly property alias swap: swap
|
|
74
|
+
|
|
75
|
+
// The listed and rows replies land through the listing swap, see ui/PaneSwap.qml.
|
|
76
|
+
Flea.PaneSwap { id: swap; pane: root.pane; wire: root }
|
|
77
|
+
|
|
78
|
+
Flea.Opener {
|
|
79
|
+
id: opener
|
|
80
|
+
// A dropped request is the app being busy, not a failure, so it takes the plain role.
|
|
81
|
+
onBusy: function (path) { pane.message("Still opening the last file; try again in a moment.", false) }
|
|
82
|
+
// canonicalize proved the path before every failure src/open.rs and src/terminal.rs report under their one status, so neither sentence below names a cause.
|
|
83
|
+
onFailed: function (path) { pane.message("No application on this system opened that file.", true) }
|
|
84
|
+
onIsDirectory: function (path) { pane.open(path) }
|
|
85
|
+
onTerminalBusy: function (path) { pane.message("Still opening the last terminal; try again in a moment.", false) }
|
|
86
|
+
onTerminalFailed: function (path) { pane.message("No terminal on this system opened that folder.", true) }
|
|
87
|
+
// The run card's own answers: a program asks once on its raw ask line, and a file no application claims asks Open with.
|
|
88
|
+
onAskRunRaw: function (path, text) { pane.askRunCard({ path: path, raw: text }) }
|
|
89
|
+
onAskOpenWith: function (path) { pane.showOpenWith(path) }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
Flea.ShareLink {
|
|
93
|
+
id: shareLink
|
|
94
|
+
onCopied: pane.message("Share link copied to the clipboard.", false)
|
|
95
|
+
onFailed: function(reason) { pane.message(reason, true) }
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
Flea.Taildrop {
|
|
99
|
+
id: taildrop
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// The owed re-read, run when nothing is holding the rows. A refusal keeps the debt rather than
|
|
103
|
+
// dropping it, and watchBusy going false below is what pays it.
|
|
104
|
+
function reread() {
|
|
105
|
+
if (root.watchBusy)
|
|
106
|
+
return
|
|
107
|
+
root.stale = false
|
|
108
|
+
root.anchor = Anchor.watched(pane, false, Theme.fileRowHeight)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// The owed re-read goes through the timer rather than straight out of this handler: reading
|
|
112
|
+
// watchBusy back inside its own change notification re-enters the binding, which Qt reports as a
|
|
113
|
+
// binding loop, and reread() writes listInFlight, which watchBusy reads.
|
|
114
|
+
onWatchBusyChanged: if (root.stale && !watchSettle.running) watchSettle.start()
|
|
115
|
+
|
|
116
|
+
Timer {
|
|
117
|
+
id: watchSettle
|
|
118
|
+
interval: root.watchMs
|
|
119
|
+
repeat: false
|
|
120
|
+
onTriggered: root.reread()
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Ok item lines wait here and join the card at the next other line or this beat, so a run of small files writes it once; a failure never waits.
|
|
124
|
+
property var heldItems: []
|
|
125
|
+
readonly property int heldItemBeatMs: 100
|
|
126
|
+
Timer { id: heldItemBeat; interval: root.heldItemBeatMs; onTriggered: root.flushItems() }
|
|
127
|
+
function flushItems() {
|
|
128
|
+
heldItemBeat.stop()
|
|
129
|
+
if (root.heldItems.length === 0) return
|
|
130
|
+
root.pane.transfer = Transfer.itemsDone(root.pane.transfer, root.heldItems)
|
|
131
|
+
root.heldItems = []
|
|
132
|
+
root.pane.sticky(Ops.progressLine(root.pane.transfer))
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// A debt owed for the directory the pane has left is not owed by the one it arrived in: without
|
|
136
|
+
// this, a change in A held back by a selection is paid by a full re-list of B.
|
|
137
|
+
Connections {
|
|
138
|
+
target: pane
|
|
139
|
+
function onPathChanged() {
|
|
140
|
+
root.stale = false
|
|
141
|
+
root.anchor = null
|
|
142
|
+
watchSettle.stop()
|
|
143
|
+
root.retryId = 0
|
|
144
|
+
root.retryPaths = []
|
|
145
|
+
}
|
|
146
|
+
function onMenuSelectionInputsChanged() {
|
|
147
|
+
if (root.retrySelectionText && root.pane.menuSelectionIdentity() !== root.retrySelectionIdentity) root.retrySelectionText = ""
|
|
148
|
+
}
|
|
149
|
+
function onListInFlightChanged() { if (!pane.listInFlight) root.locateRetry() }
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function locateRetry() {
|
|
153
|
+
if (!root.retryId || root.retryListing || pane.listInFlight || pane.searchRunning) return
|
|
154
|
+
if (pane.path !== root.retryFolder) { root.retryId = 0; root.retryPaths = []; return }
|
|
155
|
+
root.retryListing = pane.menuSelectionIdentity()
|
|
156
|
+
pane.backend.send({c: "locate", paths: root.retryPaths, transferId: root.retryId})
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Only arm an editor after the new folder's actual row arrives in the held window, matched
|
|
160
|
+
// by the name the backend lists so an NFC name on hfsplus finds its NFD row and editor.
|
|
161
|
+
function openRenameOnArrival() {
|
|
162
|
+
if (root.renameOnArrival.length === 0)
|
|
163
|
+
return
|
|
164
|
+
var target = root.renameOnArrival
|
|
165
|
+
root.renameOnArrival = ""
|
|
166
|
+
var at = Anchor.matchListed(pane, target)
|
|
167
|
+
if (at >= 0) {
|
|
168
|
+
pane.setCursor(at)
|
|
169
|
+
pane.act("rename")
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function refreshRename(request, selected, pointer) {
|
|
174
|
+
if (pane.path !== request.folder) return
|
|
175
|
+
if (pane.listInFlight || pane.searchMode.length > 0) { root.stale = true; return }
|
|
176
|
+
root.stale = false
|
|
177
|
+
watchSettle.stop()
|
|
178
|
+
var anchor = Anchor.pointerRow(pane, request, pane.anchorRowHeight)
|
|
179
|
+
// A cursor a click or key moved off the renamed row while the write was pending is the operator's, so it wins at any scroll.
|
|
180
|
+
var keepsCursor = pointer || anchor.moved
|
|
181
|
+
// The re-list resets the view to its top, so every commit keeps the anchor: it puts the cursor row back at its screen y.
|
|
182
|
+
root.anchor = anchor
|
|
183
|
+
pane.refresh(keepsCursor ? "" : selected)
|
|
184
|
+
if (anchor.start > 0) pane.backend.window(anchor.start, pane.windowSize)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
Connections {
|
|
188
|
+
target: pane.backend
|
|
189
|
+
|
|
190
|
+
function onListed(total, readMs, sortMs, path, changed, gen) { swap.takeListed(total, readMs, sortMs, path, changed, gen) }
|
|
191
|
+
function onRows(start, items, ms, kinds, listing, gen) { swap.takeRows(start, items, kinds, listing, gen) }
|
|
192
|
+
|
|
193
|
+
function onLocated(message) {
|
|
194
|
+
if (BackReturn.takeLocated(pane, message)) return
|
|
195
|
+
Tabs.locatedCursor(pane, message)
|
|
196
|
+
var taken = Anchor.takeLocated(root.pane, root.anchor, message, Theme.fileRowHeight)
|
|
197
|
+
if (taken.handled) {
|
|
198
|
+
root.anchor = taken.anchor
|
|
199
|
+
return
|
|
200
|
+
}
|
|
201
|
+
if (!root.retryId || message.transferId !== root.retryId) return
|
|
202
|
+
root.retryId = 0
|
|
203
|
+
root.retryPaths = []
|
|
204
|
+
if (message.directory !== pane.path || pane.path !== root.retryFolder
|
|
205
|
+
|| root.retryListing !== pane.menuSelectionIdentity() || pane.listInFlight) return
|
|
206
|
+
if (!message.ok) { pane.message(message.error, true); return }
|
|
207
|
+
var matches = message.matches || []
|
|
208
|
+
if (!matches.length) return
|
|
209
|
+
pane.selection.clear()
|
|
210
|
+
for (var i = 0; i < matches.length; i++) pane.selection.toggle(matches[i].index)
|
|
211
|
+
pane.selectionVersion++
|
|
212
|
+
pane.setCursor(matches[0].index)
|
|
213
|
+
root.retrySelectionIdentity = root.pane.menuSelectionIdentity()
|
|
214
|
+
root.retrySelectionText = Ops.retrySelectionLine(matches)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Sample input: {"t":"searched","n":14673,"scanned":284446,"ms":229.008,"cancelled":false,"gen":3,"walking":false}
|
|
218
|
+
// The answered counts land for the newest sent generation with the first window already in place.
|
|
219
|
+
function onSearched(total, scanned, ms, cancelled, gen, walking) {
|
|
220
|
+
Search.searched(pane, total, scanned, ms, cancelled, gen, walking)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Sample input: {"t":"unmounted","path":"/media/stick","parent":"/media"}
|
|
224
|
+
// The open mount went away, so the pane moves up to its nearest existing parent.
|
|
225
|
+
function onUnmounted(path, parent) {
|
|
226
|
+
if (path !== pane.path && !pane.path.startsWith(path + "/"))
|
|
227
|
+
return
|
|
228
|
+
pane.openWithoutHistory(parent)
|
|
229
|
+
pane.message("That drive or share was disconnected, so this folder is no longer available", false)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Sample input: {"t":"changed","path":"/home/gm/Downloads"}
|
|
233
|
+
// Unsolicited, and the only line here that is: the listed directory changed under the pane.
|
|
234
|
+
function onChanged(path) {
|
|
235
|
+
// A notification for a directory the pane has already left says nothing about this one.
|
|
236
|
+
if (path !== pane.path)
|
|
237
|
+
return
|
|
238
|
+
root.retrySelectionText = ""
|
|
239
|
+
root.stale = true
|
|
240
|
+
if (!watchSettle.running)
|
|
241
|
+
watchSettle.start()
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// A thumbed line for the previous listing is still in the pipe when open() clears the map, so it is dropped.
|
|
245
|
+
// A cache-only miss on a generating class returns to unasked so the viewport asks it again instead of keeping the miss.
|
|
246
|
+
function onThumbed(row, file) {
|
|
247
|
+
if (pane.listInFlight)
|
|
248
|
+
return
|
|
249
|
+
var next = ExtThumbs.thumbReply(pane.thumbState, row, file, pane.thumbCap, pane.storageKnown, pane.storageClass, ViewState.preview)
|
|
250
|
+
pane.thumbState = next.state
|
|
251
|
+
// A lost prefetch is visible work again: the settled view re-plans it in full and never as a prefetch, so it asks once per rest.
|
|
252
|
+
if (next.missed && pane.listArea) pane.listArea.restartSettle()
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// The Make executable row's own probe, answered off the loop; the pane keeps only its newest id.
|
|
256
|
+
function onShebang(path, hasShebang, id) { pane.noteShebang(path, hasShebang, id) }
|
|
257
|
+
|
|
258
|
+
// A dirsized line for the previous listing is still in the pipe when open() clears the map.
|
|
259
|
+
function onDirSized(row, bytes, partial) {
|
|
260
|
+
if (!pane.listInFlight)
|
|
261
|
+
pane.dirSizeState = DirSizes.remember(pane.dirSizeState, row, bytes, partial, pane.dirSizeCap)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// The measuring run ended: nothing still waiting will be answered.
|
|
265
|
+
function onDirSizeDone(cancelled) { pane.dirSizeState = DirSizes.settled(pane.dirSizeState) }
|
|
266
|
+
|
|
267
|
+
// Sample input: {"t":"transferstarted","id":12,"n":2,"moving":true}
|
|
268
|
+
// The verb comes off the wire, never off the clipboard: paste spends a cut before this line
|
|
269
|
+
// arrives, and a Dropbox move never touches the clipboard at all.
|
|
270
|
+
function onTransferStarted(id, n, moving, extract) {
|
|
271
|
+
root.heldItems = []
|
|
272
|
+
root.retryId = 0
|
|
273
|
+
root.retryPaths = []
|
|
274
|
+
root.retrySelectionText = ""
|
|
275
|
+
pane.transfer = Ops.started(id, moving, n, extract)
|
|
276
|
+
pane.sticky(Ops.progressLine(pane.transfer))
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Sample input: {"t":"transferprogress","id":12,"index":0,"name":"a.txt","bytes":40000000,"total":120000000,"scanned":8400000000}
|
|
280
|
+
// Sample input: {"t":"transferprogress","id":12,"index":0,"name":"","bytes":0,"total":0,"scanned":0,"phase":"writing","drive":"128GB"}
|
|
281
|
+
function onTransferProgress(id, index, name, bytes, total, scanned, phase, drive) {
|
|
282
|
+
if (id !== pane.transfer.id) {
|
|
283
|
+
return
|
|
284
|
+
}
|
|
285
|
+
root.flushItems()
|
|
286
|
+
// Reassigned rather than mutated in place: an in-place write re-evaluates no binding,
|
|
287
|
+
// so the card would never see a sample. The bytes and the total ride along with it.
|
|
288
|
+
// The writing phase names the drive instead of a file: every file is already complete,
|
|
289
|
+
// so the card holds its counted bytes; see docs/protocol.md "transferprogress".
|
|
290
|
+
if (phase === "writing")
|
|
291
|
+
pane.transfer = Transfer.markWriting(pane.transfer, drive)
|
|
292
|
+
else
|
|
293
|
+
pane.transfer = Transfer.sampled(pane.transfer, index, name, bytes, total, scanned)
|
|
294
|
+
pane.sticky(Ops.progressLine(pane.transfer))
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// One named failure per transfer owns the status slot until acknowledged; later failures remain in its summary.
|
|
298
|
+
function onTransferItem(id, index, name, ok, err) {
|
|
299
|
+
if (id !== pane.transfer.id) {
|
|
300
|
+
return
|
|
301
|
+
}
|
|
302
|
+
if (ok) { root.heldItems.push({ index: index, name: name }); if (!heldItemBeat.running) heldItemBeat.start(); return }
|
|
303
|
+
root.flushItems()
|
|
304
|
+
var firstFailure = !ok && err !== "cancelled" && !pane.transfer.failureReported
|
|
305
|
+
pane.transfer = Object.assign(Transfer.itemDone(pane.transfer, index, name),
|
|
306
|
+
{ failureReported: pane.transfer.failureReported || firstFailure })
|
|
307
|
+
if (firstFailure)
|
|
308
|
+
pane.message(Ops.transferFailure(pane.transfer, name, err), true)
|
|
309
|
+
pane.sticky(Ops.progressLine(pane.transfer))
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Sample input: {"t":"transferdone","id":12,"ok":1,"failed":1,"skipped":0,"cancelled":false,"durable":false,"note":""}
|
|
313
|
+
// Sample input: {"t":"transferdone","id":12,"ok":1,"failed":0,"skipped":0,"cancelled":false,"durable":false,"note":"","merged":212,"keptBoth":3,"into":"trip"}
|
|
314
|
+
function onTransferDone(id, ok, failed, skipped, cancelled, retryPaths, durable, note, merged, keptBoth, into) {
|
|
315
|
+
if (id !== pane.transfer.id) {
|
|
316
|
+
return
|
|
317
|
+
}
|
|
318
|
+
root.flushItems()
|
|
319
|
+
// A merge carries into on its own line; every other transfer keeps today's line.
|
|
320
|
+
var line = into && pane.collide ? pane.collide.doneLine(pane.transfer,
|
|
321
|
+
{ into: into, merged: merged, keptBoth: keptBoth, ok: ok, failed: failed, skipped: skipped, cancelled: cancelled, durable: durable, note: note })
|
|
322
|
+
: Ops.transferDone(pane.transfer, ok, failed, skipped, cancelled, durable, note)
|
|
323
|
+
var unreportedFailure = failed > 1 || (failed > 0 && !pane.transfer.failureReported)
|
|
324
|
+
pane.transfer = Ops.emptyTransfer()
|
|
325
|
+
pane.sticky("")
|
|
326
|
+
pane.message(line, unreportedFailure)
|
|
327
|
+
if (unreportedFailure) pane.message(line, false)
|
|
328
|
+
root.retryId = retryPaths.length ? id : 0
|
|
329
|
+
root.retryPaths = retryPaths
|
|
330
|
+
root.retryFolder = pane.path
|
|
331
|
+
root.retryListing = ""
|
|
332
|
+
if (pane.searchMode === Search.RESULTS) {
|
|
333
|
+
root.stale = true
|
|
334
|
+
root.locateRetry()
|
|
335
|
+
} else pane.refresh("")
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// The listing is read again with the cursor left where the deleted rows were, and the row
|
|
339
|
+
// that took their place selected, so the next delete needs no mouse. The whole selection is
|
|
340
|
+
// gone from disk, so there is nothing to carry over but the position.
|
|
341
|
+
function onTrashed(ok, failed, reason) {
|
|
342
|
+
if (ok === 0 && failed === 0) return
|
|
343
|
+
pane.sticky("")
|
|
344
|
+
pane.message(Ops.trashed(ok, failed, reason), ok === 0)
|
|
345
|
+
pane.clearSelection()
|
|
346
|
+
root.anchor = Anchor.afterDelete(pane, ok > 0)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// The listing is re-read with the new name selected, so the row the operator was on stays
|
|
350
|
+
// under the cursor; a cursor a click or key moved meanwhile keeps its own row instead.
|
|
351
|
+
function onRenamed(ok, path) {
|
|
352
|
+
var request = pane.renameRequest
|
|
353
|
+
if (!SlowOp.closesRename(request, path)) return
|
|
354
|
+
pane.renameRequest = null
|
|
355
|
+
pane.renamingIndex = -1
|
|
356
|
+
var target = Nav.renameRefreshTarget(pane, path)
|
|
357
|
+
root.refreshRename(request, target, target === "")
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// A remote write past its deadline: information only, so the request stays open
|
|
361
|
+
// for the late reply, which closes it exactly as an in-time reply would.
|
|
362
|
+
function onSlowOp(op, path, msg) { pane.message(msg, false) }
|
|
363
|
+
// One line for the whole batch, and one undo reverses every rename it made.
|
|
364
|
+
function onBulkRenamed(ok) { pane.bulkRenamed(ok) }
|
|
365
|
+
|
|
366
|
+
// Sample input: {"t":"made","ok":true,"path":"/home/gm/Pictures/New Folder"}
|
|
367
|
+
// The same refresh onRenamed does, which is also what puts the order back to name ascending
|
|
368
|
+
// and drops any filter, so the new row is never sorted or filtered out of sight.
|
|
369
|
+
function onMade(ok, path) {
|
|
370
|
+
root.renameOnArrival = path
|
|
371
|
+
pane.message(Ops.made(path), false)
|
|
372
|
+
pane.refresh(path)
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function onDuplicated(ok, path) {
|
|
376
|
+
pane.message(Format.fill(Ops.WORDS.duplicated, Ops.leaf(path)) + Status.undoHint(), false)
|
|
377
|
+
pane.refresh(path)
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// MenuAdditions040: Paste as links answers one line per request, and
|
|
381
|
+
// one journal entry, so one undo removes every link it created.
|
|
382
|
+
function onLinked(ok, failed, skipped, note) {
|
|
383
|
+
// A stranded note is shown as an error, so a leftover link is never silent.
|
|
384
|
+
var stranded = String(note || "").length > 0
|
|
385
|
+
pane.message(Ops.linkedLine(ok, failed, skipped, note || ""), (failed > 0 && ok === 0) || stranded)
|
|
386
|
+
pane.refresh("")
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// MenuAdditions040: Show original reveals the link's target in its own
|
|
390
|
+
// folder, the same path Show in folder uses.
|
|
391
|
+
function onLinkTarget(path, directory, name, id) {
|
|
392
|
+
// A stale or foreign id is ignored, so a late reply never yanks a navigation.
|
|
393
|
+
if (!pane.linkTargetPendingId || id !== pane.linkTargetPendingId) return
|
|
394
|
+
pane.linkTargetPendingId = 0
|
|
395
|
+
if (directory.length === 0 || (name.length === 0 && directory !== "/")) {
|
|
396
|
+
pane.message("That link points to an item that no longer exists.", true)
|
|
397
|
+
return
|
|
398
|
+
}
|
|
399
|
+
pane.pendingSelect = name.length === 0 ? "" : directory === "/" ? "/" + name : directory + "/" + name
|
|
400
|
+
pane.open(directory)
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function onUndone(op, ok) {
|
|
404
|
+
pane.sticky("")
|
|
405
|
+
pane.message(Ops.undone(op), false)
|
|
406
|
+
pane.refresh("", op === "permissions" || op === "settags")
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// MenuAdditions040 callout 10: Make executable reuses permissions batch; only this pane's pending id is answered here.
|
|
410
|
+
function onPermissionsResult(message) {
|
|
411
|
+
var pending = Permissions.MAKE_EXEC_ID + pane.makeExecPendingId
|
|
412
|
+
if (!pane.makeExecPendingId || !message || message.id !== pending || message.op !== "applyMany") return
|
|
413
|
+
pane.makeExecPendingId = 0
|
|
414
|
+
if (message.ok === true) {
|
|
415
|
+
pane.message(Status.withUndo("Made it executable."), false)
|
|
416
|
+
pane.refresh("")
|
|
417
|
+
} else {
|
|
418
|
+
pane.message(message.error && message.error.length > 0 ? message.error : "That file could not be made executable.", true)
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function onRedoStarted(id, n, op) {
|
|
423
|
+
var next = Ops.started(id, false, n)
|
|
424
|
+
next.redo = op
|
|
425
|
+
pane.transfer = next
|
|
426
|
+
pane.sticky(Ops.progressLine(next))
|
|
427
|
+
}
|
|
428
|
+
function onRedone(op, ok) {
|
|
429
|
+
pane.transfer = Ops.emptyTransfer()
|
|
430
|
+
pane.sticky("")
|
|
431
|
+
pane.message(Ops.redone(op) + Status.undoHint(), false)
|
|
432
|
+
pane.refresh("", op === "permissions" || op === "settags")
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// An unverified extract says so in the status slot, an encrypted archive opens the extract card, and any other failure messages.
|
|
436
|
+
function onArchiveDone(id, ok, verified, err, path, dest) {
|
|
437
|
+
if (pane.transfer.extract === true && pane.transfer.id === id)
|
|
438
|
+
pane.transfer = Ops.emptyTransfer()
|
|
439
|
+
pane.sticky("")
|
|
440
|
+
var action = Archive.doneAction(ok, err)
|
|
441
|
+
if (action !== "") {
|
|
442
|
+
pane.extractPasswordRequested(path, dest, action === "wrong" ? err : "")
|
|
443
|
+
pane.refresh("")
|
|
444
|
+
return
|
|
445
|
+
}
|
|
446
|
+
pane.message(ok ? Ops.archiveDoneLine(verified) : err === "cancelled" ? "Extraction cancelled." : Errors.sentence("archive", err), !ok && err !== "cancelled")
|
|
447
|
+
pane.refresh("")
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
function onConvertDone(id, ok, path, err, requestId, source, collision) {
|
|
451
|
+
if (requestId && (!pane.convertSource || pane.convertSource.requestId !== requestId || pane.convertSource.path !== source)) return
|
|
452
|
+
pane.sticky("")
|
|
453
|
+
pane.message(ok ? Format.fill(Ops.WORDS.convertedTo, Ops.leaf(path)) : collision ? err : Errors.sentence("convert", err), !ok)
|
|
454
|
+
if (ok) {
|
|
455
|
+
if (pane.searchMode === Search.RESULTS) root.stale = true
|
|
456
|
+
else pane.refresh(path)
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// The backend statfs's its own base, which only moves when a listing succeeds, and Nav.js moves pane.path before one does: a failed hop's figures are of the directory we never left, while a failed refresh's are still of what is on screen.
|
|
461
|
+
// Recent spans mounts and asks for no figures of its own, so a late answer for its base is refused with the stale ones.
|
|
462
|
+
function onFsInfo(fs, free, path, storageClass, tagable, systemVolume) {
|
|
463
|
+
// The line follows its listing's, but a loading mark makes the rows wait, so pane.path still names the folder left while the listing out is the one this line answers.
|
|
464
|
+
var ours = (path.length === 0 || path === root.pane.path || (root.pane.listInFlight && path === root.pane.listingPath)) && root.pane.recentMode.length === 0
|
|
465
|
+
root.pane.fsName = ours ? fs : ""; root.pane.fsFree = ours ? free : 0
|
|
466
|
+
if (ours || !root.pane.listInFlight) root.pane.fsAnswered = true
|
|
467
|
+
if (ours) {
|
|
468
|
+
pane.storageClass = storageClass || ""
|
|
469
|
+
pane.systemVolume = systemVolume === true
|
|
470
|
+
pane.storageKnown = true
|
|
471
|
+
pane.canTag = tagable === true
|
|
472
|
+
// The verdict follows the directory, so a class switch later compares
|
|
473
|
+
// against this listing's own gate rather than the one navigated from.
|
|
474
|
+
pane.extVerdict = ExtThumbs.verdict(pane.storageClass, ViewState.preview)
|
|
475
|
+
if (pane.listArea) pane.listArea.restartSettle()
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// A paths reply reaches only the asker its tag names; the anchor's own is consumed above.
|
|
480
|
+
function onPaths(list) {
|
|
481
|
+
if (Anchor.takesPaths(root.pane, root.anchor)) {
|
|
482
|
+
root.anchor = Anchor.fillPaths(root.pane, root.anchor, list)
|
|
483
|
+
return
|
|
484
|
+
}
|
|
485
|
+
Ops.pathsResolved(pane, list)
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
function onClipResult(message) { Clipboard.receive(pane, message) }
|
|
489
|
+
|
|
490
|
+
function onFailed(where, input, message, mode) {
|
|
491
|
+
if (pane.path.length === 0 && input.length > 0) pane.path = input
|
|
492
|
+
var text = Errors.sentence(where, message, input && input !== pane.path ? Ops.leaf(input) : "")
|
|
493
|
+
var terminal = where === "backend" || where === "read"
|
|
494
|
+
// A dead backend ends every listing, so no deferred menu can ever land on one.
|
|
495
|
+
if (terminal) {
|
|
496
|
+
pane.pendingMenu = false
|
|
497
|
+
Nav.clearPendingBackground(pane)
|
|
498
|
+
}
|
|
499
|
+
var request = pane.renameRequest
|
|
500
|
+
var renamePath = request && (input === request.source || input === request.destination
|
|
501
|
+
|| (where === "rename" && (input.length === 0 || input.indexOf(request.source + "/") === 0
|
|
502
|
+
|| input.indexOf(request.destination + "/") === 0)))
|
|
503
|
+
if (request && (terminal || (renamePath && ["rename", "journal", "rename-kept", "rename-stranded"].indexOf(where) >= 0))) {
|
|
504
|
+
var pointer = pane.renameKeepsPointerRow
|
|
505
|
+
pane.renameRequest = null
|
|
506
|
+
pane.renameKeepsPointerRow = false
|
|
507
|
+
if (terminal) {
|
|
508
|
+
text = "Flea stopped responding, so the rename may not have finished. Check the name."
|
|
509
|
+
} else if (where === "rename-kept" || where === "rename-stranded" || (where === "journal" && input === request.destination)) {
|
|
510
|
+
// A destination-side journal failure happens after the filesystem rename succeeded.
|
|
511
|
+
pane.renamingIndex = -1
|
|
512
|
+
if (where === "journal") text = "Renamed, but undo cannot reverse this rename."
|
|
513
|
+
pane.message(text, true)
|
|
514
|
+
root.refreshRename(request, pointer ? "" : (where === "journal" ? request.destination : ""), pointer)
|
|
515
|
+
return
|
|
516
|
+
} else {
|
|
517
|
+
var reason = Errors.exists(message) ? Format.fill(Ops.WORDS.alreadyExists, Ops.leaf(request.destination)) : Errors.capitalised(message)
|
|
518
|
+
// Grid closing review G1: with no live editor to show it, the
|
|
519
|
+
// refusal goes to the status bar and the edit closes.
|
|
520
|
+
Ops.refuseRename(pane, reason)
|
|
521
|
+
return
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
if (where === "redo") { pane.transfer = Ops.emptyTransfer(); pane.sticky("") }
|
|
525
|
+
// A refused sort changes nothing in the backend, so it changes nothing here: a notice in the
|
|
526
|
+
// plain role, never the error role, which is for a listing that stopped being true.
|
|
527
|
+
if (where === "sort") {
|
|
528
|
+
pane.message(text, false)
|
|
529
|
+
return
|
|
530
|
+
}
|
|
531
|
+
// Rows parked for a Back's locate land at the top on every failure that reaches here but a stale one, so that listing still ends.
|
|
532
|
+
var parkedLanded = where !== "stale" && pane.swap.landParked()
|
|
533
|
+
// The rows a request named were another numbering's, so only that request ended, see src/backend/rowguard.rs.
|
|
534
|
+
// A paths failure clears its claim either way. Leaving it set blocks the next copy.
|
|
535
|
+
var listingEnded = (terminal || !parkedLanded) && Swap.failListing(pane, where, input)
|
|
536
|
+
if (input === "paths") {
|
|
537
|
+
var claim = pane.pathsPending
|
|
538
|
+
if (claim && claim.kind === "drag") {
|
|
539
|
+
pane.pathsPending = null
|
|
540
|
+
claim.deliver(null, claim)
|
|
541
|
+
if (!listingEnded) return
|
|
542
|
+
} else if (claim && claim.kind === "anchor") {
|
|
543
|
+
// A failed anchor ask ends the anchor on its clamped index instead of stranding it.
|
|
544
|
+
if (root.anchor && root.anchor.needPaths)
|
|
545
|
+
root.anchor = Anchor.failAnchor(root.pane, root.anchor, Theme.fileRowHeight)
|
|
546
|
+
else
|
|
547
|
+
root.pane.pathsPending = null
|
|
548
|
+
if (!listingEnded) return
|
|
549
|
+
} else if (claim) pane.pathsPending = null
|
|
550
|
+
else Ops.clipFailed(pane)
|
|
551
|
+
}
|
|
552
|
+
if (!listingEnded) {
|
|
553
|
+
// A refused window ends its directory's anchor so the owed re-read can run.
|
|
554
|
+
if (where === "window" && root.anchor && input === root.anchor.path
|
|
555
|
+
&& root.anchor.path === root.pane.path)
|
|
556
|
+
root.anchor = Anchor.failAnchor(root.pane, root.anchor, Theme.fileRowHeight)
|
|
557
|
+
pane.message(text, true)
|
|
558
|
+
return
|
|
559
|
+
}
|
|
560
|
+
// The target listing actually ended, so neither deferred menu can land on it; a stale or refused sort never reaches here.
|
|
561
|
+
pane.pendingMenu = false
|
|
562
|
+
Nav.clearPendingBackground(pane)
|
|
563
|
+
// Neither the child nor its stream comes back, so the listing it produced stops being true.
|
|
564
|
+
// Only these two mean the refresh will never deliver rows. An editor left armed past that
|
|
565
|
+
// would open over whatever row the cursor happens to hold in some later listing.
|
|
566
|
+
if (terminal || where === "scan")
|
|
567
|
+
root.renameOnArrival = ""
|
|
568
|
+
if (terminal) {
|
|
569
|
+
pane.renamingIndex = -1
|
|
570
|
+
root.retrySelectionText = ""
|
|
571
|
+
pane.total = 0
|
|
572
|
+
pane.held = 0
|
|
573
|
+
pane.rows = []
|
|
574
|
+
pane.cursorIndex = 0
|
|
575
|
+
// No transferdone is coming from a backend that is gone, and nothing else ends a
|
|
576
|
+
// running transfer, so the card would crawl over a dead child until the app closed.
|
|
577
|
+
pane.transfer = Ops.emptyTransfer()
|
|
578
|
+
pane.sticky("")
|
|
579
|
+
}
|
|
580
|
+
// A failure landing on the waiting state ends the wait the same way, so no
|
|
581
|
+
// stale "not responding" outlives the answer that replaced it.
|
|
582
|
+
if (terminal || where === "scan" || pane.listingState === "loading" || pane.listingState === "waiting") {
|
|
583
|
+
pane.listingState = Errors.listingState(where, message)
|
|
584
|
+
pane.lockedMode = mode; pane.stateMessage = text
|
|
585
|
+
}
|
|
586
|
+
pane.message(text, true) // The rule: the centre lane carries the refusal, both StatusBar lanes
|
|
587
|
+
// The names on disk changed in a way no reply listed (a kept copy, or a twin left under its temp), so re-read the listing and select nothing.
|
|
588
|
+
if (where === "rename-kept" || where === "rename-stranded")
|
|
589
|
+
pane.refresh("")
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// flea --ui-state is a reply from outside the window too. A refused patch, or a state file it
|
|
594
|
+
// could not write, means the change is on screen and the file does not have it; nothing else
|
|
595
|
+
// would ever say so, because the window's own read is taken once before the first frame.
|
|
596
|
+
Connections {
|
|
597
|
+
target: ViewState
|
|
598
|
+
function onSaveFailed() { pane.message(Errors.sentence("state", ""), true) }
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// The other half of the same seam: main() leaves a ui.json it cannot read exactly as the operator
|
|
602
|
+
// wrote it, and the window draws the shipped defaults, so this says once that none of it was used.
|
|
603
|
+
Component.onCompleted: if (ViewState.unreadable) pane.message(Errors.sentence("statefile", ""), true)
|
|
604
|
+
|
|
605
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
|
|
3
|
+
// The parked Back's listing wait, built on the first park by ui/PaneSwap.qml so a window that never parks starts no Timer.
|
|
4
|
+
Timer {
|
|
5
|
+
required property var swap
|
|
6
|
+
interval: swap.parkedWaitMs
|
|
7
|
+
repeat: false
|
|
8
|
+
onTriggered: swap.landParked()
|
|
9
|
+
}
|