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
package/ui/Header.qml ADDED
@@ -0,0 +1,433 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+ import qs.Ui
4
+ import "." as Flea
5
+ import "js/Columns.js" as Columns
6
+ import "js/DirSizes.js" as DirSizes
7
+ import "js/Sort.js" as Sort
8
+
9
+ // The column header renders sort state and owns none of it, so Pane stays the one state owner.
10
+ Item {
11
+ id: root
12
+
13
+ property string sortBy: "name"
14
+ property bool sortDesc: false
15
+ property bool dualMode: false
16
+ readonly property real sizeWidth: root.dualMode ? Theme.dualColumn.size : Theme.column.size
17
+ // The chooser's pair, matching ui/Row.qml: the check box slot and SendPicker.html's narrower date.
18
+ property real leadingSlot: 0
19
+ property bool compactDate: false
20
+ readonly property real dateWidth: root.dualMode ? Theme.dualColumn.date : root.compactDate ? Theme.column.pickerDate : Theme.column.date
21
+
22
+ // The click ui/js/Sort.js answers. The header owns no sort state, so it only says which column
23
+ // was hit; the key is the protocol's own, which is why Modified sends "mtime".
24
+ signal sortRequested(string key)
25
+
26
+ // The pane whose held rows a double click fits; null where the picker reuses this header.
27
+ property var pane: null
28
+ // Only the list view heads columns; Pane wires its viewMode so other views build no handles.
29
+ property string viewMode: "list"
30
+ // A drag in flight, so the hairline follows the pointer and one write lands on release.
31
+ property string dragKey: ""
32
+ property real dragStartX: 0
33
+ property real dragLastX: 0
34
+ property real dragStartWidth: 0
35
+ property real dragPreview: 0
36
+ // True once the pointer travelled, so a click or a fit ending the drag writes nothing.
37
+ property bool dragMoved: false
38
+
39
+ // A right click over the titles opens the pane's one ContextMenu with the column toggles and
40
+ // the hidden toggle; a left click still sorts, and sortable still gates everything on a search.
41
+ signal menuRequested(var scenePosition)
42
+
43
+ // The same hairline lift the status bar uses, so the two rules read alike.
44
+ readonly property real ruleOpacity: 0.12
45
+
46
+ // A column header is chrome, not a data row; see Theme.qml's chromeHeight comment.
47
+ // The search's query line takes the header's slot whole, per the design canvas's Search board.
48
+ property string searchMode: ""
49
+ property string searchQuery: ""
50
+ property string searchScope: ""
51
+ property string searchNote: ""
52
+ property string searchWayOut: ""
53
+ property string searchPlaceholder: ""
54
+ property string searchTabHint: ""
55
+ property bool searchRunning: false
56
+ signal searchCloseRequested()
57
+ // flea-qml: the Find field's edits and the keys it hands back, and a way to give it the keyboard.
58
+ signal searchEdited(string text)
59
+ signal searchKeyOut(var event)
60
+ signal searchFieldEntered()
61
+ function focusSearchField() { searchStrip.focusField() }
62
+ readonly property bool searchFieldFocused: searchStrip.fieldFocused
63
+
64
+ // A search takes the header's slot whole, but the strip's ground is a plain Rectangle and
65
+ // accepts no input, so the titles under it stay hittable unless the handlers go down with them.
66
+ readonly property bool sortable: root.searchMode.length === 0
67
+ // On glass the strip lets the desktop through, so what it covers when opaque goes down with it.
68
+ readonly property bool underStrip: Glass.on && root.searchMode.length > 0
69
+ // Sidebar040: Recent replaces Mode with fixed Location and heads its date as Used.
70
+ property bool recent: false
71
+
72
+ // The columns this width affords, less the hidden ones; rows draw lane-narrow like this header.
73
+ property var hiddenCols: ViewState.hiddenCols
74
+ readonly property real contentWidth: Math.max(0, root.width - Theme.spacing.rowPaddingX)
75
+ readonly property var cols: root.recent ? Theme.columns(root.contentWidth, root.hiddenCols, root.dateWidth, true, root.dualMode) : root.dualMode ? Theme.dualColumns(root.contentWidth, root.hiddenCols) : Theme.columns(root.contentWidth, root.hiddenCols, root.dateWidth)
76
+
77
+ implicitHeight: Theme.chromeHeight
78
+
79
+ SearchStrip {
80
+ id: searchStrip
81
+ anchors.fill: parent
82
+ visible: root.searchMode.length > 0
83
+ z: 1
84
+ query: root.searchQuery
85
+ scope: root.searchScope
86
+ note: root.searchNote
87
+ wayOut: root.searchWayOut
88
+ placeholder: root.searchPlaceholder
89
+ tabHint: root.searchTabHint
90
+ running: root.searchRunning
91
+ onCloseRequested: root.searchCloseRequested()
92
+ onEdited: function (text) { root.searchEdited(text) }
93
+ onKeyOut: function (event) { root.searchKeyOut(event) }
94
+ onFieldEntered: root.searchFieldEntered()
95
+ // The canvas draws the caret on both its search boards, so it stays up as long as the strip is.
96
+ typing: true
97
+ }
98
+
99
+ // The OEM lifts a section header off the body with a fill, on top of the hairline rule below.
100
+ Rectangle {
101
+ anchors.fill: parent
102
+ visible: !root.underStrip
103
+ color: Style.normalFill
104
+ }
105
+
106
+ PanelSectionHeader {
107
+ id: headerName
108
+ anchors.left: parent.left
109
+ anchors.leftMargin: Theme.spacing.rowPaddingX + root.leadingSlot + (root.dualMode ? Theme.markSize + Theme.spacing.gap : 0)
110
+ anchors.right: headerMode.left
111
+ anchors.rightMargin: (root.recent ? root.cols.location : root.cols.mode) ? Theme.spacing.gap : 0
112
+ anchors.verticalCenter: parent.verticalCenter
113
+ visible: !root.underStrip
114
+ text: root.title("Name", "name")
115
+ elide: Text.ElideRight
116
+
117
+ TapHandler { enabled: root.sortable; onTapped: root.sortRequested("name") }
118
+ }
119
+
120
+ PanelSectionHeader {
121
+ id: headerMode
122
+ anchors.right: headerSize.left
123
+ anchors.rightMargin: root.cols.size && !root.dualMode ? Theme.spacing.gap : 0
124
+ anchors.verticalCenter: parent.verticalCenter
125
+ visible: (root.recent ? root.cols.location : root.cols.mode) && !root.underStrip
126
+ width: root.recent ? (root.cols.location ? Theme.column.location : 0) : root.cols.mode ? (root.dragKey === "mode" ? root.dragPreview : Theme.column.mode) : 0
127
+ text: root.recent ? "Location" : root.title("Mode", "mode")
128
+ }
129
+
130
+ PanelSectionHeader {
131
+ id: headerSize
132
+ anchors.right: headerDate.left
133
+ anchors.rightMargin: root.cols.date && !root.dualMode ? Theme.spacing.gap : 0
134
+ anchors.verticalCenter: parent.verticalCenter
135
+ visible: root.cols.size && !root.underStrip
136
+ width: root.cols.size ? (root.dragKey === "size" ? root.dragPreview : root.sizeWidth) : 0
137
+ text: root.title("Size", "size")
138
+ horizontalAlignment: Text.AlignRight
139
+
140
+ // flea-qml: the ⚖️ at the cell's left measures every folder in the listing (ui/Pane.qml
141
+ // measureAllDirs); the title itself still sorts. One handler decides by where the click landed.
142
+ Text {
143
+ id: sizeScale
144
+ anchors.left: parent.left
145
+ anchors.verticalCenter: parent.verticalCenter
146
+ visible: root.pane !== null && !root.recent && headerSize.width > 0
147
+ text: DirSizes.UNMEASURED
148
+ textFormat: Text.PlainText
149
+ font.pixelSize: headerSize.font.pixelSize
150
+ }
151
+ HoverHandler {
152
+ id: scaleHover
153
+ cursorShape: scaleHover.point.position.x < sizeScale.width + Theme.spacing.gap && sizeScale.visible ? Qt.PointingHandCursor : Qt.ArrowCursor
154
+ }
155
+ TapHandler {
156
+ enabled: root.sortable || sizeScale.visible
157
+ onTapped: function (eventPoint) {
158
+ if (sizeScale.visible && eventPoint.position.x < sizeScale.width + Theme.spacing.gap) root.pane.measureAllDirs()
159
+ else if (root.sortable) root.sortRequested("size")
160
+ }
161
+ }
162
+ }
163
+
164
+ PanelSectionHeader {
165
+ id: headerDate
166
+ anchors.right: headerKind.left
167
+ anchors.rightMargin: root.cols.kind && !root.recent ? Theme.spacing.gap : 0
168
+ anchors.verticalCenter: parent.verticalCenter
169
+ visible: root.cols.date && !root.underStrip
170
+ width: root.cols.date ? (root.dragKey === "date" ? root.dragPreview : root.dateWidth) : 0
171
+ text: root.title(root.pane && root.pane.recentMode === "trash" ? "Deleted" : root.recent ? "Used" : "Modified", "mtime")
172
+ horizontalAlignment: Text.AlignRight
173
+ elide: Text.ElideRight
174
+
175
+ TapHandler { enabled: root.sortable; onTapped: root.sortRequested("mtime") }
176
+ }
177
+
178
+ PanelSectionHeader {
179
+ id: headerKind
180
+ anchors.right: parent.right
181
+ // The header carries the lane the rows keep: its own padding plus the lane, so titles stay over their cells.
182
+ anchors.rightMargin: 2 * Theme.spacing.rowPaddingX
183
+ anchors.verticalCenter: parent.verticalCenter
184
+ visible: root.cols.kind && !root.recent && !root.underStrip
185
+ width: root.cols.kind && !root.recent ? (root.dragKey === "kind" ? root.dragPreview : Theme.column.kind) : 0
186
+ text: root.title("Kind", "kind")
187
+ elide: Text.ElideRight
188
+
189
+ TapHandler { enabled: root.sortable; onTapped: root.sortRequested("kind") }
190
+ }
191
+
192
+ // The header is chrome, but it is the chrome the columns belong to, so its right click is where
193
+ // the columns are turned on and off. Left click sorts; sortable gates that, not this.
194
+ TapHandler {
195
+ acceptedButtons: Qt.RightButton
196
+ onTapped: function (eventPoint) { root.menuRequested(eventPoint.scenePosition) }
197
+ }
198
+
199
+ // ListColumns040: build edges only where usable; cells outside the Loader require x placement.
200
+ Loader {
201
+ id: handlesLoader
202
+ anchors.fill: parent
203
+ active: root.viewMode === "list" && root.visible && !root.dualMode && root.sortable && root.pane !== null
204
+ sourceComponent: Item {
205
+ anchors.fill: parent
206
+ Flea.ResizeHandle {
207
+ id: modeHandle
208
+ visible: root.cols.mode
209
+ x: headerMode.x - Math.floor(width / 2)
210
+ anchors.top: parent.top
211
+ anchors.bottom: parent.bottom
212
+ z: 3
213
+ columnKey: "mode"
214
+ hot: root.dragKey === "mode"
215
+ onPressed: function (mouse) { root.beginDrag("mode", modeHandle, mouse) }
216
+ onMoved: function (mouse) { root.moveDrag("mode", modeHandle, mouse) }
217
+ onReleased: root.endDrag()
218
+ onDoubleClicked: root.autofitColumn("mode")
219
+ }
220
+ Flea.ResizeHandle {
221
+ id: sizeHandle
222
+ visible: root.cols.size
223
+ x: headerSize.x - Math.floor(width / 2)
224
+ anchors.top: parent.top
225
+ anchors.bottom: parent.bottom
226
+ z: 3
227
+ columnKey: "size"
228
+ hot: root.dragKey === "size"
229
+ onPressed: function (mouse) { root.beginDrag("size", sizeHandle, mouse) }
230
+ onMoved: function (mouse) { root.moveDrag("size", sizeHandle, mouse) }
231
+ onReleased: root.endDrag()
232
+ onDoubleClicked: root.autofitColumn("size")
233
+ }
234
+ Flea.ResizeHandle {
235
+ id: dateHandle
236
+ visible: root.cols.date
237
+ x: headerDate.x - Math.floor(width / 2)
238
+ anchors.top: parent.top
239
+ anchors.bottom: parent.bottom
240
+ z: 3
241
+ columnKey: "date"
242
+ hot: root.dragKey === "date"
243
+ onPressed: function (mouse) { root.beginDrag("date", dateHandle, mouse) }
244
+ onMoved: function (mouse) { root.moveDrag("date", dateHandle, mouse) }
245
+ onReleased: root.endDrag()
246
+ onDoubleClicked: root.autofitColumn("date")
247
+ }
248
+ Flea.ResizeHandle {
249
+ id: kindHandle
250
+ visible: root.cols.kind
251
+ x: headerKind.x - Math.floor(width / 2)
252
+ anchors.top: parent.top
253
+ anchors.bottom: parent.bottom
254
+ z: 3
255
+ columnKey: "kind"
256
+ hot: root.dragKey === "kind"
257
+ onPressed: function (mouse) { root.beginDrag("kind", kindHandle, mouse) }
258
+ onMoved: function (mouse) { root.moveDrag("kind", kindHandle, mouse) }
259
+ onReleased: root.endDrag()
260
+ onDoubleClicked: root.autofitColumn("kind")
261
+ }
262
+ }
263
+ }
264
+
265
+ // Built only while a fit measures, from the fit-only file, so rest carries no metrics object.
266
+ Loader {
267
+ id: fitLoader
268
+ active: false
269
+ source: ""
270
+ }
271
+
272
+ Rectangle {
273
+ anchors.bottom: parent.bottom
274
+ anchors.left: parent.left
275
+ anchors.right: parent.right
276
+ height: Theme.spacing.hairline
277
+ visible: !root.underStrip
278
+ color: Theme.color.foreground
279
+ opacity: root.ruleOpacity
280
+ }
281
+
282
+ function title(label, key) {
283
+ return root.sortBy === key ? Sort.title(label, root.sortDesc) : label
284
+ }
285
+
286
+ // The stored width a drag or a fit wrote, or the measured one when nothing did.
287
+ function currentWidthOf(key) { return Theme.column[key] }
288
+
289
+ // One remembered edge: clamped to the rails and written once, so a drag is layout only.
290
+ function writeWidth(key, px) {
291
+ var next = Columns.clampListWidth(px)
292
+ var cur = (ViewState.state.columnWidths || ({}))[key]
293
+ if (cur === next)
294
+ return
295
+ var obj = {}
296
+ var leaf = {}
297
+ var stored = ViewState.state.columnWidths || {}
298
+ for (var k in stored) obj[k] = stored[k]
299
+ obj[key] = next
300
+ leaf[key] = next
301
+ ViewState.changeMapEntries("columnWidths", leaf, obj)
302
+ }
303
+
304
+ function beginDrag(key, handle, mouse) {
305
+ root.dragStartX = handle.mapToItem(root, mouse.x, mouse.y).x
306
+ root.dragLastX = root.dragStartX
307
+ root.dragStartWidth = root.currentWidthOf(key)
308
+ root.dragPreview = root.dragStartWidth
309
+ root.dragMoved = false
310
+ // Activate the preview only after capture, because its width binding moves the handle.
311
+ root.dragKey = key
312
+ }
313
+
314
+ function moveDrag(key, handle, mouse) {
315
+ if (root.dragKey !== key)
316
+ return
317
+ var x = handle.mapToItem(root, mouse.x, mouse.y).x
318
+ // A press that never travels is a click; the grab zone sits on the column's left hairline of a right-anchored chain, so widening moves it left: start minus dx.
319
+ if (Math.abs(x - root.dragStartX) < 1)
320
+ return
321
+ root.dragMoved = true
322
+ root.dragLastX = x
323
+ root.dragPreview = Columns.clampListWidth(root.dragStartWidth - (x - root.dragStartX))
324
+ }
325
+
326
+ // One remembered edge, written once on release after a real move, so a click or a fit writes nothing.
327
+ function endDrag() {
328
+ if (root.dragKey.length === 0)
329
+ return
330
+ if (root.dragMoved)
331
+ root.writeWidth(root.dragKey, root.dragPreview)
332
+ root.dragKey = ""
333
+ root.dragMoved = false
334
+ }
335
+
336
+ // The fit-only file builds synchronously, so the same call can consume its item.
337
+ function ensureFit() {
338
+ if (fitLoader.item !== null)
339
+ return fitLoader.item
340
+ fitLoader.source = Qt.resolvedUrl("FitMetrics.qml")
341
+ fitLoader.active = true
342
+ return fitLoader.item
343
+ }
344
+
345
+ // Releasing clears the item, so rest carries no metrics object after a fit.
346
+ function releaseFit() {
347
+ fitLoader.active = false
348
+ fitLoader.source = ""
349
+ }
350
+
351
+ // The strings ui/Row.qml draws over the held rows only; one F4 reuses one item.
352
+ function fittedWidth(key) {
353
+ var item = root.ensureFit()
354
+ if (item === null)
355
+ return -1
356
+ var widths = []
357
+ for (var i = 0; i < root.pane.rows.length; i++) {
358
+ var row = root.pane.rows[i]
359
+ if (!row)
360
+ continue
361
+ widths.push(item.cellWidth(key, row, root.pane.kindNames,
362
+ item.dirSizeFor(root.pane.dirSizeState, root.pane.held, i)))
363
+ }
364
+ if (widths.length === 0)
365
+ return -1
366
+ return Columns.autofitWidth(widths, root.currentWidthOf(key))
367
+ }
368
+
369
+ // A double click fits one column and ends the drag, so the release after doubleClicked writes nothing back; F4 fits every drawn one.
370
+ function autofitColumn(key) {
371
+ root.dragKey = ""
372
+ root.dragMoved = false
373
+ if (!root.pane || root.dualMode || !root.sortable || !root.cols[key]) {
374
+ root.releaseFit()
375
+ return
376
+ }
377
+ var next = root.fittedWidth(key)
378
+ root.releaseFit()
379
+ if (next >= 0)
380
+ root.writeWidth(key, next)
381
+ }
382
+
383
+ function autofitAll() {
384
+ if (!root.pane || root.dualMode || !root.sortable)
385
+ return
386
+ var obj = {}
387
+ var leaf = {}
388
+ var stored = ViewState.state.columnWidths || {}
389
+ for (var k in stored) obj[k] = stored[k]
390
+ var changed = false
391
+ var keys = ["mode", "size", "date", "kind"]
392
+ if (root.ensureFit() === null) {
393
+ root.releaseFit()
394
+ return
395
+ }
396
+ for (var i = 0; i < keys.length; i++) {
397
+ if (!root.cols[keys[i]])
398
+ continue
399
+ var next = root.fittedWidth(keys[i])
400
+ if (next >= 0 && obj[keys[i]] !== Columns.clampListWidth(next)) {
401
+ obj[keys[i]] = Columns.clampListWidth(next)
402
+ leaf[keys[i]] = Columns.clampListWidth(next)
403
+ changed = true
404
+ }
405
+ }
406
+ root.releaseFit()
407
+ if (changed)
408
+ ViewState.changeMapEntries("columnWidths", leaf, obj)
409
+ }
410
+
411
+ // What the header case reads, built from the same values the header renders.
412
+ function titles() {
413
+ if (root.recent)
414
+ return "Name" + (root.cols.location ? "|Location" : "") + (root.cols.size ? "|Size" : "") + (root.cols.date ? "|Used" : "")
415
+ return "Name|Mode|Size|Modified|Kind"
416
+ }
417
+
418
+ // What the header is drawing right now, for the seam that reads it beside a row's.
419
+ function columnSet() { return Columns.names(root.cols) }
420
+
421
+ // The one lookup the geometry reader needs, the same by-key idiom Pane.itemFor uses for rows.
422
+ function cell(key) {
423
+ switch (key) {
424
+ case "name": return headerName
425
+ case "location": return root.recent ? headerMode : null
426
+ case "mode": return root.recent ? null : headerMode
427
+ case "size": return headerSize
428
+ case "date": return headerDate
429
+ case "kind": return headerKind
430
+ }
431
+ return null
432
+ }
433
+ }
@@ -0,0 +1,39 @@
1
+ import QtQuick
2
+ import "js/DragOut.js" as DragOut
3
+
4
+ // The two timers a drag rests on, built with the first hovered row and kept for the window's life.
5
+ Item {
6
+ id: root
7
+ required property var session
8
+ // The autoscroll step's own interval, one row per tick.
9
+ readonly property int scrollMs: 100
10
+
11
+ // Resting on a folder opens it when the setting is on; any move restarts the rest.
12
+ Timer {
13
+ id: openTimer
14
+ interval: DragOut.OPEN_MS
15
+ repeat: false
16
+ onTriggered: {
17
+ if (ViewState.openFoldersWhileDragging && root.session.hoverPath.length > 0 && root.session.pane)
18
+ root.session.pane.open(root.session.hoverPath)
19
+ }
20
+ }
21
+
22
+ // Resting in the top or bottom band scrolls the view a row at a time, with the setting on or off.
23
+ Timer {
24
+ id: scrollTimer
25
+ interval: root.scrollMs
26
+ repeat: true
27
+ running: root.session.scrollDir !== 0
28
+ onTriggered: {
29
+ var view = root.session.pane ? root.session.pane.listArea : null
30
+ if (!view || view.contentY === undefined)
31
+ return
32
+ var step = view.cellHeightPx !== undefined ? view.cellHeightPx : Theme.fileRowHeight
33
+ view.contentY = Math.max(0, Math.min(view.contentHeight - view.height, view.contentY + root.session.scrollDir * step))
34
+ }
35
+ }
36
+
37
+ function rest() { openTimer.restart() }
38
+ function stopRest() { openTimer.stop() }
39
+ }
@@ -0,0 +1,30 @@
1
+ import QtQuick
2
+ import QtQuick.Shapes
3
+
4
+ // One viewport texture follows the frame's inner arc; the tall page keeps its original decode.
5
+ Shape {
6
+ id: root
7
+ property Item target: null
8
+ property real radius: 0
9
+ property bool roundTop: true
10
+ preferredRendererType: Shape.CurveRenderer
11
+
12
+ ShaderEffectSource {
13
+ id: texture
14
+ sourceItem: root.target
15
+ hideSource: true
16
+ visible: false
17
+ }
18
+ ShapePath {
19
+ strokeWidth: -1
20
+ fillColor: "transparent"
21
+ fillItem: texture
22
+ PathRectangle {
23
+ width: root.width
24
+ height: root.height
25
+ radius: root.radius
26
+ topLeftRadius: root.roundTop ? root.radius : 0
27
+ topRightRadius: root.roundTop ? root.radius : 0
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,63 @@
1
+ import QtQuick
2
+ import "." as Flea
3
+ import "js/Icons.js" as Icons
4
+
5
+ // Quick Look uses the same bar as Markdown; the column loads only the document body.
6
+ Item {
7
+ id: root
8
+ property bool active: false
9
+ // flea-qml: the row's icon; an emoji one marks the bar instead of the HTML glyph.
10
+ property string iconName: ""
11
+ property string path: ""
12
+ property int size: 0
13
+ property string view: "rendered"
14
+ readonly property int byteCeiling: 1048576
15
+ property int maxBytes: byteCeiling
16
+ property bool truncate: false
17
+ property string blockPath: ""
18
+ property var backend: null
19
+ property bool wrap: false
20
+ property bool closeFocused: false
21
+ signal closeRequested
22
+ readonly property var viewport: doc.viewport
23
+ readonly property var bodyItem: doc.bodyItem
24
+ readonly property var document: doc
25
+ readonly property string rawText: doc.sourceCode ? doc.sourceCode.lines.join("\n") : ""
26
+ readonly property string status: doc.status
27
+ readonly property string lineLabel: doc.lineLabel
28
+ readonly property string shownView: doc.shownView
29
+ readonly property bool contentReady: doc.contentReady
30
+ readonly property bool firstScreen: doc.firstScreen
31
+ readonly property real scrollY: doc.scrollY
32
+ function endGap() { return doc.endGap() }
33
+ function closeState() { return bar.closeState() }
34
+ function barGeometry() { var g = bar.geometry(); g.ready = root.contentReady; return g }
35
+ function scrollBy(rows) { doc.scrollBy(rows) }
36
+ function zoomBy(steps) { doc.zoomBy(steps) }
37
+ function zoomFit() { doc.zoomFit() }
38
+ function tableScroller() { return null }
39
+
40
+ Flea.QuickLookBar {
41
+ id: bar
42
+ anchors { top: parent.top; left: parent.left; right: parent.right }
43
+ markName: Icons.isEmoji(root.iconName) ? root.iconName : "html"
44
+ name: root.path.substring(root.path.lastIndexOf("/") + 1)
45
+ countLabel: root.contentReady ? root.lineLabel : ""
46
+ closeFocused: root.closeFocused
47
+ onCloseRequested: root.closeRequested()
48
+ }
49
+ Flea.PreviewHtml {
50
+ id: doc
51
+ anchors.fill: parent
52
+ anchors.topMargin: bar.height
53
+ active: root.active
54
+ path: root.path
55
+ size: root.size
56
+ view: root.view
57
+ maxBytes: root.maxBytes
58
+ truncate: root.truncate
59
+ backend: root.backend
60
+ slot: "look"
61
+ wrap: root.wrap
62
+ }
63
+ }
@@ -0,0 +1,45 @@
1
+ import QtQuick
2
+ import QtQuick.Shapes
3
+ import qs.Commons
4
+
5
+ // The Hyprland droplet, reproduced rather than recut, the same ruling that brought TailscaleMark and
6
+ // DropboxMark back: a brand row carries the brand's own mark and never a generic glyph. Outside the
7
+ // cut and outside Glyph.qml, where FleaMark sits.
8
+ Item {
9
+ id: root
10
+
11
+ // The type scale, not the slot, and clamped so a reproduction can never out-size the cut glyph
12
+ // beside it. A smaller caller slot still wins, the way Glyph's own min() lets it.
13
+ property real iconSize: Theme.markSize
14
+ property color color: "transparent"
15
+
16
+ // The artwork is drawn on the same 24 unit grid every mark in this tree uses.
17
+ readonly property real grid: 24
18
+ readonly property real drawn: Math.min(Theme.markSize, root.iconSize)
19
+
20
+ implicitWidth: root.drawn
21
+ implicitHeight: root.drawn
22
+ width: root.drawn
23
+ height: root.drawn
24
+
25
+ Shape {
26
+ width: root.grid
27
+ height: root.grid
28
+ // Scale's origin defaults to (0,0), so the grid box is scaled from the top left into the slot.
29
+ transform: Scale { xScale: root.drawn / root.grid; yScale: root.drawn / root.grid }
30
+ preferredRendererType: Shape.CurveRenderer
31
+
32
+ // The hollow centre is the even-odd rule over one subpath pair, which is how the artwork cuts it.
33
+ ShapePath {
34
+ fillColor: root.color
35
+ fillRule: ShapePath.OddEvenFill
36
+ strokeColor: "transparent"
37
+ strokeWidth: 0
38
+
39
+ PathSvg {
40
+ path: "M12 2.2c4 5.4 6.9 9.4 6.9 12.6a6.9 6.9 0 1 1-13.8 0c0-3.2 2.9-7.2 6.9-12.6Z"
41
+ + "M12 8.1c-2.4 3.3-4.1 5.8-4.1 7.6a4.1 4.1 0 0 0 8.2 0c0-1.8-1.7-4.3-4.1-7.6Z"
42
+ }
43
+ }
44
+ }
45
+ }