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
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import qs.Commons
|
|
3
|
+
import "." as Flea
|
|
4
|
+
import "js/OpenWith.js" as OpenWith
|
|
5
|
+
import "js/Format.js" as Format
|
|
6
|
+
import "js/Input.js" as Input
|
|
7
|
+
|
|
8
|
+
// OpenWith.html rule 4: the Convert popup family, and the one place a default handler is written.
|
|
9
|
+
// The flyout beside it overrides once and writes nothing; only this card touches mimeapps.list.
|
|
10
|
+
Item {
|
|
11
|
+
id: root
|
|
12
|
+
|
|
13
|
+
property bool opened: false
|
|
14
|
+
readonly property string action: "openWith"
|
|
15
|
+
property int requestId: 0
|
|
16
|
+
property Item focusHolder: null
|
|
17
|
+
property bool busy: false
|
|
18
|
+
property bool committing: false
|
|
19
|
+
property string errorText: ""
|
|
20
|
+
property string path: ""
|
|
21
|
+
property string kind: ""
|
|
22
|
+
property string mime: ""
|
|
23
|
+
property var handlers: []
|
|
24
|
+
property var installed: []
|
|
25
|
+
property bool always: false
|
|
26
|
+
property int cursor: 0
|
|
27
|
+
// 0 search, 1 list, 2 always box, 3 Cancel, 4 Open: rule 8's own cycle, and it wraps; the cursor row draws on 0 and 1 only, as Enter from either opens it.
|
|
28
|
+
property int focusPart: 0
|
|
29
|
+
// Where a row or the ground last saw the pointer, -1 since opening, so a row built or scrolled under a resting pointer never takes the cursor.
|
|
30
|
+
property point pointerGlobal: Qt.point(-1, -1)
|
|
31
|
+
|
|
32
|
+
signal requested(var message)
|
|
33
|
+
signal closed()
|
|
34
|
+
|
|
35
|
+
readonly property string name: root.path.split("/").pop()
|
|
36
|
+
readonly property var rows: OpenWith.rows(root.handlers, root.installed, root.kind, field.text)
|
|
37
|
+
readonly property var applications: OpenWith.applications(root.rows)
|
|
38
|
+
readonly property var chosen: root.applications[root.cursor]
|
|
39
|
+
readonly property bool canSubmit: !root.busy && root.chosen !== undefined
|
|
40
|
+
// The shared menu-dialog probe reads these; ui/Ipc.qml openWithState adds this board's own rows.
|
|
41
|
+
readonly property var facts: ({})
|
|
42
|
+
readonly property bool deletionActive: false
|
|
43
|
+
readonly property var confirmationItem: null
|
|
44
|
+
readonly property var cardItem: card
|
|
45
|
+
readonly property var closeItem: cancelButton
|
|
46
|
+
readonly property var submitItem: openButton
|
|
47
|
+
readonly property var fieldItem: field
|
|
48
|
+
readonly property var titleRuleItem: title.ruleItem
|
|
49
|
+
readonly property var searchItem: searchBox
|
|
50
|
+
readonly property var applicationsItem: list
|
|
51
|
+
readonly property var alwaysItem: alwaysBox
|
|
52
|
+
function applicationItem(index) { return list.itemAtIndex(OpenWith.rowOf(root.rows, index)) }
|
|
53
|
+
|
|
54
|
+
// Rule 5: seven applications before the list scrolls. Measured once from the whole catalogue, so
|
|
55
|
+
// rule 6's "keeps its height" holds for every search the user types into it, not only the empty one.
|
|
56
|
+
readonly property int viewportRows: 7
|
|
57
|
+
readonly property int eyebrowHeight: Math.round(Theme.font.caption * 1.6) + Theme.spacing.gap
|
|
58
|
+
property int listHeight: root.viewportRows * Theme.rowHeight
|
|
59
|
+
readonly property int clampMargin: 8
|
|
60
|
+
// DialogButtons040 at size 14: the field is 18 px under the title rule (two gaps) and 31 px over the eyebrow's ink (the row's own 15 plus 16).
|
|
61
|
+
readonly property int searchLead: 2 * Theme.spacing.gap
|
|
62
|
+
readonly property real eyebrowLeadBoard: 16
|
|
63
|
+
readonly property real bodySmallBoard: 13
|
|
64
|
+
readonly property int searchTrail: Math.round(root.eyebrowLeadBoard * Theme.font.bodySmall / root.bodySmallBoard)
|
|
65
|
+
|
|
66
|
+
anchors.fill: parent
|
|
67
|
+
visible: root.opened || root.opacity > 0
|
|
68
|
+
// Closed means no input, even while the fade-out is still drawn.
|
|
69
|
+
enabled: root.opened
|
|
70
|
+
opacity: 0
|
|
71
|
+
z: 2
|
|
72
|
+
Flea.Reveal { target: root; shown: root.opened; lift: card }
|
|
73
|
+
|
|
74
|
+
// The shared signature the Loader calls both cards with; this one reads the item off the reply.
|
|
75
|
+
function open(operation, id, sourceFolder, holder) {
|
|
76
|
+
root.requestId = id
|
|
77
|
+
root.focusHolder = holder
|
|
78
|
+
root.path = ""
|
|
79
|
+
root.kind = ""
|
|
80
|
+
root.mime = ""
|
|
81
|
+
root.handlers = []
|
|
82
|
+
root.installed = []
|
|
83
|
+
root.always = false
|
|
84
|
+
root.cursor = 0
|
|
85
|
+
root.pointerGlobal = Qt.point(-1, -1)
|
|
86
|
+
root.listHeight = root.viewportRows * Theme.rowHeight
|
|
87
|
+
root.errorText = ""
|
|
88
|
+
root.committing = false
|
|
89
|
+
root.busy = true
|
|
90
|
+
root.focusPart = 0
|
|
91
|
+
field.text = ""
|
|
92
|
+
root.opened = true
|
|
93
|
+
list.contentY = 0
|
|
94
|
+
wheel.resetSteps()
|
|
95
|
+
field.forceActiveFocus()
|
|
96
|
+
// installed: the whole catalogue, which only this card draws. The flyout asks without it,
|
|
97
|
+
// so a right-click does not pay for a walk of every applications directory on the box.
|
|
98
|
+
root.requested({c: "menuaction", op: "applications", id: id, installed: true})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function close() {
|
|
102
|
+
if (!root.opened) return
|
|
103
|
+
// The close op expires the snapshot and cancels the owned launcher, so Cancel during a launch
|
|
104
|
+
// ends the child rather than leaving it running behind a card that is already gone.
|
|
105
|
+
root.requested({c: "menuaction", op: "close", id: root.requestId})
|
|
106
|
+
root.opened = false
|
|
107
|
+
root.settleClosed()
|
|
108
|
+
root.closed()
|
|
109
|
+
if (root.focusHolder) root.focusHolder.forceActiveFocus()
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// A closed card keeps its busy look while it fades out; the reset waits until it is gone.
|
|
113
|
+
function settleClosed() {
|
|
114
|
+
if (root.opened || root.opacity !== 0) return
|
|
115
|
+
root.busy = false
|
|
116
|
+
root.committing = false
|
|
117
|
+
}
|
|
118
|
+
onOpacityChanged: root.settleClosed()
|
|
119
|
+
|
|
120
|
+
// The pane calls this when the folder is refreshed under an open dialog. Nothing to redraw here:
|
|
121
|
+
// the backend rechecks the captured item on submit, so a selection that moved refuses there.
|
|
122
|
+
function sourceChanged() {}
|
|
123
|
+
|
|
124
|
+
function receive(message) {
|
|
125
|
+
if (!root.opened || message.id !== root.requestId) return
|
|
126
|
+
if (message.op === "applications") {
|
|
127
|
+
root.busy = false
|
|
128
|
+
if (!message.ok) { root.errorText = message.error || "The list of applications could not be read."; return }
|
|
129
|
+
root.path = message.path || ""
|
|
130
|
+
root.kind = message.kind || ""
|
|
131
|
+
root.mime = message.mime || ""
|
|
132
|
+
root.handlers = message.applications || []
|
|
133
|
+
root.installed = message.installed || []
|
|
134
|
+
root.cursor = 0
|
|
135
|
+
root.listHeight = OpenWith.viewportHeight(root.rows, root.viewportRows, Theme.rowHeight, root.eyebrowHeight)
|
|
136
|
+
return
|
|
137
|
+
}
|
|
138
|
+
if (message.op !== "openWith") return
|
|
139
|
+
if (message.ok) { root.close(); return }
|
|
140
|
+
root.busy = false
|
|
141
|
+
root.committing = false
|
|
142
|
+
if (!message.cancelled) root.errorText = message.error || "The application could not be opened."
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function commit() {
|
|
146
|
+
if (!root.canSubmit) return
|
|
147
|
+
root.errorText = ""
|
|
148
|
+
root.busy = true
|
|
149
|
+
root.committing = true
|
|
150
|
+
root.requested({c: "menuaction", op: "openWith", id: root.requestId,
|
|
151
|
+
application: root.chosen.id, always: root.always})
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function moveCursor(delta) {
|
|
155
|
+
var count = root.applications.length
|
|
156
|
+
if (!count) return
|
|
157
|
+
root.focusPart = 1
|
|
158
|
+
root.cursor = Math.max(0, Math.min(count - 1, root.cursor + delta))
|
|
159
|
+
list.forceActiveFocus()
|
|
160
|
+
// By index, not by item: a ListView has no item for a row it has not realized yet.
|
|
161
|
+
list.positionViewAtIndex(OpenWith.rowOf(root.rows, root.cursor), ListView.Contain)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Wheel step: cursor and view move, focus never does; a busy list answers nothing.
|
|
165
|
+
function stepCursor(delta) {
|
|
166
|
+
if (root.busy) return
|
|
167
|
+
var count = root.applications.length
|
|
168
|
+
if (!count) return
|
|
169
|
+
root.cursor = Math.max(0, Math.min(count - 1, root.cursor + delta))
|
|
170
|
+
list.positionViewAtIndex(OpenWith.rowOf(root.rows, root.cursor), ListView.Contain)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function stepFocus(back) {
|
|
174
|
+
if (root.busy) return
|
|
175
|
+
var parts = [0, 1, 2, 3, 4]
|
|
176
|
+
var at = parts.indexOf(root.focusPart)
|
|
177
|
+
root.focusPart = parts[(at + (back ? parts.length - 1 : 1)) % parts.length]
|
|
178
|
+
var item = [field, list, alwaysBox, cancelButton, openButton][root.focusPart]
|
|
179
|
+
item.forceActiveFocus()
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Rule 8: typing anywhere goes to the search, so a key nothing else claimed lands in the field.
|
|
183
|
+
function typeIntoSearch(text) {
|
|
184
|
+
root.focusPart = 0
|
|
185
|
+
field.forceActiveFocus()
|
|
186
|
+
field.insert(field.length, text)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
Rectangle {
|
|
190
|
+
anchors.fill: parent
|
|
191
|
+
color: Theme.color.background
|
|
192
|
+
opacity: 0.5
|
|
193
|
+
|
|
194
|
+
MouseArea {
|
|
195
|
+
id: ground
|
|
196
|
+
anchors.fill: parent
|
|
197
|
+
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
|
198
|
+
hoverEnabled: true
|
|
199
|
+
onEntered: root.pointerGlobal = ground.mapToItem(null, ground.mouseX, ground.mouseY)
|
|
200
|
+
onPositionChanged: function (mouse) { root.pointerGlobal = ground.mapToItem(null, mouse.x, mouse.y) }
|
|
201
|
+
onClicked: root.close()
|
|
202
|
+
onWheel: function (wheel) { wheel.accepted = true }
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
Rectangle {
|
|
207
|
+
id: card
|
|
208
|
+
x: Theme.cardOrigin(root.width, width)
|
|
209
|
+
y: Theme.cardOrigin(root.height, height)
|
|
210
|
+
width: Theme.cardSpan(Theme.space(480) * Theme.dialogWidthRatio, root.width - 2 * root.clampMargin)
|
|
211
|
+
// Clamped to the window; the body scrolls whatever the clamp cut, so a short screen cannot
|
|
212
|
+
// put Cancel and Open past the bottom edge with no way to reach them.
|
|
213
|
+
height: Theme.cardSpan(body.wanted + 2 * Theme.spacing.rowPaddingX, root.height - 2 * root.clampMargin)
|
|
214
|
+
color: Theme.color.surface
|
|
215
|
+
border.width: Theme.spacing.hairline
|
|
216
|
+
border.color: Theme.color.mutedFrame
|
|
217
|
+
radius: Style.cornerRadius
|
|
218
|
+
|
|
219
|
+
// The checkbox handler takes a passive grab, so without this sink its press reaches the ground.
|
|
220
|
+
MouseArea {
|
|
221
|
+
id: cardSink
|
|
222
|
+
anchors.fill: parent
|
|
223
|
+
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
|
224
|
+
hoverEnabled: true
|
|
225
|
+
onEntered: root.pointerGlobal = cardSink.mapToItem(null, cardSink.mouseX, cardSink.mouseY)
|
|
226
|
+
onPositionChanged: function (mouse) { root.pointerGlobal = cardSink.mapToItem(null, mouse.x, mouse.y) }
|
|
227
|
+
onClicked: {}
|
|
228
|
+
onWheel: function (wheel) { wheel.accepted = true }
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
Flea.CardFrame {
|
|
232
|
+
id: body
|
|
233
|
+
bleedY: Theme.focusClearance
|
|
234
|
+
anchors.fill: parent
|
|
235
|
+
anchors.topMargin: Theme.spacing.rowPaddingX - Theme.focusClearance
|
|
236
|
+
anchors.bottomMargin: Theme.spacing.rowPaddingX - Theme.focusClearance
|
|
237
|
+
spacing: 0
|
|
238
|
+
|
|
239
|
+
// RunCard's own header: the esc hint at the right and the rule inset to the content edge.
|
|
240
|
+
title: Flea.DialogHeader {
|
|
241
|
+
id: title
|
|
242
|
+
x: Theme.spacing.rowPaddingX
|
|
243
|
+
width: parent.width - 2 * Theme.spacing.rowPaddingX
|
|
244
|
+
elide: Text.ElideMiddle
|
|
245
|
+
// The registry names the item, so the title says only what it knows until it lands.
|
|
246
|
+
text: root.name.length > 0 ? Format.fill(OpenWith.WORDS.titleNamed, root.name) : "Open with"
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
Column {
|
|
250
|
+
width: parent.width
|
|
251
|
+
|
|
252
|
+
// Rule 4: the Network board's field, with the lens beside it and a clear mark once it holds text.
|
|
253
|
+
Item {
|
|
254
|
+
width: parent.width
|
|
255
|
+
height: root.searchLead + searchBox.height + root.searchTrail
|
|
256
|
+
|
|
257
|
+
Rectangle {
|
|
258
|
+
id: searchBox
|
|
259
|
+
anchors.left: parent.left
|
|
260
|
+
anchors.right: parent.right
|
|
261
|
+
anchors.leftMargin: Theme.spacing.rowPaddingX
|
|
262
|
+
anchors.rightMargin: Theme.spacing.rowPaddingX
|
|
263
|
+
anchors.bottom: parent.bottom
|
|
264
|
+
anchors.bottomMargin: root.searchTrail
|
|
265
|
+
height: Theme.rowHeight - Theme.spacing.rowPaddingY
|
|
266
|
+
color: Theme.color.background
|
|
267
|
+
border.width: Theme.spacing.hairline
|
|
268
|
+
border.color: field.activeFocus ? Theme.color.accent : Theme.color.mutedFrame
|
|
269
|
+
|
|
270
|
+
Flea.Glyph {
|
|
271
|
+
id: lens
|
|
272
|
+
anchors.left: parent.left
|
|
273
|
+
anchors.leftMargin: Theme.spacing.gap
|
|
274
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
275
|
+
width: Theme.font.body
|
|
276
|
+
height: Theme.font.body
|
|
277
|
+
name: "search"
|
|
278
|
+
color: Theme.color.mutedFrame
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
TextInput {
|
|
282
|
+
id: field
|
|
283
|
+
anchors.left: lens.right
|
|
284
|
+
anchors.right: clear.left
|
|
285
|
+
anchors.leftMargin: Theme.spacing.gap
|
|
286
|
+
anchors.rightMargin: Theme.spacing.gap
|
|
287
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
288
|
+
color: Theme.color.foreground
|
|
289
|
+
selectionColor: Theme.color.accent
|
|
290
|
+
selectedTextColor: Theme.color.background
|
|
291
|
+
font.family: Theme.font.family
|
|
292
|
+
font.pixelSize: Theme.font.body
|
|
293
|
+
clip: true
|
|
294
|
+
activeFocusOnTab: false
|
|
295
|
+
Keys.forwardTo: [keys]
|
|
296
|
+
onTextChanged: { root.cursor = 0; list.contentY = 0 }
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
Text {
|
|
300
|
+
anchors.left: field.left
|
|
301
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
302
|
+
visible: field.text.length === 0
|
|
303
|
+
text: "Search applications"
|
|
304
|
+
color: Theme.color.muted
|
|
305
|
+
font.family: Theme.font.family
|
|
306
|
+
font.pixelSize: Theme.font.body
|
|
307
|
+
textFormat: Text.PlainText
|
|
308
|
+
elide: Text.ElideRight
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
Item {
|
|
312
|
+
id: clear
|
|
313
|
+
anchors.right: parent.right
|
|
314
|
+
anchors.rightMargin: Theme.spacing.gap
|
|
315
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
316
|
+
width: field.text.length > 0 ? Theme.font.caption : 0
|
|
317
|
+
height: Theme.font.caption
|
|
318
|
+
|
|
319
|
+
Flea.Glyph {
|
|
320
|
+
anchors.fill: parent
|
|
321
|
+
visible: field.text.length > 0
|
|
322
|
+
name: "x"
|
|
323
|
+
color: Theme.color.mutedFrame
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
TapHandler {
|
|
327
|
+
enabled: field.text.length > 0
|
|
328
|
+
acceptedButtons: Qt.LeftButton
|
|
329
|
+
gesturePolicy: TapHandler.ReleaseWithinBounds
|
|
330
|
+
onTapped: { field.text = ""; root.focusPart = 0; field.forceActiveFocus() }
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
Item {
|
|
337
|
+
width: parent.width
|
|
338
|
+
height: root.listHeight
|
|
339
|
+
|
|
340
|
+
// A ListView, not a Repeater: a box holds well over a hundred applications and the
|
|
341
|
+
// model is a fresh array on every keystroke, so a Repeater rebuilt every delegate,
|
|
342
|
+
// each one a MenuRow with its own Shape, for every character typed.
|
|
343
|
+
ListView {
|
|
344
|
+
id: list
|
|
345
|
+
anchors.fill: parent
|
|
346
|
+
clip: true
|
|
347
|
+
model: root.rows
|
|
348
|
+
reuseItems: true
|
|
349
|
+
boundsBehavior: Flickable.StopAtBounds
|
|
350
|
+
activeFocusOnTab: false
|
|
351
|
+
Keys.forwardTo: [keys]
|
|
352
|
+
Flea.FastScrollHandler {
|
|
353
|
+
id: wheel
|
|
354
|
+
parent: list
|
|
355
|
+
flickable: list
|
|
356
|
+
// The app list steps the highlight like a menu: one row a notch, one
|
|
357
|
+
// row per row height of gained touchpad travel. No bar, no lane.
|
|
358
|
+
stepMode: true
|
|
359
|
+
stepRowHeight: Theme.rowHeight
|
|
360
|
+
stepBy: function (delta) { root.stepCursor(delta) }
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
delegate: Item {
|
|
364
|
+
id: row
|
|
365
|
+
required property var modelData
|
|
366
|
+
required property int index
|
|
367
|
+
readonly property bool isEyebrow: row.modelData.eyebrow !== undefined
|
|
368
|
+
// The cursor counts applications only, so an eyebrow never takes it.
|
|
369
|
+
readonly property int appIndex: row.isEyebrow ? -1 : row.modelData.at
|
|
370
|
+
width: list.width
|
|
371
|
+
height: row.isEyebrow ? root.eyebrowHeight : menuRow.height
|
|
372
|
+
|
|
373
|
+
Rectangle {
|
|
374
|
+
anchors.top: parent.top
|
|
375
|
+
width: parent.width
|
|
376
|
+
height: Theme.spacing.hairline
|
|
377
|
+
visible: row.isEyebrow && row.modelData.rule === true
|
|
378
|
+
color: Theme.color.mutedFrame
|
|
379
|
+
opacity: 0.4
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
Text {
|
|
383
|
+
id: eyebrow
|
|
384
|
+
visible: row.isEyebrow
|
|
385
|
+
anchors.left: parent.left
|
|
386
|
+
anchors.leftMargin: Theme.spacing.rowPaddingX
|
|
387
|
+
anchors.bottom: parent.bottom
|
|
388
|
+
text: row.isEyebrow ? row.modelData.eyebrow : ""
|
|
389
|
+
color: Theme.color.muted
|
|
390
|
+
font.family: Theme.font.family
|
|
391
|
+
font.pixelSize: Theme.font.caption
|
|
392
|
+
font.bold: true
|
|
393
|
+
font.capitalization: Font.AllUppercase
|
|
394
|
+
font.letterSpacing: Theme.font.caption * 0.14
|
|
395
|
+
textFormat: Text.PlainText
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
Flea.MenuRow {
|
|
399
|
+
id: menuRow
|
|
400
|
+
visible: !row.isEyebrow
|
|
401
|
+
width: parent.width
|
|
402
|
+
entry: row.isEyebrow ? ({}) : ({ label: row.modelData.label, action: "",
|
|
403
|
+
icon: row.modelData.icon, glyph: "app-window",
|
|
404
|
+
hint: row.modelData.default === true ? "default" : "" })
|
|
405
|
+
current: !row.isEyebrow && root.focusPart < 2 && root.cursor === row.appIndex
|
|
406
|
+
lastPointerGlobal: root.pointerGlobal
|
|
407
|
+
onPointerSeen: function (at) { root.pointerGlobal = at }
|
|
408
|
+
// The cursor follows the pointer, the focus does not: a pointer crossing
|
|
409
|
+
// this list on its way to Cancel used to make Enter open a row instead.
|
|
410
|
+
onPointerMoved: if (!row.isEyebrow) root.cursor = row.appIndex
|
|
411
|
+
onActivated: if (!row.isEyebrow) { root.focusPart = 1; root.cursor = row.appIndex; root.commit() }
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Rule 6: the area keeps its height and centres the one caption that says why it is empty.
|
|
417
|
+
Text {
|
|
418
|
+
anchors.centerIn: parent
|
|
419
|
+
width: parent.width - 4 * Theme.spacing.rowPaddingX
|
|
420
|
+
visible: !root.busy && !root.rows.length && field.text.trim().length > 0
|
|
421
|
+
text: OpenWith.noMatch(field.text)
|
|
422
|
+
color: Theme.color.muted
|
|
423
|
+
font.family: Theme.font.family
|
|
424
|
+
font.pixelSize: Theme.font.caption
|
|
425
|
+
textFormat: Text.PlainText
|
|
426
|
+
horizontalAlignment: Text.AlignHCenter
|
|
427
|
+
wrapMode: Text.Wrap
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// The fade that says the viewport cut the list, drawn in the card's own ground inside its frame.
|
|
431
|
+
Rectangle {
|
|
432
|
+
anchors.left: parent.left
|
|
433
|
+
anchors.right: parent.right
|
|
434
|
+
anchors.leftMargin: Theme.spacing.hairline
|
|
435
|
+
anchors.rightMargin: Theme.spacing.hairline
|
|
436
|
+
anchors.bottom: parent.bottom
|
|
437
|
+
height: Theme.spacing.gap
|
|
438
|
+
visible: list.contentHeight > list.height && list.contentY < list.contentHeight - list.height - 1
|
|
439
|
+
gradient: Gradient {
|
|
440
|
+
GradientStop { position: 0; color: Qt.rgba(Theme.color.surface.r, Theme.color.surface.g, Theme.color.surface.b, 0) }
|
|
441
|
+
GradientStop { position: 1; color: Theme.color.surface }
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// The Always checkbox row; a tap or Space toggles it.
|
|
447
|
+
Item {
|
|
448
|
+
id: alwaysBox
|
|
449
|
+
width: parent.width
|
|
450
|
+
height: Theme.rowHeight
|
|
451
|
+
activeFocusOnTab: true
|
|
452
|
+
Keys.forwardTo: [keys]
|
|
453
|
+
Accessible.role: Accessible.CheckBox
|
|
454
|
+
Accessible.name: alwaysLabel.text
|
|
455
|
+
Accessible.checkable: true
|
|
456
|
+
Accessible.checked: root.always
|
|
457
|
+
Accessible.onPressAction: root.always = !root.always
|
|
458
|
+
|
|
459
|
+
Rectangle {
|
|
460
|
+
anchors.top: parent.top
|
|
461
|
+
width: parent.width
|
|
462
|
+
height: Theme.spacing.hairline
|
|
463
|
+
color: Theme.color.mutedFrame
|
|
464
|
+
opacity: 0.4
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
Item {
|
|
468
|
+
id: box
|
|
469
|
+
anchors.left: parent.left
|
|
470
|
+
anchors.leftMargin: Theme.spacing.rowPaddingX
|
|
471
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
472
|
+
width: ruleBox.implicitWidth
|
|
473
|
+
height: ruleBox.implicitHeight
|
|
474
|
+
|
|
475
|
+
Flea.CheckBox {
|
|
476
|
+
id: ruleBox
|
|
477
|
+
value: root.always ? "on" : "off"
|
|
478
|
+
focused: root.focusPart === 2
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
Text {
|
|
483
|
+
id: alwaysLabel
|
|
484
|
+
anchors.left: box.right
|
|
485
|
+
anchors.leftMargin: Theme.spacing.gap
|
|
486
|
+
anchors.right: parent.right
|
|
487
|
+
anchors.rightMargin: Theme.spacing.rowPaddingX
|
|
488
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
489
|
+
text: root.kind.length > 0 ? Format.fill(OpenWith.WORDS.alwaysKind, root.kind)
|
|
490
|
+
: "Always use this application for this file type"
|
|
491
|
+
color: Theme.color.foreground
|
|
492
|
+
font.family: Theme.font.family
|
|
493
|
+
font.pixelSize: Theme.font.body
|
|
494
|
+
textFormat: Text.PlainText
|
|
495
|
+
wrapMode: Text.Wrap
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
TapHandler {
|
|
499
|
+
acceptedButtons: Qt.LeftButton
|
|
500
|
+
gesturePolicy: TapHandler.ReleaseWithinBounds
|
|
501
|
+
onTapped: { root.focusPart = 2; root.always = !root.always; alwaysBox.forceActiveFocus() }
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
Text {
|
|
506
|
+
id: consequence
|
|
507
|
+
width: parent.width
|
|
508
|
+
leftPadding: Theme.spacing.rowPaddingX + box.width + Theme.spacing.gap
|
|
509
|
+
rightPadding: Theme.spacing.rowPaddingX
|
|
510
|
+
bottomPadding: Theme.spacing.gap
|
|
511
|
+
// The board's one line: the box above already says what is written.
|
|
512
|
+
text: "Undo does not reverse this; change it here again."
|
|
513
|
+
color: Theme.color.muted
|
|
514
|
+
font.family: Theme.font.family
|
|
515
|
+
font.pixelSize: Theme.font.caption
|
|
516
|
+
textFormat: Text.PlainText
|
|
517
|
+
wrapMode: Text.Wrap
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// The status slot is always laid out, two caption lines tall (the network slot's rowHeight) inside its padding, so rest, busy and a short error keep one card height; only a longer error grows it.
|
|
521
|
+
Text {
|
|
522
|
+
width: parent.width
|
|
523
|
+
leftPadding: Theme.spacing.rowPaddingX
|
|
524
|
+
rightPadding: Theme.spacing.rowPaddingX
|
|
525
|
+
bottomPadding: Theme.spacing.gap
|
|
526
|
+
height: Math.max(Theme.rowHeight + topPadding + bottomPadding, implicitHeight)
|
|
527
|
+
text: root.committing ? "Opening…" : root.errorText
|
|
528
|
+
color: root.committing ? Theme.color.muted : Theme.color.errorOnSurface
|
|
529
|
+
font.family: Theme.font.family
|
|
530
|
+
font.pixelSize: Theme.font.caption
|
|
531
|
+
textFormat: Text.PlainText
|
|
532
|
+
wrapMode: Text.Wrap
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
buttons: Item {
|
|
537
|
+
width: parent.width
|
|
538
|
+
height: Math.max(cancelButton.implicitHeight, openButton.implicitHeight)
|
|
539
|
+
|
|
540
|
+
Row {
|
|
541
|
+
anchors.right: parent.right
|
|
542
|
+
anchors.rightMargin: Theme.spacing.rowPaddingX
|
|
543
|
+
spacing: Theme.spacing.gap
|
|
544
|
+
|
|
545
|
+
Flea.DialogButton {
|
|
546
|
+
id: cancelButton
|
|
547
|
+
label: "Cancel"
|
|
548
|
+
focused: root.focusPart === 3
|
|
549
|
+
activeFocusOnTab: true
|
|
550
|
+
Keys.forwardTo: [keys]
|
|
551
|
+
onActivated: root.close()
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
Flea.DialogButton {
|
|
555
|
+
id: openButton
|
|
556
|
+
label: "Open"
|
|
557
|
+
primary: true
|
|
558
|
+
focused: root.focusPart === 4
|
|
559
|
+
available: root.canSubmit
|
|
560
|
+
activeFocusOnTab: true
|
|
561
|
+
Keys.forwardTo: [keys]
|
|
562
|
+
onActivated: root.commit()
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
Item {
|
|
570
|
+
id: keys
|
|
571
|
+
anchors.fill: parent
|
|
572
|
+
|
|
573
|
+
// Rule 8's whole map. A printable key nobody above claimed is search text, whatever holds focus.
|
|
574
|
+
Keys.onPressed: function (event) {
|
|
575
|
+
event.accepted = true
|
|
576
|
+
if (event.key === Qt.Key_Escape) { root.close(); return }
|
|
577
|
+
if (event.key === Qt.Key_Tab || event.key === Qt.Key_Backtab) {
|
|
578
|
+
root.stepFocus(event.key === Qt.Key_Backtab || (event.modifiers & Qt.ShiftModifier) !== 0)
|
|
579
|
+
return
|
|
580
|
+
}
|
|
581
|
+
if (root.busy) return
|
|
582
|
+
// j and k move only while the search line is both empty and unfocused: from the field
|
|
583
|
+
// they are the first letters of kate, krita and joplin, and stealing them lost the query.
|
|
584
|
+
var quiet = field.text.length === 0 && root.focusPart !== 0
|
|
585
|
+
if (event.key === Qt.Key_Down || (quiet && event.key === Qt.Key_J)) { root.moveCursor(1); return }
|
|
586
|
+
if (event.key === Qt.Key_Up || (quiet && event.key === Qt.Key_K)) { root.moveCursor(-1); return }
|
|
587
|
+
if (event.key === Qt.Key_PageDown) { root.moveCursor(root.viewportRows); return }
|
|
588
|
+
if (event.key === Qt.Key_PageUp) { root.moveCursor(-root.viewportRows); return }
|
|
589
|
+
// Backspace edits the search from anywhere, the mirror of typing reaching it from anywhere.
|
|
590
|
+
if (event.key === Qt.Key_Backspace && !field.activeFocus) {
|
|
591
|
+
if (field.text.length > 0) { root.focusPart = 0; field.forceActiveFocus(); field.remove(field.length - 1, field.length) }
|
|
592
|
+
return
|
|
593
|
+
}
|
|
594
|
+
if (event.key === Qt.Key_Space) {
|
|
595
|
+
// Space answers the control that holds focus; only from the list, the box itself or an
|
|
596
|
+
// empty search line is it rule 7's toggle rather than a character.
|
|
597
|
+
if (root.focusPart === 3) { root.close(); return }
|
|
598
|
+
if (root.focusPart === 4) { root.commit(); return }
|
|
599
|
+
if (root.focusPart !== 0 || field.text.length === 0) { root.always = !root.always; return }
|
|
600
|
+
}
|
|
601
|
+
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
|
602
|
+
if (root.focusPart === 3) root.close()
|
|
603
|
+
else if (root.focusPart === 2) root.always = !root.always
|
|
604
|
+
else root.commit()
|
|
605
|
+
return
|
|
606
|
+
}
|
|
607
|
+
if (Input.isPrintable(event.text.charAt(0)) && !(event.modifiers & Qt.ControlModifier)) {
|
|
608
|
+
if (!field.activeFocus) { root.typeIntoSearch(event.text); return }
|
|
609
|
+
}
|
|
610
|
+
event.accepted = false
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|