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.
Files changed (625) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +478 -2
  3. package/THIRD-PARTY-NOTICES.md +29 -0
  4. package/demos/App.java +5 -0
  5. package/demos/Dockerfile +4 -0
  6. package/demos/Main.kt +3 -0
  7. package/demos/Program.cs +1 -0
  8. package/demos/README.md +12 -0
  9. package/demos/app.dart +3 -0
  10. package/demos/app.deb +0 -0
  11. package/demos/app.js +1 -0
  12. package/demos/backup.tar +0 -0
  13. package/demos/budget.xlsx +0 -0
  14. package/demos/build.sh +2 -0
  15. package/demos/bundle.zip +0 -0
  16. package/demos/clip.mp4 +0 -0
  17. package/demos/data.sqlite +0 -0
  18. package/demos/disk.iso +0 -0
  19. package/demos/engine.cpp +5 -0
  20. package/demos/firmware.bin +0 -0
  21. package/demos/flake.nix +4 -0
  22. package/demos/folder/inside.txt +1 -0
  23. package/demos/font.ttf +0 -0
  24. package/demos/index.html +5 -0
  25. package/demos/index.php +2 -0
  26. package/demos/init.lua +1 -0
  27. package/demos/letter.docx +0 -0
  28. package/demos/lib.rs +3 -0
  29. package/demos/main.c +6 -0
  30. package/demos/main.h +3 -0
  31. package/demos/math-and-diagrams.md +200 -0
  32. package/demos/notes.tar.gz +0 -0
  33. package/demos/notes.txt +3 -0
  34. package/demos/photo.png +0 -0
  35. package/demos/program +2 -0
  36. package/demos/report.pdf +32 -0
  37. package/demos/script.py +1 -0
  38. package/demos/server.go +7 -0
  39. package/demos/settings.json +4 -0
  40. package/demos/slides.pptx +0 -0
  41. package/demos/song.mp3 +0 -0
  42. package/demos/style.css +4 -0
  43. package/demos/tool.rb +1 -0
  44. package/demos/types.ts +2 -0
  45. package/docs/pele.md +23 -0
  46. package/docs/protocol.md +3420 -0
  47. package/docs/temml.md +63 -0
  48. package/index.js +107 -0
  49. package/package.json +34 -4
  50. package/src/archive.js +402 -0
  51. package/src/archiveops.js +697 -0
  52. package/src/backend.js +369 -0
  53. package/src/bulkrename.js +95 -0
  54. package/src/clip-host.js +76 -0
  55. package/src/clip.js +462 -0
  56. package/src/code.js +168 -0
  57. package/src/compare.js +74 -0
  58. package/src/create.js +128 -0
  59. package/src/dirsize.js +147 -0
  60. package/src/figure-svg.js +530 -0
  61. package/src/figure-thread.js +23 -0
  62. package/src/figure.js +132 -0
  63. package/src/find.js +55 -0
  64. package/src/flea.js +39 -0
  65. package/src/fsinfo.js +39 -0
  66. package/src/highlight.js +141 -0
  67. package/src/html.js +52 -0
  68. package/src/kinds.js +89 -0
  69. package/src/listing.js +130 -0
  70. package/src/markdown-html.js +317 -0
  71. package/src/mathml.js +186 -0
  72. package/src/menu.js +180 -0
  73. package/src/meta.js +129 -0
  74. package/src/office.js +810 -0
  75. package/src/order.js +100 -0
  76. package/src/peek.js +49 -0
  77. package/src/pele-wrapper.js +695 -0
  78. package/src/permissions.js +180 -0
  79. package/src/places.js +313 -0
  80. package/src/preview-language.js +10 -0
  81. package/src/transfer.js +669 -0
  82. package/src/trash-record.js +41 -0
  83. package/src/trash.js +210 -0
  84. package/src/trashbrowse.js +326 -0
  85. package/src/uistate.js +393 -0
  86. package/src/uistore.js +168 -0
  87. package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
  88. package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
  89. package/src/vendor/LICENSES/MIT-katex.txt +21 -0
  90. package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
  91. package/src/vendor/LICENSES/MIT-pele.txt +40 -0
  92. package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
  93. package/src/vendor/LICENSES/MIT-temml.txt +21 -0
  94. package/src/vendor/pele.js +145 -0
  95. package/src/vendor/temml.mjs +14708 -0
  96. package/src/watch.js +98 -0
  97. package/src/wayland/client.js +109 -0
  98. package/src/wayland/protocol.js +55 -0
  99. package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
  100. package/src/wayland/protocols/wayland.xml +3248 -0
  101. package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
  102. package/src/wayland/resource-io.js +6 -0
  103. package/src/wayland/socket-discovery.js +26 -0
  104. package/src/wayland/transport-posix.js +120 -0
  105. package/src/wayland/transport-win32.js +11 -0
  106. package/src/wayland/transport.js +3 -0
  107. package/src/wayland/win32-resources.js +80 -0
  108. package/src/wayland/win32-wire.js +62 -0
  109. package/test/archive.test.js +80 -0
  110. package/test/bench-markdown-scroll.mjs +190 -0
  111. package/test/clip-host.test.js +113 -0
  112. package/test/code-preview.test.js +35 -0
  113. package/test/compare-ui-paths.test.js +24 -0
  114. package/test/compare.test.js +54 -0
  115. package/test/delete-trash.test.js +67 -0
  116. package/test/dirsize.test.js +138 -0
  117. package/test/file-ops.test.js +241 -0
  118. package/test/find-contents.test.js +161 -0
  119. package/test/find-input.test.js +66 -0
  120. package/test/fixtures/pele-parity.json +1006 -0
  121. package/test/highlight-launcher.test.js +35 -0
  122. package/test/html-preview.test.js +22 -0
  123. package/test/input.test.js +15 -0
  124. package/test/keymap.test.js +26 -0
  125. package/test/language-icons.test.js +36 -0
  126. package/test/launcher.test.js +51 -0
  127. package/test/manual-code-scroll.mjs +28 -0
  128. package/test/manual-column-scroll.mjs +24 -0
  129. package/test/manual-compare-ui.mjs +20 -0
  130. package/test/manual-find-status.mjs +37 -0
  131. package/test/manual-html-security.mjs +23 -0
  132. package/test/manual-html-ui.mjs +30 -0
  133. package/test/manual-syntax-preview.mjs +26 -0
  134. package/test/manual-trash-ui.mjs +86 -0
  135. package/test/markdown-diagrams.test.js +93 -0
  136. package/test/markdown-html.test.js +105 -0
  137. package/test/mathml.test.js +92 -0
  138. package/test/menu-transfer.test.js +57 -0
  139. package/test/office-preview.test.js +154 -0
  140. package/test/pele-parity.test.js +28 -0
  141. package/test/places.test.js +134 -0
  142. package/test/preview-keys.test.js +60 -0
  143. package/test/preview-language.test.js +22 -0
  144. package/test/status-filename.test.js +20 -0
  145. package/test/transfer-replace-merge.test.js +187 -0
  146. package/test/trash-address.test.js +23 -0
  147. package/test/trash-view.test.js +37 -0
  148. package/test/trashbrowse.test.js +135 -0
  149. package/ui/AboutFacts.qml +78 -0
  150. package/ui/ArchiveCards.qml +68 -0
  151. package/ui/ArchiveCompressDialog.qml +378 -0
  152. package/ui/ArchivePasswordDialog.qml +257 -0
  153. package/ui/Backend.qml +771 -0
  154. package/ui/BulkOldNames.qml +47 -0
  155. package/ui/BulkRenameDialog.qml +380 -0
  156. package/ui/CardFrame.qml +67 -0
  157. package/ui/CardScroll.qml +79 -0
  158. package/ui/CheckBox.qml +73 -0
  159. package/ui/ChromeBar.qml +360 -0
  160. package/ui/ChromeButton.qml +131 -0
  161. package/ui/ChromeModes.qml +43 -0
  162. package/ui/CodeLines.qml +256 -0
  163. package/ui/CodeRefusal.qml +52 -0
  164. package/ui/CollideConfirm.qml +147 -0
  165. package/ui/CollideHost.qml +167 -0
  166. package/ui/ColumnPane.qml +523 -0
  167. package/ui/ColumnRow.qml +380 -0
  168. package/ui/ColumnsArea.qml +594 -0
  169. package/ui/ColumnsLanding.qml +147 -0
  170. package/ui/CompareView.qml +321 -0
  171. package/ui/ContextMenu.qml +743 -0
  172. package/ui/ConvertDialog.qml +456 -0
  173. package/ui/CountedWorker.qml +7 -0
  174. package/ui/Crumb.qml +64 -0
  175. package/ui/CrumbDrop.qml +25 -0
  176. package/ui/CsvTable.qml +394 -0
  177. package/ui/CursorMark.qml +41 -0
  178. package/ui/DefaultClaim.qml +130 -0
  179. package/ui/DeviceLock.qml +47 -0
  180. package/ui/DeviceMounts.qml +540 -0
  181. package/ui/DialogButton.qml +150 -0
  182. package/ui/DialogField.qml +147 -0
  183. package/ui/DialogHeader.qml +31 -0
  184. package/ui/DialogScrim.qml +20 -0
  185. package/ui/DialogTitle.qml +37 -0
  186. package/ui/Divider.qml +9 -0
  187. package/ui/DropInto.qml +126 -0
  188. package/ui/DropTarget.qml +35 -0
  189. package/ui/DropboxMark.qml +60 -0
  190. package/ui/EmptyState.qml +150 -0
  191. package/ui/EscapeHint.qml +11 -0
  192. package/ui/FactsTable.qml +54 -0
  193. package/ui/FastScrollHandler.qml +476 -0
  194. package/ui/FatNamesConfirm.qml +157 -0
  195. package/ui/Favourites.qml +143 -0
  196. package/ui/FigureService.qml +120 -0
  197. package/ui/FileDrag.qml +267 -0
  198. package/ui/FilterStrip.qml +133 -0
  199. package/ui/FitMetrics.qml +22 -0
  200. package/ui/FlashDriveRows.qml +137 -0
  201. package/ui/FlashHost.qml +72 -0
  202. package/ui/FlashImageRow.qml +104 -0
  203. package/ui/FlashRunner.qml +119 -0
  204. package/ui/FlashStepRow.qml +172 -0
  205. package/ui/FlashStrip.qml +38 -0
  206. package/ui/FlashView.qml +397 -0
  207. package/ui/FleaMark.qml +88 -0
  208. package/ui/FlyoutFade.qml +23 -0
  209. package/ui/FontPane.qml +170 -0
  210. package/ui/Glass.qml +114 -0
  211. package/ui/GlassTagger.qml +59 -0
  212. package/ui/Glyph.qml +64 -0
  213. package/ui/GlyphSolid.qml +22 -0
  214. package/ui/GridArea.qml +664 -0
  215. package/ui/GridTile.qml +325 -0
  216. package/ui/GvfsBridge.qml +164 -0
  217. package/ui/Header.qml +433 -0
  218. package/ui/HoverTimers.qml +39 -0
  219. package/ui/HtmlClip.qml +30 -0
  220. package/ui/HtmlPane.qml +63 -0
  221. package/ui/HyprlandMark.qml +45 -0
  222. package/ui/Ipc.qml +1005 -0
  223. package/ui/IpcControls.qml +7 -0
  224. package/ui/IpcMenuState.qml +48 -0
  225. package/ui/IpcPreviewState.qml +185 -0
  226. package/ui/JumpPath.qml +51 -0
  227. package/ui/KeymapSheet.qml +561 -0
  228. package/ui/KeymapSheetResult.qml +89 -0
  229. package/ui/KindStack.qml +40 -0
  230. package/ui/LangMark.qml +51 -0
  231. package/ui/LangMarkLoader.qml +26 -0
  232. package/ui/List.qml +480 -0
  233. package/ui/LoadingState.qml +54 -0
  234. package/ui/LocalSend.qml +56 -0
  235. package/ui/LocalSendMark.qml +73 -0
  236. package/ui/MarkdownBlockView.qml +311 -0
  237. package/ui/MarkdownBlocks.qml +35 -0
  238. package/ui/MarkdownFigure.qml +254 -0
  239. package/ui/MarkdownImages.qml +72 -0
  240. package/ui/MarkdownList.qml +81 -0
  241. package/ui/MarkdownMathsText.qml +97 -0
  242. package/ui/MarkdownPane.qml +83 -0
  243. package/ui/MarkdownPictures.qml +41 -0
  244. package/ui/MarkdownQuote.qml +52 -0
  245. package/ui/MarkdownRemote.qml +82 -0
  246. package/ui/MarkdownSource.qml +155 -0
  247. package/ui/MarkdownTable.qml +222 -0
  248. package/ui/MarkdownTableScroll.qml +64 -0
  249. package/ui/MarkdownTableWheel.qml +126 -0
  250. package/ui/MarkdownText.qml +87 -0
  251. package/ui/MarkdownWorker.js +132 -0
  252. package/ui/MatchText.qml +99 -0
  253. package/ui/MediaSession.qml +38 -0
  254. package/ui/MediaSound.qml +26 -0
  255. package/ui/MediaStrip.qml +191 -0
  256. package/ui/MediaTrack.qml +36 -0
  257. package/ui/MediaVolume.qml +54 -0
  258. package/ui/MenuActionDialog.qml +396 -0
  259. package/ui/MenuEdgeFade.qml +24 -0
  260. package/ui/MenuHost.qml +227 -0
  261. package/ui/MenuRow.qml +351 -0
  262. package/ui/MountListing.qml +100 -0
  263. package/ui/NetworkDialog.qml +435 -0
  264. package/ui/NetworkForm.qml +426 -0
  265. package/ui/NetworkMounts.qml +913 -0
  266. package/ui/NetworkPlaces.qml +127 -0
  267. package/ui/OpenWithDialog.qml +613 -0
  268. package/ui/Opener.qml +115 -0
  269. package/ui/Pane.qml +1296 -0
  270. package/ui/PaneMenuActions.qml +527 -0
  271. package/ui/PanePath.qml +90 -0
  272. package/ui/PaneRail.qml +239 -0
  273. package/ui/PaneStates.qml +88 -0
  274. package/ui/PaneSwap.qml +339 -0
  275. package/ui/PaneWire.qml +605 -0
  276. package/ui/ParkedWait.qml +9 -0
  277. package/ui/PathEntry.qml +186 -0
  278. package/ui/PathJump.qml +400 -0
  279. package/ui/PdfViewer.qml +297 -0
  280. package/ui/PermissionsDialog.qml +658 -0
  281. package/ui/PermissionsHeadings.qml +31 -0
  282. package/ui/PhoneMounts.qml +67 -0
  283. package/ui/PickerAnswers.qml +75 -0
  284. package/ui/PickerBox.qml +26 -0
  285. package/ui/PickerChrome.qml +295 -0
  286. package/ui/PickerFilter.qml +97 -0
  287. package/ui/PickerGrid.qml +308 -0
  288. package/ui/PickerHeader.qml +28 -0
  289. package/ui/PickerLifecycle.qml +27 -0
  290. package/ui/PickerList.qml +218 -0
  291. package/ui/PickerListing.qml +149 -0
  292. package/ui/PickerPathBar.qml +127 -0
  293. package/ui/PickerPlaces.qml +189 -0
  294. package/ui/PickerRecent.qml +92 -0
  295. package/ui/PickerSave.qml +101 -0
  296. package/ui/PickerSelection.qml +155 -0
  297. package/ui/PickerWindow.qml +846 -0
  298. package/ui/PowerSectorsReader.qml +10 -0
  299. package/ui/PrebuildDriver.qml +146 -0
  300. package/ui/Preview.qml +1004 -0
  301. package/ui/PreviewAnimation.qml +24 -0
  302. package/ui/PreviewArchive.qml +66 -0
  303. package/ui/PreviewColumn.qml +551 -0
  304. package/ui/PreviewEdge.qml +63 -0
  305. package/ui/PreviewFacts.qml +30 -0
  306. package/ui/PreviewFactsLine.qml +34 -0
  307. package/ui/PreviewHtml.qml +233 -0
  308. package/ui/PreviewImage.qml +253 -0
  309. package/ui/PreviewImagePan.qml +13 -0
  310. package/ui/PreviewImageSharp.qml +32 -0
  311. package/ui/PreviewLines.qml +106 -0
  312. package/ui/PreviewMarkdown.qml +706 -0
  313. package/ui/PreviewMedia.qml +250 -0
  314. package/ui/PreviewPdf.qml +482 -0
  315. package/ui/PreviewScroll.qml +201 -0
  316. package/ui/PreviewSwap.qml +335 -0
  317. package/ui/PreviewText.qml +149 -0
  318. package/ui/ProtocolChip.qml +18 -0
  319. package/ui/QuickLookArchive.qml +38 -0
  320. package/ui/QuickLookBar.qml +103 -0
  321. package/ui/QuickLookPrepare.qml +355 -0
  322. package/ui/QuickLookSwap.qml +10 -0
  323. package/ui/QuickLookWarm.qml +65 -0
  324. package/ui/RailDrop.qml +155 -0
  325. package/ui/RailHeading.qml +19 -0
  326. package/ui/RailPlaces.qml +38 -0
  327. package/ui/RailTrashRow.qml +67 -0
  328. package/ui/RenameField.qml +353 -0
  329. package/ui/RendererRetry.qml +11 -0
  330. package/ui/ResizeHandle.qml +52 -0
  331. package/ui/Reveal.qml +54 -0
  332. package/ui/Row.qml +476 -0
  333. package/ui/RowDrag.qml +213 -0
  334. package/ui/RowDropTarget.qml +27 -0
  335. package/ui/RunCard.qml +286 -0
  336. package/ui/Scripts.qml +65 -0
  337. package/ui/SearchStrip.qml +232 -0
  338. package/ui/SelectionBand.qml +140 -0
  339. package/ui/SelectionPreview.qml +370 -0
  340. package/ui/SettingsFavourite.qml +122 -0
  341. package/ui/SettingsGroup.qml +96 -0
  342. package/ui/SettingsHint.qml +12 -0
  343. package/ui/SettingsMetrics.qml +29 -0
  344. package/ui/SettingsPane.qml +178 -0
  345. package/ui/SettingsPanel.qml +547 -0
  346. package/ui/SettingsRail.qml +128 -0
  347. package/ui/SettingsRow.qml +409 -0
  348. package/ui/SettingsRuler.qml +85 -0
  349. package/ui/SettingsSegment.qml +85 -0
  350. package/ui/ShareBrowser.qml +113 -0
  351. package/ui/ShareLink.qml +67 -0
  352. package/ui/ShelfPins.qml +101 -0
  353. package/ui/Sidebar.qml +732 -0
  354. package/ui/SidebarRow.qml +358 -0
  355. package/ui/Spinner.qml +60 -0
  356. package/ui/StableModel.qml +89 -0
  357. package/ui/StateMessage.qml +84 -0
  358. package/ui/StatusBar.qml +512 -0
  359. package/ui/StatusFileName.qml +27 -0
  360. package/ui/TabBar.qml +673 -0
  361. package/ui/TabDragGeometry.qml +60 -0
  362. package/ui/TagMenuMark.qml +52 -0
  363. package/ui/TagRailSection.qml +53 -0
  364. package/ui/TagSlot.qml +40 -0
  365. package/ui/TagState.qml +150 -0
  366. package/ui/TagSwatch.qml +28 -0
  367. package/ui/Taildrop.qml +86 -0
  368. package/ui/TailscaleMark.qml +50 -0
  369. package/ui/Theme.qml +460 -0
  370. package/ui/ThemeColors.qml +43 -0
  371. package/ui/TransferCard.qml +239 -0
  372. package/ui/TrashConfirm.qml +129 -0
  373. package/ui/TrashDropHandler.qml +11 -0
  374. package/ui/TrashHost.qml +202 -0
  375. package/ui/TrashMonitor.qml +30 -0
  376. package/ui/TrashToolbar.qml +19 -0
  377. package/ui/TrashView.qml +492 -0
  378. package/ui/UnlockDialog.qml +450 -0
  379. package/ui/UnlockHost.qml +206 -0
  380. package/ui/UpdateCheck.qml +97 -0
  381. package/ui/UserDirs.qml +25 -0
  382. package/ui/ViewState.qml +565 -0
  383. package/ui/ViewportScrollBar.qml +195 -0
  384. package/ui/ViewportScrollBars.qml +25 -0
  385. package/ui/WebPreview.qml +33 -0
  386. package/ui/WebPreviewView.qml +26 -0
  387. package/ui/WindowBody.qml +827 -0
  388. package/ui/WindowDrag.qml +35 -0
  389. package/ui/boot/Commons/AudioNodes.qml +50 -0
  390. package/ui/boot/Commons/AudioNodesModel.js +96 -0
  391. package/ui/boot/Commons/Border.qml +243 -0
  392. package/ui/boot/Commons/BorderGeometry.js +373 -0
  393. package/ui/boot/Commons/Color.qml +258 -0
  394. package/ui/boot/Commons/I18n.qml +118 -0
  395. package/ui/boot/Commons/InputDevices.qml +112 -0
  396. package/ui/boot/Commons/InputMethodState.qml +38 -0
  397. package/ui/boot/Commons/IpcRegistry.qml +77 -0
  398. package/ui/boot/Commons/Numbers.js +19 -0
  399. package/ui/boot/Commons/Plural.js +91 -0
  400. package/ui/boot/Commons/ShellIpc.qml +12 -0
  401. package/ui/boot/Commons/Style.qml +561 -0
  402. package/ui/boot/Commons/Translations.qml +100 -0
  403. package/ui/boot/Commons/UntypedInput.qml +152 -0
  404. package/ui/boot/Commons/Util.qml +188 -0
  405. package/ui/boot/Commons/qmldir +13 -0
  406. package/ui/boot/LICENSE-omarchy +20 -0
  407. package/ui/boot/Ui/BackgroundMedia.qml +49 -0
  408. package/ui/boot/Ui/BarIconButton.qml +106 -0
  409. package/ui/boot/Ui/BarIconContent.qml +38 -0
  410. package/ui/boot/Ui/BarIndicator.qml +53 -0
  411. package/ui/boot/Ui/BarWidget.qml +50 -0
  412. package/ui/boot/Ui/BorderOverlay.qml +54 -0
  413. package/ui/boot/Ui/BorderSurface.qml +40 -0
  414. package/ui/boot/Ui/Button.qml +224 -0
  415. package/ui/boot/Ui/ButtonGroup.qml +131 -0
  416. package/ui/boot/Ui/ConfirmDialog.qml +134 -0
  417. package/ui/boot/Ui/CursorSurface.qml +42 -0
  418. package/ui/boot/Ui/Dropdown.qml +245 -0
  419. package/ui/boot/Ui/FilterInput.qml +26 -0
  420. package/ui/boot/Ui/IconContentBounds.qml +141 -0
  421. package/ui/boot/Ui/KeyboardPanel.qml +453 -0
  422. package/ui/boot/Ui/MultiSelect.qml +624 -0
  423. package/ui/boot/Ui/NumberField.qml +86 -0
  424. package/ui/boot/Ui/OpticalGlyph.qml +68 -0
  425. package/ui/boot/Ui/OverlayWindow.qml +102 -0
  426. package/ui/boot/Ui/Panel.qml +60 -0
  427. package/ui/boot/Ui/PanelActionButton.qml +105 -0
  428. package/ui/boot/Ui/PanelController.qml +16 -0
  429. package/ui/boot/Ui/PanelHero.qml +112 -0
  430. package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
  431. package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
  432. package/ui/boot/Ui/PanelSeparator.qml +19 -0
  433. package/ui/boot/Ui/PanelSlider.qml +156 -0
  434. package/ui/boot/Ui/PanelToolTip.qml +50 -0
  435. package/ui/boot/Ui/PluginBarApi.qml +89 -0
  436. package/ui/boot/Ui/PointerMoveGate.qml +54 -0
  437. package/ui/boot/Ui/PopupCard.qml +181 -0
  438. package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
  439. package/ui/boot/Ui/SearchableDropdown.qml +354 -0
  440. package/ui/boot/Ui/SizedImage.qml +125 -0
  441. package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
  442. package/ui/boot/Ui/TextField.qml +58 -0
  443. package/ui/boot/Ui/Toggle.qml +118 -0
  444. package/ui/boot/Ui/ToggleSwitch.qml +115 -0
  445. package/ui/boot/Ui/WidgetButton.qml +172 -0
  446. package/ui/boot/Ui/qmldir +41 -0
  447. package/ui/boot/fleatab.qml +50 -0
  448. package/ui/boot/picker.qml +39 -0
  449. package/ui/boot/shell.qml +122 -0
  450. package/ui/boot/tabtearoff.qml +51 -0
  451. package/ui/js/Anchor.js +379 -0
  452. package/ui/js/AnchorHold.js +162 -0
  453. package/ui/js/Archive.js +157 -0
  454. package/ui/js/ArchiveCard.js +44 -0
  455. package/ui/js/ArchiveOps.js +44 -0
  456. package/ui/js/BackReturn.js +118 -0
  457. package/ui/js/BulkRename.js +100 -0
  458. package/ui/js/Buttons.js +54 -0
  459. package/ui/js/ChromeKeys.js +116 -0
  460. package/ui/js/ClipMarks.js +73 -0
  461. package/ui/js/ClipSelection.js +67 -0
  462. package/ui/js/Clipboard.js +179 -0
  463. package/ui/js/Cloud.js +97 -0
  464. package/ui/js/CodeRuns.js +72 -0
  465. package/ui/js/Collide.js +212 -0
  466. package/ui/js/ColumnFit.js +28 -0
  467. package/ui/js/ColumnMenu.js +111 -0
  468. package/ui/js/Columns.js +298 -0
  469. package/ui/js/ColumnsCarry.js +103 -0
  470. package/ui/js/Compare.js +74 -0
  471. package/ui/js/Contrast.js +157 -0
  472. package/ui/js/ControlReader.js +42 -0
  473. package/ui/js/Convert.js +52 -0
  474. package/ui/js/CopyAs.js +52 -0
  475. package/ui/js/Crumbs.js +178 -0
  476. package/ui/js/Csv.js +231 -0
  477. package/ui/js/Density.js +44 -0
  478. package/ui/js/Devices.js +440 -0
  479. package/ui/js/DirSizes.js +180 -0
  480. package/ui/js/Drag.js +364 -0
  481. package/ui/js/DragOut.js +166 -0
  482. package/ui/js/DropDev.js +52 -0
  483. package/ui/js/Dropbox.js +41 -0
  484. package/ui/js/Eject.js +217 -0
  485. package/ui/js/Errors.js +188 -0
  486. package/ui/js/ExtThumbs.js +115 -0
  487. package/ui/js/Facts.js +402 -0
  488. package/ui/js/FigureDate.js +14 -0
  489. package/ui/js/Filter.js +285 -0
  490. package/ui/js/Find.js +46 -0
  491. package/ui/js/Flash.js +184 -0
  492. package/ui/js/FlashCard.js +79 -0
  493. package/ui/js/FlashEndings.js +125 -0
  494. package/ui/js/FlashPane.js +116 -0
  495. package/ui/js/FleaBin.js +12 -0
  496. package/ui/js/Focus.js +502 -0
  497. package/ui/js/FolderSorts.js +108 -0
  498. package/ui/js/FolderViews.js +44 -0
  499. package/ui/js/Format.js +305 -0
  500. package/ui/js/Fuzzy.js +141 -0
  501. package/ui/js/GlassTag.js +72 -0
  502. package/ui/js/Grid.js +33 -0
  503. package/ui/js/GridGeometry.js +90 -0
  504. package/ui/js/GridNames.js +153 -0
  505. package/ui/js/GvfsBridge.js +200 -0
  506. package/ui/js/HostClipboard.js +29 -0
  507. package/ui/js/Icons.js +218 -0
  508. package/ui/js/Input.js +50 -0
  509. package/ui/js/Jump.js +200 -0
  510. package/ui/js/KeyName.js +64 -0
  511. package/ui/js/Keymap.js +401 -0
  512. package/ui/js/Kinds.js +164 -0
  513. package/ui/js/LICENSES/ISC-lucide.txt +43 -0
  514. package/ui/js/LangMarkPaths.js +47 -0
  515. package/ui/js/LangMarks.js +120 -0
  516. package/ui/js/Lists.js +11 -0
  517. package/ui/js/LocalSend.js +39 -0
  518. package/ui/js/LockedMenu.js +63 -0
  519. package/ui/js/MakeDefault.js +186 -0
  520. package/ui/js/MarkBox.js +7 -0
  521. package/ui/js/Markdown.js +119 -0
  522. package/ui/js/MarkdownLists.js +86 -0
  523. package/ui/js/MarkdownMaths.js +58 -0
  524. package/ui/js/MarkdownPictures.js +32 -0
  525. package/ui/js/MarkdownPrepared.js +139 -0
  526. package/ui/js/MarkdownTableFit.js +34 -0
  527. package/ui/js/Marks.js +148 -0
  528. package/ui/js/Marquee.js +96 -0
  529. package/ui/js/Match.js +93 -0
  530. package/ui/js/Material.js +109 -0
  531. package/ui/js/MdBlocks.js +437 -0
  532. package/ui/js/MdBreak.js +71 -0
  533. package/ui/js/MdChunks.js +70 -0
  534. package/ui/js/MdContainer.js +137 -0
  535. package/ui/js/MdDocument.js +337 -0
  536. package/ui/js/MdEmph.js +97 -0
  537. package/ui/js/MdEntity.js +108 -0
  538. package/ui/js/MdEntityTable.js +223 -0
  539. package/ui/js/MdEscape.js +59 -0
  540. package/ui/js/MdFront.js +37 -0
  541. package/ui/js/MdHold.js +32 -0
  542. package/ui/js/MdHtml.js +307 -0
  543. package/ui/js/MdHtmlBlock.js +290 -0
  544. package/ui/js/MdHtmlHeading.js +53 -0
  545. package/ui/js/MdHtmlImage.js +179 -0
  546. package/ui/js/MdInline.js +154 -0
  547. package/ui/js/MdItems.js +212 -0
  548. package/ui/js/MdLeaf.js +309 -0
  549. package/ui/js/MdLink.js +196 -0
  550. package/ui/js/MdMath.js +67 -0
  551. package/ui/js/MdParagraphs.js +138 -0
  552. package/ui/js/MdRefs.js +232 -0
  553. package/ui/js/MdResolve.js +226 -0
  554. package/ui/js/MdRun.js +300 -0
  555. package/ui/js/MdUrl.js +226 -0
  556. package/ui/js/Menu.js +514 -0
  557. package/ui/js/MenuContext.js +85 -0
  558. package/ui/js/MenuFit.js +13 -0
  559. package/ui/js/MenuRefresh.js +74 -0
  560. package/ui/js/MenuWheel.js +35 -0
  561. package/ui/js/Messages.js +186 -0
  562. package/ui/js/Motion.js +16 -0
  563. package/ui/js/Mounts.js +320 -0
  564. package/ui/js/MouseNav.js +13 -0
  565. package/ui/js/Nav.js +329 -0
  566. package/ui/js/NetFs.js +26 -0
  567. package/ui/js/OpenWith.js +83 -0
  568. package/ui/js/Ops.js +585 -0
  569. package/ui/js/Palette.js +33 -0
  570. package/ui/js/PathBar.js +260 -0
  571. package/ui/js/Permissions.js +179 -0
  572. package/ui/js/Phones.js +112 -0
  573. package/ui/js/Picker.js +353 -0
  574. package/ui/js/PlaceMenu.js +96 -0
  575. package/ui/js/Places.js +265 -0
  576. package/ui/js/PreviewAsk.js +21 -0
  577. package/ui/js/PreviewKeys.js +155 -0
  578. package/ui/js/PreviewSettle.js +29 -0
  579. package/ui/js/PreviewSwap.js +101 -0
  580. package/ui/js/PropertyFacts.js +144 -0
  581. package/ui/js/Protocols.js +296 -0
  582. package/ui/js/QuickLookKinds.js +27 -0
  583. package/ui/js/QuickLookRect.js +24 -0
  584. package/ui/js/RailDrop.js +51 -0
  585. package/ui/js/RailKeys.js +87 -0
  586. package/ui/js/RailMenu.js +133 -0
  587. package/ui/js/Recent.js +135 -0
  588. package/ui/js/RecentMode.js +156 -0
  589. package/ui/js/Reload.js +60 -0
  590. package/ui/js/Renderer.js +9 -0
  591. package/ui/js/RunFile.js +143 -0
  592. package/ui/js/Scripts.js +28 -0
  593. package/ui/js/Scroll.js +304 -0
  594. package/ui/js/ScrollOff.js +69 -0
  595. package/ui/js/Search.js +478 -0
  596. package/ui/js/Selection.js +97 -0
  597. package/ui/js/Settings.js +476 -0
  598. package/ui/js/SettingsAbout.js +97 -0
  599. package/ui/js/SettingsShelf.js +52 -0
  600. package/ui/js/SheetKeys.js +42 -0
  601. package/ui/js/SheetQuery.js +281 -0
  602. package/ui/js/ShelfPile.js +27 -0
  603. package/ui/js/SlowClick.js +53 -0
  604. package/ui/js/SlowOp.js +6 -0
  605. package/ui/js/Sort.js +134 -0
  606. package/ui/js/Startup.js +63 -0
  607. package/ui/js/StateWords.js +17 -0
  608. package/ui/js/Status.js +238 -0
  609. package/ui/js/Swap.js +166 -0
  610. package/ui/js/TabMove.js +39 -0
  611. package/ui/js/Tabs.js +736 -0
  612. package/ui/js/Tags.js +134 -0
  613. package/ui/js/Taildrop.js +128 -0
  614. package/ui/js/Tap.js +174 -0
  615. package/ui/js/TextSize.js +107 -0
  616. package/ui/js/Thumbs.js +158 -0
  617. package/ui/js/Transfer.js +172 -0
  618. package/ui/js/Trash.js +81 -0
  619. package/ui/js/TrashDates.js +47 -0
  620. package/ui/js/TrashDrop.js +64 -0
  621. package/ui/js/UiState.js +438 -0
  622. package/ui/js/Unlock.js +152 -0
  623. package/ui/js/Update.js +130 -0
  624. package/ui/js/UserDirs.js +56 -0
  625. package/ui/qmldir +228 -0
@@ -0,0 +1,335 @@
1
+ import QtQuick
2
+ import "js/PreviewSwap.js" as PreviewSwap
3
+
4
+ // A preview's last picture held on screen while the next preview builds under it, and let go in the frame
5
+ // the new one is whole; see AGENTS.md "The preview swap". The layer exists only while a hold does, so a
6
+ // settled preview is drawn directly and costs no texture.
7
+ Item {
8
+ id: root
9
+
10
+ // What the surface draws: the host's children land in here.
11
+ default property alias content: content.data
12
+ // Quick Look keeps its panes eager outside this wrapper and builds only it on first open, so
13
+ // the picture captures that outer container rather than children of its own. Null draws as before.
14
+ property Item captureSource: null
15
+ // The host's answer: what is under the picture is the whole preview it was asked for.
16
+ property bool ready: true
17
+ // True for the column, where a move during a hold means held j, and the stale picture gives way to loading.
18
+ property bool burstEnds: false
19
+ // What the host paints behind the panes, laid under them inside the picture only: text drawn into a clear
20
+ // layer blends its edges against nothing and comes out heavier than the same text drawn on its real ground.
21
+ property color ground: "transparent"
22
+ property real groundInset: 0
23
+ property real groundRadius: 0
24
+
25
+ property bool capturing: false
26
+ property bool holding: false
27
+ property bool started: false
28
+ property bool fellBack: false
29
+ // Set just before the frame that first syncs the layer; the picture is taken in that frame's render.
30
+ property bool syncArmed: false
31
+ // The event loop ran after the arming frame's afterAnimating, so its afterSynchronizing came queued (threaded loop).
32
+ property bool syncQueued: false
33
+ property var key: undefined
34
+ property var queued: []
35
+
36
+ // What ui/Ipc.qml previewSwapState reads: how each hold ended and every frame drawn half-built.
37
+ property int holds: 0
38
+ property int fallbacks: 0
39
+ property int bursts: 0
40
+ property int heldFrames: 0
41
+ property int midFrames: 0
42
+ property int loadingFrames: 0
43
+ property var last: ({ ms: 0, end: "" })
44
+ property double since: 0
45
+
46
+ // A move: the change runs once a picture of the preview as it stands is frozen, or at once when nothing needs one.
47
+ // After a burst the loading state stays live under held j; atWork is the new preview's own start, which is held again.
48
+ function hold(apply, key, atWork) {
49
+ if (atWork !== true && root.fellBack && root.burstEnds && !root.capturing && !root.holding) {
50
+ root.run([apply])
51
+ return
52
+ }
53
+ var action = PreviewSwap.onMove({ capturing: root.capturing, holding: root.holding, key: root.key },
54
+ key, root.burstEnds)
55
+ if (action === PreviewSwap.BURST) {
56
+ root.bursts += 1
57
+ root.release("burst", true)
58
+ root.run([apply])
59
+ return
60
+ }
61
+ if (action === PreviewSwap.JOIN) {
62
+ // A newer target means the work already started was for a row the cursor has left.
63
+ if (root.key !== key) {
64
+ root.key = key
65
+ root.started = false
66
+ cap.stop()
67
+ }
68
+ if (root.holding)
69
+ root.run([apply])
70
+ else if (apply)
71
+ root.queued.push(apply)
72
+ return
73
+ }
74
+ if (!root.visible || root.width <= 0 || root.height <= 0) {
75
+ root.run([apply])
76
+ return
77
+ }
78
+ root.key = key
79
+ root.started = false
80
+ root.fellBack = root.fellBack && root.shownAt > 0
81
+ root.since = Date.now()
82
+ root.holds += 1
83
+ root.queued = apply ? [apply] : []
84
+ root.syncArmed = false
85
+ root.capturing = true
86
+ captureGuard.restart()
87
+ }
88
+
89
+ // The host: the new preview's own work has begun, so the cap counts from here.
90
+ function start(isPdf) {
91
+ if (!root.holding && !root.capturing)
92
+ return
93
+ root.started = true
94
+ cap.interval = PreviewSwap.capMs(isPdf)
95
+ cap.restart()
96
+ Qt.callLater(root.check)
97
+ }
98
+
99
+ // A folder wait keeps the live picture under its own fallback, so the old work's cap stops here.
100
+ function stopCap() { cap.stop() }
101
+
102
+ function captured() {
103
+ if (!root.capturing)
104
+ return
105
+ captureGuard.stop()
106
+ root.syncArmed = false
107
+ // holding first: with capturing cleared first the Loader would drop the frozen layer for one binding pass.
108
+ root.holding = true
109
+ root.capturing = false
110
+ var pending = root.queued
111
+ root.queued = []
112
+ root.run(pending)
113
+ root.check()
114
+ }
115
+
116
+ // True while an unanswered folder waits under the live picture: its own fallback bounds the wait.
117
+ property bool folderHold: false
118
+
119
+ function check() {
120
+ if (root.folderHold)
121
+ return
122
+ if (root.holding && PreviewSwap.releaseIn(root.ready, root.started, root.shownAt, Date.now()) >= 0)
123
+ root.land()
124
+ }
125
+
126
+ function release(end, fell) {
127
+ root.endTimers(fell)
128
+ captureGuard.stop()
129
+ if (root.capturing || root.holding) {
130
+ root.last = { ms: Date.now() - root.since, end: end }
131
+ // The layer goes in this frame, but it lets go of its source only when its deferred delete runs: a hidden
132
+ // source would leave this frame with neither drawn, and the late unref would ask for one frame more.
133
+ if (layer.item)
134
+ layer.item.sourceItem = null
135
+ }
136
+ root.syncArmed = false
137
+ root.capturing = false
138
+ root.holding = false
139
+ root.started = false
140
+ root.fellBack = fell === true
141
+ var pending = root.queued
142
+ root.queued = []
143
+ root.run(pending)
144
+ }
145
+
146
+ // Quick Look closing: nothing queued may run after it, and the picture goes with it.
147
+ function cancel() {
148
+ root.queued = []
149
+ root.release("cancelled", false)
150
+ }
151
+
152
+ function run(changes) {
153
+ for (var i = 0; i < changes.length; i++) {
154
+ if (changes[i])
155
+ changes[i]()
156
+ }
157
+ }
158
+
159
+ // tests/preview-swap.qml reparents its body under the picture; the default alias
160
+ // covers declarative children and this covers the one runtime move.
161
+ function contentItem() { return content }
162
+
163
+ function describe() {
164
+ return { holding: root.holding, capturing: root.capturing, fellBack: root.fellBack, holds: root.holds,
165
+ fallbacks: root.fallbacks, bursts: root.bursts, heldFrames: root.heldFrames,
166
+ midFrames: root.midFrames, loadingFrames: root.loadingFrames, last: root.last, shownMs: root.shownMs }
167
+ }
168
+
169
+ onReadyChanged: {
170
+ if (root.ready)
171
+ root.fellBack = false
172
+ root.readyNow()
173
+ }
174
+ onVisibleChanged: if (!root.visible) root.release("hidden", false)
175
+
176
+ // When this swap put the loading state on screen, 0 while none stands, and how long the last one stood.
177
+ // Timing: it stands Swap.MIN_SHOW_MS from then, across a burst and a new hold, until a whole preview lands.
178
+ property double shownAt: 0
179
+ property int shownMs: 0
180
+
181
+ // A whole preview lets go now, or once the loading state on screen has stood its minimum.
182
+ function land() {
183
+ var wait = PreviewSwap.releaseIn(root.ready, root.started, root.shownAt, Date.now())
184
+ if (wait > 0) {
185
+ minShow.interval = wait
186
+ minShow.restart()
187
+ } else {
188
+ root.release("landed", false)
189
+ }
190
+ }
191
+
192
+ // Past the cap the content draws the loading state, and the held picture is taken again from it.
193
+ // Order: the picture retakes in the next frame, and the new preview lands under it once the minimum is spent.
194
+ function fallBack() {
195
+ var held = root.holding && layer.item !== null
196
+ var next = PreviewSwap.fallBack(held, root.shownAt, Date.now())
197
+ root.shownAt = next.shownAt
198
+ if (!next.keeps) {
199
+ root.release("expired", true)
200
+ return
201
+ }
202
+ root.fellBack = true
203
+ layer.item.scheduleUpdate()
204
+ minShow.interval = next.left
205
+ minShow.restart()
206
+ }
207
+
208
+ // A fallback or a burst starts a loading state; anything else ends it, and a whole preview says how long it stood.
209
+ function shown(fell) {
210
+ if (fell === true) {
211
+ if (root.shownAt === 0)
212
+ root.shownAt = Date.now()
213
+ return
214
+ }
215
+ if (root.shownAt > 0 && root.ready)
216
+ root.shownMs = Date.now() - root.shownAt
217
+ root.shownAt = 0
218
+ }
219
+
220
+ function endTimers(fell) {
221
+ cap.stop()
222
+ minShow.stop()
223
+ root.shown(fell)
224
+ }
225
+
226
+ // A preview turning whole while nothing is held is drawn live, which ends the loading state it replaced.
227
+ function readyNow() {
228
+ if (root.ready && !root.holding && !root.capturing)
229
+ root.shown(false)
230
+ root.check()
231
+ }
232
+
233
+ // The loading state has stood its minimum: a whole preview lands, and one still building goes live so the mark can crawl.
234
+ Timer {
235
+ id: minShow
236
+ repeat: false
237
+ onTriggered: {
238
+ if (!root.holding || root.folderHold)
239
+ return
240
+ if (PreviewSwap.releaseIn(root.ready, root.started, root.shownAt, Date.now()) < 0)
241
+ root.release("expired", true)
242
+ else
243
+ root.land()
244
+ }
245
+ }
246
+
247
+ Item {
248
+ id: content
249
+ anchors.fill: parent
250
+
251
+ Rectangle {
252
+ anchors.fill: parent
253
+ anchors.margins: root.groundInset
254
+ radius: root.groundRadius
255
+ color: root.ground
256
+ visible: root.capturing || root.holding
257
+ }
258
+ }
259
+
260
+ // The picture: the content drawn once into a texture that then stops updating, shown in its place.
261
+ Loader {
262
+ id: layer
263
+ anchors.fill: parent
264
+ active: root.capturing || root.holding
265
+ sourceComponent: ShaderEffectSource {
266
+ sourceItem: root.captureSource !== null ? root.captureSource : content
267
+ hideSource: root.capturing || root.holding
268
+ visible: root.capturing || root.holding
269
+ live: false
270
+ onScheduledUpdateCompleted: root.captured()
271
+ }
272
+ }
273
+
274
+ // While a picture stands for the preview, the pointer reaches nothing under it: no hover, wheel or press.
275
+ MouseArea {
276
+ anchors.fill: parent
277
+ enabled: root.capturing || root.holding
278
+ hoverEnabled: true
279
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
280
+ onWheel: function (wheel) { wheel.accepted = true }
281
+ }
282
+
283
+ Timer {
284
+ id: cap
285
+ repeat: false
286
+ onTriggered: {
287
+ if (root.folderHold)
288
+ return
289
+ if (!root.holding && !root.capturing)
290
+ return
291
+ root.fallbacks += 1
292
+ root.fallBack()
293
+ }
294
+ }
295
+
296
+ // The first sync queues a repaint, so the change runs after it; the basic loop emits inside the frame, so it waits for scheduledUpdateCompleted.
297
+ Connections {
298
+ target: root.syncArmed ? root.Window.window : null
299
+ function onAfterSynchronizing() { if (root.syncQueued) root.captured() }
300
+ }
301
+ function markSyncQueued() { root.syncQueued = root.syncArmed }
302
+
303
+ // A window that is not drawing never completes a capture, so the change goes ahead unheld.
304
+ Timer {
305
+ id: captureGuard
306
+ interval: PreviewSwap.CAPTURE_MS
307
+ repeat: false
308
+ onTriggered: if (root.capturing) root.release("uncaptured", false)
309
+ }
310
+
311
+ // afterAnimating runs on this thread just before each frame is synchronised, so it sees what that frame draws.
312
+ // Live from the first hold until ready lands after the release, so a half-built frame is never drawn uncounted; an idle window still pays nothing.
313
+ Connections {
314
+ target: (root.capturing || root.holding || !root.ready) ? root.Window.window : null
315
+ function onAfterAnimating() {
316
+ var source = root.captureSource !== null ? root.captureSource : content
317
+ if (!root.syncArmed && root.capturing && root.visible && layer.item !== null && source.width > 0
318
+ && source.height > 0) {
319
+ root.syncArmed = true
320
+ root.syncQueued = false
321
+ Qt.callLater(root.markSyncQueued)
322
+ }
323
+ if (!root.visible)
324
+ return
325
+ var kind = PreviewSwap.frameKind(root.capturing || root.holding, root.ready, root.fellBack,
326
+ root.holding && root.shownAt > 0)
327
+ if (kind === "held")
328
+ root.heldFrames += 1
329
+ else if (kind === "mid")
330
+ root.midFrames += 1
331
+ else if (kind === "loading")
332
+ root.loadingFrames += 1
333
+ }
334
+ }
335
+ }
@@ -0,0 +1,149 @@
1
+ import QtQuick
2
+ import Quickshell.Io
3
+ import qs.Commons
4
+ import "." as Flea
5
+ import "js/Markdown.js" as Markdown
6
+ import "js/Csv.js" as Csv
7
+
8
+ // Quick Look's code and text pane: the bar, then the lines coloured by the backend; a network or phone file is read here, never by the backend.
9
+ Item {
10
+ id: root
11
+
12
+ property bool active: false
13
+ property string path: ""
14
+ property real size: 0
15
+
16
+ // Past this size the pane draws the too-large frame; remote storage sets 256 KiB, the most FileView reads whole into memory here.
17
+ property int maxBytes: 1048576
18
+ // True on network and phone storage, where the backend is never given the path.
19
+ property bool truncate: false
20
+ // The backend that colours the lines; a bare stub leaves the file's own text drawn plain.
21
+ property var backend: null
22
+ property string markName: "file"
23
+ property bool numbered: false
24
+ property bool wrap: false
25
+ // The keyboard is on the bar's close mark; Quick Look's key handler owns the walk.
26
+ property bool closeFocused: false
27
+
28
+ signal closeRequested
29
+
30
+ // The row count for a table, the line count for code and text.
31
+ function countText() {
32
+ if (!root.csv) return Markdown.countLine(lines.total)
33
+ return root.body !== null ? Csv.rowCount(Csv.dataRows(root.body.records)) : ""
34
+ }
35
+
36
+ readonly property bool engine: root.backend !== null && typeof root.backend.askCode === "function"
37
+ readonly property bool fromFile: root.truncate || !root.engine
38
+ // A .csv or .tsv is drawn as a table in place of the line view.
39
+ readonly property bool csv: Csv.tabular(root.path, root.size, root.maxBytes, root.fromFile)
40
+ readonly property var body: root.csv ? csvLoader.item : lines
41
+ // Over the gate by the listing's size, or by the backend's own count when the file grew since.
42
+ readonly property bool tooLarge: (root.fromFile && root.size > root.maxBytes) || (root.body !== null && root.body.answer === "large")
43
+ property bool readFailed: false
44
+ readonly property bool failed: root.readFailed || (root.body !== null && root.body.answer === "failed")
45
+ readonly property bool binary: root.body !== null && root.body.answer === "binary"
46
+ // For ui/Ipc.qml: the drawn lines and their box.
47
+ readonly property var bodyItem: root.body
48
+ readonly property bool firstScreen: root.body !== null && root.body.firstScreen
49
+ // CodeLines' scrolling view, which the scroll bar and the wrap toggle read; its one Flickable child.
50
+ readonly property var codeList: {
51
+ var kids = lines.children
52
+ for (var i = 0; i < kids.length; i++)
53
+ if (kids[i].contentY !== undefined) return kids[i]
54
+ return null
55
+ }
56
+ readonly property var list: root.csv ? (root.body !== null ? root.body.list : null) : root.codeList
57
+ function shownText() { return root.fromFile ? file.text() : root.body !== null ? root.body.lines.join("\n") : "" }
58
+ readonly property string status: {
59
+ if (root.tooLarge) return "This file is too large to preview."
60
+ if (root.failed) return "This file could not be read."
61
+ return root.body !== null && root.body.answer !== "" ? "ready" : "loading"
62
+ }
63
+
64
+ visible: root.active
65
+
66
+ // The line at the top of the view stays at the top while the rows change height.
67
+ onWrapChanged: if (root.list !== null) Qt.callLater(root.keepTop, Math.max(0, root.list.indexAt(0, root.list.contentY + 1)))
68
+ function keepTop(top) {
69
+ if (root.list === null) return
70
+ root.list.forceLayout()
71
+ root.list.positionViewAtIndex(top, ListView.Beginning)
72
+ }
73
+
74
+ FileView {
75
+ id: file
76
+ path: (root.active && root.size <= root.maxBytes && root.fromFile) ? root.path : ""
77
+ printErrors: false
78
+ onLoadFailed: root.readFailed = true
79
+ onPathChanged: root.readFailed = false
80
+ }
81
+
82
+ Flea.QuickLookBar {
83
+ id: bar
84
+ anchors.top: parent.top
85
+ anchors.left: parent.left
86
+ anchors.right: parent.right
87
+ markName: root.markName
88
+ name: root.path.substring(root.path.lastIndexOf("/") + 1)
89
+ countLabel: root.body !== null && root.body.settled ? root.countText() : ""
90
+ closeFocused: root.closeFocused
91
+ onCloseRequested: root.closeRequested()
92
+ }
93
+
94
+ Flea.CodeLines {
95
+ id: lines
96
+ anchors.fill: parent
97
+ anchors.topMargin: bar.height + Theme.spacing.rowPaddingX
98
+ anchors.margins: Theme.spacing.rowPaddingX
99
+ visible: !root.csv && !root.tooLarge && !root.failed && !root.binary
100
+ backend: root.backend
101
+ slot: "look"
102
+ path: root.path
103
+ fromText: root.fromFile
104
+ text: root.fromFile && file.loaded ? file.text() : null
105
+ active: root.active && !root.tooLarge && !root.csv
106
+ numbered: root.numbered
107
+ wrap: root.wrap
108
+ scrolls: true
109
+ pixelSize: Theme.font.body
110
+
111
+ Flea.FastScrollHandler {
112
+ flickable: root.codeList
113
+ }
114
+
115
+ Flea.ViewportScrollBar {
116
+ anchors { top: parent.top; right: parent.right }
117
+ flickable: root.codeList
118
+ }
119
+ }
120
+
121
+ Loader {
122
+ id: csvLoader
123
+ anchors.fill: parent
124
+ anchors.topMargin: bar.height
125
+ active: root.active && root.csv
126
+ visible: csvLoader.item !== null && root.csv && !root.tooLarge && !root.failed && !root.binary
127
+ source: "CsvTable.qml"
128
+ onLoaded: {
129
+ item.look = true
130
+ item.slot = "look"
131
+ item.pixelSize = Qt.binding(function () { return Theme.font.caption })
132
+ item.backend = Qt.binding(function () { return root.backend })
133
+ item.path = Qt.binding(function () { return root.path })
134
+ item.fromText = Qt.binding(function () { return root.fromFile })
135
+ item.text = Qt.binding(function () { return root.fromFile && file.loaded ? file.text() : null })
136
+ item.active = Qt.binding(function () { return root.active && root.size <= root.maxBytes })
137
+ }
138
+ }
139
+
140
+ Flea.CodeRefusal {
141
+ visible: false // Failed previews remain blank.
142
+ anchors.fill: parent
143
+ topInset: bar.height
144
+ binary: root.binary
145
+ tooLarge: root.tooLarge
146
+ failed: root.failed
147
+ markName: root.markName
148
+ }
149
+ }
@@ -0,0 +1,18 @@
1
+ import QtQuick
2
+ import "." as Flea
3
+
4
+ // One protocol member: buttons A's one control as a set member (ButtonSystem040 callout 1, Nearby callout 6), current in the foreground frame.
5
+ Flea.DialogButton {
6
+ id: root
7
+
8
+ property bool picked: false
9
+
10
+ setMember: true
11
+ current: root.picked
12
+ // The form owns the Tab order, so the member only reports it and is never walked by Qt.
13
+ tabHandle: true
14
+
15
+ function takeFocus() {
16
+ root.forceActiveFocus()
17
+ }
18
+ }
@@ -0,0 +1,38 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+ import "." as Flea
4
+ import "js/Facts.js" as Facts
5
+
6
+ // The canvas's Archive tile at Quick Look size: the name, the count the index gave, then the entries.
7
+ Column {
8
+ id: root
9
+ spacing: Theme.spacing.gap
10
+ property string path: ""
11
+ property var meta: null
12
+
13
+ // corner: a filename is arbitrary text, so PlainText, the same rule every name on this surface follows.
14
+ Text {
15
+ width: parent.width
16
+ text: root.path.substring(root.path.lastIndexOf("/") + 1)
17
+ color: Theme.color.foreground
18
+ font.family: Theme.font.family
19
+ font.pixelSize: Theme.font.body
20
+ textFormat: Text.PlainText
21
+ elide: Text.ElideMiddle
22
+ }
23
+
24
+ Text {
25
+ width: parent.width
26
+ text: Facts.archiveLine(root.meta)
27
+ color: Theme.color.muted
28
+ font.family: Theme.font.family
29
+ font.pixelSize: Theme.font.caption
30
+ textFormat: Text.PlainText
31
+ }
32
+
33
+ Flea.PreviewArchive {
34
+ width: parent.width
35
+ height: parent.height - y
36
+ meta: root.meta
37
+ }
38
+ }
@@ -0,0 +1,103 @@
1
+ import QtQuick
2
+ import "." as Flea
3
+ import "js/LangMarks.js" as LangMarks
4
+ import "js/Icons.js" as Icons
5
+
6
+ // Quick Look's strip: language mark, name, line count and close; no fill, the chrome surface rounds its corners.
7
+ Item {
8
+ id: root
9
+
10
+ property string markName: "file"
11
+ property string name: ""
12
+ // flea-qml: an emoji mark is drawn as itself, never replaced by a language logo.
13
+ readonly property string langSlug: ViewState.langMarks && !Icons.isEmoji(root.markName) ? LangMarks.slugForFile(root.name) : ""
14
+ readonly property bool thumbDrawn: false
15
+ property var langLoader: null
16
+ onLangSlugChanged: LangMarks.syncMark(root, barMark, Qt.resolvedUrl("LangMarkLoader.qml"), Component.Ready)
17
+ // Empty hides the count; it hides too once the name has given up all its room.
18
+ property string countLabel: ""
19
+ // The keyboard is on the close mark; Quick Look's key handler owns the walk, as the PDF viewer's controls do.
20
+ property bool closeFocused: false
21
+
22
+ signal closeRequested
23
+
24
+ height: Theme.chromeHeight
25
+ readonly property real ruleOpacity: 0.12
26
+ // Where the right-hand group starts: the name and the count give way to it, it never gives way to them.
27
+ readonly property real trail: barClose.x
28
+ readonly property bool countShown: root.countLabel.length > 0
29
+ && barName.x + 2 * Theme.spacing.gap + barLines.implicitWidth <= root.trail
30
+
31
+ // The render suite reads the bar's order off these rects, the way PdfViewer.buttonFor opens its buttons.
32
+ function geometry() {
33
+ return { mark: barMark, language: root.langLoader ? root.langLoader.item : null, markName: barMark.name, name: barName, nameEnd: barName.x + Math.min(barName.width, barName.implicitWidth),
34
+ lines: barLines, countShown: root.countShown, close: barClose, bar: root, height: root.height,
35
+ segment: null, rendered: null, source: null }
36
+ }
37
+
38
+ function closeState() { var c = barClose.mapToItem(null, barClose.width / 2, barClose.height / 2); return { hovered: barClose.hovered, pressed: barClose.pressed, focused: barClose.keyboardFocused, centre: Math.round(c.x) + " " + Math.round(c.y) } }
39
+
40
+ Rectangle {
41
+ anchors.bottom: parent.bottom
42
+ anchors.left: parent.left
43
+ anchors.right: parent.right
44
+ height: Theme.spacing.hairline
45
+ color: Theme.color.foreground
46
+ opacity: root.ruleOpacity
47
+ }
48
+
49
+ // The kind's mark of the LanguageMarks set, in foreground and centred above the rule like the PDF viewer's kind mark.
50
+ Flea.Glyph {
51
+ id: barMark
52
+ anchors.left: parent.left
53
+ anchors.leftMargin: Theme.spacing.rowPaddingX
54
+ y: Math.round((parent.height - Theme.spacing.hairline - height) / 2)
55
+ width: Theme.chromeMarkSize
56
+ height: Theme.chromeMarkSize
57
+ visible: root.langSlug === ""
58
+ name: root.markName
59
+ color: Theme.color.foreground
60
+ }
61
+
62
+ // corner: a filename is arbitrary text, so PlainText, the same rule every name on this surface follows.
63
+ Text {
64
+ id: barName
65
+ anchors.left: barMark.right
66
+ anchors.leftMargin: Theme.spacing.gap
67
+ anchors.verticalCenter: parent.verticalCenter
68
+ width: Math.min(implicitWidth, Math.max(0, root.trail - x - 2 * Theme.spacing.gap
69
+ - (root.countShown ? barLines.implicitWidth : 0)))
70
+ text: root.name
71
+ color: Theme.color.foreground
72
+ font.family: Theme.font.family
73
+ font.pixelSize: Theme.font.caption
74
+ textFormat: Text.PlainText
75
+ elide: Text.ElideMiddle
76
+ }
77
+
78
+ Text {
79
+ id: barLines
80
+ anchors.left: barName.right
81
+ anchors.leftMargin: Theme.spacing.gap
82
+ anchors.verticalCenter: parent.verticalCenter
83
+ text: root.countLabel
84
+ visible: root.countShown
85
+ color: Theme.color.muted
86
+ font.family: Theme.font.family
87
+ font.pixelSize: Theme.font.caption
88
+ textFormat: Text.PlainText
89
+ }
90
+
91
+ Flea.ChromeButton {
92
+ id: barClose
93
+ gesturePolicy: TapHandler.ReleaseWithinBounds
94
+ ruleRows: Theme.spacing.hairline
95
+ anchors.right: parent.right
96
+ anchors.rightMargin: Theme.spacing.rowPaddingX
97
+ anchors.verticalCenter: parent.verticalCenter
98
+ glyph: "x"
99
+ keyboardFocused: root.closeFocused
100
+ accessName: "Close"
101
+ onActivated: root.closeRequested()
102
+ }
103
+ }