flea-qml 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (637) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +511 -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 +407 -0
  51. package/src/archiveops.js +728 -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 +135 -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/terminal-server.js +95 -0
  82. package/src/terminal-shell.js +26 -0
  83. package/src/transfer.js +669 -0
  84. package/src/trash-record.js +41 -0
  85. package/src/trash.js +210 -0
  86. package/src/trashbrowse.js +327 -0
  87. package/src/uistate.js +393 -0
  88. package/src/uistore.js +168 -0
  89. package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
  90. package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
  91. package/src/vendor/LICENSES/MIT-katex.txt +21 -0
  92. package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
  93. package/src/vendor/LICENSES/MIT-pele.txt +40 -0
  94. package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
  95. package/src/vendor/LICENSES/MIT-temml.txt +21 -0
  96. package/src/vendor/pele.js +145 -0
  97. package/src/vendor/temml.mjs +14708 -0
  98. package/src/watch.js +98 -0
  99. package/src/wayland/client.js +109 -0
  100. package/src/wayland/protocol.js +55 -0
  101. package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
  102. package/src/wayland/protocols/wayland.xml +3248 -0
  103. package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
  104. package/src/wayland/resource-io.js +6 -0
  105. package/src/wayland/socket-discovery.js +26 -0
  106. package/src/wayland/transport-posix.js +120 -0
  107. package/src/wayland/transport-win32.js +11 -0
  108. package/src/wayland/transport.js +3 -0
  109. package/src/wayland/win32-resources.js +80 -0
  110. package/src/wayland/win32-wire.js +62 -0
  111. package/test/archive.test.js +80 -0
  112. package/test/bench-markdown-scroll.mjs +190 -0
  113. package/test/clip-host.test.js +113 -0
  114. package/test/code-preview.test.js +35 -0
  115. package/test/compare-ui-paths.test.js +24 -0
  116. package/test/compare.test.js +54 -0
  117. package/test/delete-trash.test.js +67 -0
  118. package/test/dirsize.test.js +138 -0
  119. package/test/file-ops.test.js +307 -0
  120. package/test/file-url.test.js +24 -0
  121. package/test/find-contents.test.js +161 -0
  122. package/test/find-input.test.js +66 -0
  123. package/test/fixtures/pele-parity.json +1006 -0
  124. package/test/highlight-launcher.test.js +35 -0
  125. package/test/html-preview.test.js +22 -0
  126. package/test/input.test.js +15 -0
  127. package/test/keymap.test.js +26 -0
  128. package/test/language-icons.test.js +36 -0
  129. package/test/launcher.test.js +51 -0
  130. package/test/manual-archive-here-ui.mjs +47 -0
  131. package/test/manual-code-scroll.mjs +28 -0
  132. package/test/manual-column-scroll.mjs +24 -0
  133. package/test/manual-compare-ui.mjs +20 -0
  134. package/test/manual-find-status.mjs +37 -0
  135. package/test/manual-folder-focus.mjs +63 -0
  136. package/test/manual-html-security.mjs +23 -0
  137. package/test/manual-html-ui.mjs +30 -0
  138. package/test/manual-syntax-preview.mjs +26 -0
  139. package/test/manual-terminal-lifecycle.mjs +42 -0
  140. package/test/manual-terminal-navigation.mjs +48 -0
  141. package/test/manual-terminal-ui.mjs +47 -0
  142. package/test/manual-trash-ui.mjs +86 -0
  143. package/test/markdown-diagrams.test.js +93 -0
  144. package/test/markdown-html.test.js +105 -0
  145. package/test/mathml.test.js +92 -0
  146. package/test/menu-transfer.test.js +57 -0
  147. package/test/office-preview.test.js +154 -0
  148. package/test/pele-parity.test.js +28 -0
  149. package/test/places.test.js +134 -0
  150. package/test/preview-keys.test.js +60 -0
  151. package/test/preview-language.test.js +22 -0
  152. package/test/status-filename.test.js +20 -0
  153. package/test/transfer-replace-merge.test.js +187 -0
  154. package/test/trash-address.test.js +23 -0
  155. package/test/trash-view.test.js +37 -0
  156. package/test/trashbrowse.test.js +135 -0
  157. package/ui/AboutFacts.qml +78 -0
  158. package/ui/ArchiveCards.qml +95 -0
  159. package/ui/ArchiveCompressDialog.qml +378 -0
  160. package/ui/ArchiveHereConfirm.qml +127 -0
  161. package/ui/ArchivePasswordDialog.qml +257 -0
  162. package/ui/Backend.qml +775 -0
  163. package/ui/BulkOldNames.qml +47 -0
  164. package/ui/BulkRenameDialog.qml +380 -0
  165. package/ui/CardFrame.qml +67 -0
  166. package/ui/CardScroll.qml +79 -0
  167. package/ui/CheckBox.qml +73 -0
  168. package/ui/ChromeBar.qml +360 -0
  169. package/ui/ChromeButton.qml +131 -0
  170. package/ui/ChromeModes.qml +43 -0
  171. package/ui/CodeLines.qml +256 -0
  172. package/ui/CodeRefusal.qml +52 -0
  173. package/ui/CollideConfirm.qml +147 -0
  174. package/ui/CollideHost.qml +167 -0
  175. package/ui/ColumnPane.qml +525 -0
  176. package/ui/ColumnRow.qml +380 -0
  177. package/ui/ColumnsArea.qml +594 -0
  178. package/ui/ColumnsLanding.qml +147 -0
  179. package/ui/CompareView.qml +321 -0
  180. package/ui/ContextMenu.qml +743 -0
  181. package/ui/ConvertDialog.qml +456 -0
  182. package/ui/CountedWorker.qml +7 -0
  183. package/ui/Crumb.qml +64 -0
  184. package/ui/CrumbDrop.qml +25 -0
  185. package/ui/CsvTable.qml +394 -0
  186. package/ui/CursorMark.qml +41 -0
  187. package/ui/DefaultClaim.qml +130 -0
  188. package/ui/DeviceLock.qml +47 -0
  189. package/ui/DeviceMounts.qml +540 -0
  190. package/ui/DialogButton.qml +150 -0
  191. package/ui/DialogField.qml +147 -0
  192. package/ui/DialogHeader.qml +31 -0
  193. package/ui/DialogScrim.qml +20 -0
  194. package/ui/DialogTitle.qml +37 -0
  195. package/ui/Divider.qml +9 -0
  196. package/ui/DropInto.qml +126 -0
  197. package/ui/DropTarget.qml +35 -0
  198. package/ui/DropboxMark.qml +60 -0
  199. package/ui/EmptyState.qml +150 -0
  200. package/ui/EscapeHint.qml +11 -0
  201. package/ui/FactsTable.qml +54 -0
  202. package/ui/FastScrollHandler.qml +476 -0
  203. package/ui/FatNamesConfirm.qml +157 -0
  204. package/ui/Favourites.qml +143 -0
  205. package/ui/FigureService.qml +120 -0
  206. package/ui/FileDrag.qml +267 -0
  207. package/ui/FilterStrip.qml +133 -0
  208. package/ui/FitMetrics.qml +22 -0
  209. package/ui/FlashDriveRows.qml +137 -0
  210. package/ui/FlashHost.qml +72 -0
  211. package/ui/FlashImageRow.qml +104 -0
  212. package/ui/FlashRunner.qml +119 -0
  213. package/ui/FlashStepRow.qml +172 -0
  214. package/ui/FlashStrip.qml +38 -0
  215. package/ui/FlashView.qml +397 -0
  216. package/ui/FleaMark.qml +88 -0
  217. package/ui/FlyoutFade.qml +23 -0
  218. package/ui/FontPane.qml +170 -0
  219. package/ui/Glass.qml +114 -0
  220. package/ui/GlassTagger.qml +59 -0
  221. package/ui/Glyph.qml +64 -0
  222. package/ui/GlyphSolid.qml +22 -0
  223. package/ui/GridArea.qml +664 -0
  224. package/ui/GridTile.qml +325 -0
  225. package/ui/GvfsBridge.qml +164 -0
  226. package/ui/Header.qml +433 -0
  227. package/ui/HoverTimers.qml +39 -0
  228. package/ui/HtmlClip.qml +30 -0
  229. package/ui/HtmlPane.qml +63 -0
  230. package/ui/HyprlandMark.qml +45 -0
  231. package/ui/Ipc.qml +1005 -0
  232. package/ui/IpcControls.qml +7 -0
  233. package/ui/IpcMenuState.qml +48 -0
  234. package/ui/IpcPreviewState.qml +185 -0
  235. package/ui/JumpPath.qml +51 -0
  236. package/ui/KeymapSheet.qml +561 -0
  237. package/ui/KeymapSheetResult.qml +89 -0
  238. package/ui/KindStack.qml +40 -0
  239. package/ui/LangMark.qml +51 -0
  240. package/ui/LangMarkLoader.qml +26 -0
  241. package/ui/List.qml +480 -0
  242. package/ui/LoadingState.qml +54 -0
  243. package/ui/LocalSend.qml +56 -0
  244. package/ui/LocalSendMark.qml +73 -0
  245. package/ui/MarkdownBlockView.qml +311 -0
  246. package/ui/MarkdownBlocks.qml +35 -0
  247. package/ui/MarkdownFigure.qml +254 -0
  248. package/ui/MarkdownImages.qml +72 -0
  249. package/ui/MarkdownList.qml +81 -0
  250. package/ui/MarkdownMathsText.qml +97 -0
  251. package/ui/MarkdownPane.qml +83 -0
  252. package/ui/MarkdownPictures.qml +41 -0
  253. package/ui/MarkdownQuote.qml +52 -0
  254. package/ui/MarkdownRemote.qml +82 -0
  255. package/ui/MarkdownSource.qml +155 -0
  256. package/ui/MarkdownTable.qml +222 -0
  257. package/ui/MarkdownTableScroll.qml +64 -0
  258. package/ui/MarkdownTableWheel.qml +126 -0
  259. package/ui/MarkdownText.qml +87 -0
  260. package/ui/MarkdownWorker.js +132 -0
  261. package/ui/MatchText.qml +99 -0
  262. package/ui/MediaSession.qml +38 -0
  263. package/ui/MediaSound.qml +26 -0
  264. package/ui/MediaStrip.qml +191 -0
  265. package/ui/MediaTrack.qml +36 -0
  266. package/ui/MediaVolume.qml +54 -0
  267. package/ui/MenuActionDialog.qml +396 -0
  268. package/ui/MenuEdgeFade.qml +24 -0
  269. package/ui/MenuHost.qml +227 -0
  270. package/ui/MenuRow.qml +351 -0
  271. package/ui/MountListing.qml +100 -0
  272. package/ui/NetworkDialog.qml +435 -0
  273. package/ui/NetworkForm.qml +426 -0
  274. package/ui/NetworkMounts.qml +913 -0
  275. package/ui/NetworkPlaces.qml +127 -0
  276. package/ui/OpenWithDialog.qml +613 -0
  277. package/ui/Opener.qml +95 -0
  278. package/ui/Pane.qml +1320 -0
  279. package/ui/PaneMenuActions.qml +527 -0
  280. package/ui/PanePath.qml +90 -0
  281. package/ui/PaneRail.qml +268 -0
  282. package/ui/PaneStates.qml +88 -0
  283. package/ui/PaneSwap.qml +339 -0
  284. package/ui/PaneWire.qml +601 -0
  285. package/ui/ParkedWait.qml +9 -0
  286. package/ui/PathEntry.qml +186 -0
  287. package/ui/PathJump.qml +400 -0
  288. package/ui/PdfViewer.qml +297 -0
  289. package/ui/PermissionsDialog.qml +658 -0
  290. package/ui/PermissionsHeadings.qml +31 -0
  291. package/ui/PhoneMounts.qml +67 -0
  292. package/ui/PickerAnswers.qml +75 -0
  293. package/ui/PickerBox.qml +26 -0
  294. package/ui/PickerChrome.qml +295 -0
  295. package/ui/PickerFilter.qml +97 -0
  296. package/ui/PickerGrid.qml +308 -0
  297. package/ui/PickerHeader.qml +28 -0
  298. package/ui/PickerLifecycle.qml +27 -0
  299. package/ui/PickerList.qml +218 -0
  300. package/ui/PickerListing.qml +149 -0
  301. package/ui/PickerPathBar.qml +127 -0
  302. package/ui/PickerPlaces.qml +189 -0
  303. package/ui/PickerRecent.qml +92 -0
  304. package/ui/PickerSave.qml +101 -0
  305. package/ui/PickerSelection.qml +155 -0
  306. package/ui/PickerWindow.qml +846 -0
  307. package/ui/PowerSectorsReader.qml +10 -0
  308. package/ui/PrebuildDriver.qml +146 -0
  309. package/ui/Preview.qml +1005 -0
  310. package/ui/PreviewAnimation.qml +24 -0
  311. package/ui/PreviewArchive.qml +91 -0
  312. package/ui/PreviewColumn.qml +553 -0
  313. package/ui/PreviewEdge.qml +63 -0
  314. package/ui/PreviewFacts.qml +30 -0
  315. package/ui/PreviewFactsLine.qml +34 -0
  316. package/ui/PreviewHtml.qml +233 -0
  317. package/ui/PreviewImage.qml +253 -0
  318. package/ui/PreviewImagePan.qml +13 -0
  319. package/ui/PreviewImageSharp.qml +32 -0
  320. package/ui/PreviewLines.qml +106 -0
  321. package/ui/PreviewMarkdown.qml +706 -0
  322. package/ui/PreviewMedia.qml +250 -0
  323. package/ui/PreviewPdf.qml +482 -0
  324. package/ui/PreviewScroll.qml +201 -0
  325. package/ui/PreviewSwap.qml +335 -0
  326. package/ui/PreviewText.qml +149 -0
  327. package/ui/ProtocolChip.qml +18 -0
  328. package/ui/QuickLookArchive.qml +41 -0
  329. package/ui/QuickLookBar.qml +103 -0
  330. package/ui/QuickLookPrepare.qml +355 -0
  331. package/ui/QuickLookSwap.qml +10 -0
  332. package/ui/QuickLookWarm.qml +65 -0
  333. package/ui/RailDrop.qml +155 -0
  334. package/ui/RailHeading.qml +19 -0
  335. package/ui/RailPlaces.qml +38 -0
  336. package/ui/RailTrashRow.qml +67 -0
  337. package/ui/RenameField.qml +353 -0
  338. package/ui/RendererRetry.qml +11 -0
  339. package/ui/ResizeHandle.qml +52 -0
  340. package/ui/Reveal.qml +54 -0
  341. package/ui/Row.qml +476 -0
  342. package/ui/RowDrag.qml +213 -0
  343. package/ui/RowDropTarget.qml +27 -0
  344. package/ui/RunCard.qml +286 -0
  345. package/ui/Scripts.qml +65 -0
  346. package/ui/SearchStrip.qml +232 -0
  347. package/ui/SelectionBand.qml +140 -0
  348. package/ui/SelectionPreview.qml +370 -0
  349. package/ui/SettingsFavourite.qml +122 -0
  350. package/ui/SettingsGroup.qml +96 -0
  351. package/ui/SettingsHint.qml +12 -0
  352. package/ui/SettingsMetrics.qml +29 -0
  353. package/ui/SettingsPane.qml +178 -0
  354. package/ui/SettingsPanel.qml +547 -0
  355. package/ui/SettingsRail.qml +128 -0
  356. package/ui/SettingsRow.qml +409 -0
  357. package/ui/SettingsRuler.qml +85 -0
  358. package/ui/SettingsSegment.qml +85 -0
  359. package/ui/ShareBrowser.qml +113 -0
  360. package/ui/ShareLink.qml +67 -0
  361. package/ui/ShelfPins.qml +101 -0
  362. package/ui/Sidebar.qml +728 -0
  363. package/ui/SidebarRow.qml +358 -0
  364. package/ui/Spinner.qml +60 -0
  365. package/ui/StableModel.qml +89 -0
  366. package/ui/StateMessage.qml +84 -0
  367. package/ui/StatusBar.qml +512 -0
  368. package/ui/StatusFileName.qml +27 -0
  369. package/ui/TabBar.qml +673 -0
  370. package/ui/TabDragGeometry.qml +60 -0
  371. package/ui/TagMenuMark.qml +52 -0
  372. package/ui/TagRailSection.qml +53 -0
  373. package/ui/TagSlot.qml +40 -0
  374. package/ui/TagState.qml +150 -0
  375. package/ui/TagSwatch.qml +28 -0
  376. package/ui/Taildrop.qml +86 -0
  377. package/ui/TailscaleMark.qml +50 -0
  378. package/ui/TerminalService.qml +69 -0
  379. package/ui/TerminalTab.qml +48 -0
  380. package/ui/TerminalTabs.qml +27 -0
  381. package/ui/Theme.qml +460 -0
  382. package/ui/ThemeColors.qml +43 -0
  383. package/ui/TransferCard.qml +239 -0
  384. package/ui/TrashConfirm.qml +129 -0
  385. package/ui/TrashDropHandler.qml +11 -0
  386. package/ui/TrashHost.qml +202 -0
  387. package/ui/TrashMonitor.qml +30 -0
  388. package/ui/TrashToolbar.qml +19 -0
  389. package/ui/TrashView.qml +492 -0
  390. package/ui/UnlockDialog.qml +450 -0
  391. package/ui/UnlockHost.qml +206 -0
  392. package/ui/UpdateCheck.qml +97 -0
  393. package/ui/UserDirs.qml +25 -0
  394. package/ui/ViewState.qml +565 -0
  395. package/ui/ViewportScrollBar.qml +195 -0
  396. package/ui/ViewportScrollBars.qml +25 -0
  397. package/ui/WebPreview.qml +33 -0
  398. package/ui/WebPreviewView.qml +26 -0
  399. package/ui/WindowBody.qml +829 -0
  400. package/ui/WindowDrag.qml +35 -0
  401. package/ui/boot/Commons/AudioNodes.qml +50 -0
  402. package/ui/boot/Commons/AudioNodesModel.js +96 -0
  403. package/ui/boot/Commons/Border.qml +243 -0
  404. package/ui/boot/Commons/BorderGeometry.js +373 -0
  405. package/ui/boot/Commons/Color.qml +258 -0
  406. package/ui/boot/Commons/I18n.qml +118 -0
  407. package/ui/boot/Commons/InputDevices.qml +112 -0
  408. package/ui/boot/Commons/InputMethodState.qml +38 -0
  409. package/ui/boot/Commons/IpcRegistry.qml +77 -0
  410. package/ui/boot/Commons/Numbers.js +19 -0
  411. package/ui/boot/Commons/Plural.js +91 -0
  412. package/ui/boot/Commons/ShellIpc.qml +12 -0
  413. package/ui/boot/Commons/Style.qml +561 -0
  414. package/ui/boot/Commons/Translations.qml +100 -0
  415. package/ui/boot/Commons/UntypedInput.qml +152 -0
  416. package/ui/boot/Commons/Util.qml +188 -0
  417. package/ui/boot/Commons/qmldir +13 -0
  418. package/ui/boot/LICENSE-omarchy +20 -0
  419. package/ui/boot/Ui/BackgroundMedia.qml +49 -0
  420. package/ui/boot/Ui/BarIconButton.qml +106 -0
  421. package/ui/boot/Ui/BarIconContent.qml +38 -0
  422. package/ui/boot/Ui/BarIndicator.qml +53 -0
  423. package/ui/boot/Ui/BarWidget.qml +50 -0
  424. package/ui/boot/Ui/BorderOverlay.qml +54 -0
  425. package/ui/boot/Ui/BorderSurface.qml +40 -0
  426. package/ui/boot/Ui/Button.qml +224 -0
  427. package/ui/boot/Ui/ButtonGroup.qml +131 -0
  428. package/ui/boot/Ui/ConfirmDialog.qml +134 -0
  429. package/ui/boot/Ui/CursorSurface.qml +42 -0
  430. package/ui/boot/Ui/Dropdown.qml +245 -0
  431. package/ui/boot/Ui/FilterInput.qml +26 -0
  432. package/ui/boot/Ui/IconContentBounds.qml +141 -0
  433. package/ui/boot/Ui/KeyboardPanel.qml +453 -0
  434. package/ui/boot/Ui/MultiSelect.qml +624 -0
  435. package/ui/boot/Ui/NumberField.qml +86 -0
  436. package/ui/boot/Ui/OpticalGlyph.qml +68 -0
  437. package/ui/boot/Ui/OverlayWindow.qml +102 -0
  438. package/ui/boot/Ui/Panel.qml +60 -0
  439. package/ui/boot/Ui/PanelActionButton.qml +105 -0
  440. package/ui/boot/Ui/PanelController.qml +16 -0
  441. package/ui/boot/Ui/PanelHero.qml +112 -0
  442. package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
  443. package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
  444. package/ui/boot/Ui/PanelSeparator.qml +19 -0
  445. package/ui/boot/Ui/PanelSlider.qml +156 -0
  446. package/ui/boot/Ui/PanelToolTip.qml +50 -0
  447. package/ui/boot/Ui/PluginBarApi.qml +89 -0
  448. package/ui/boot/Ui/PointerMoveGate.qml +54 -0
  449. package/ui/boot/Ui/PopupCard.qml +181 -0
  450. package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
  451. package/ui/boot/Ui/SearchableDropdown.qml +354 -0
  452. package/ui/boot/Ui/SizedImage.qml +125 -0
  453. package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
  454. package/ui/boot/Ui/TextField.qml +58 -0
  455. package/ui/boot/Ui/Toggle.qml +118 -0
  456. package/ui/boot/Ui/ToggleSwitch.qml +115 -0
  457. package/ui/boot/Ui/WidgetButton.qml +172 -0
  458. package/ui/boot/Ui/qmldir +41 -0
  459. package/ui/boot/fleatab.qml +50 -0
  460. package/ui/boot/picker.qml +39 -0
  461. package/ui/boot/shell.qml +131 -0
  462. package/ui/boot/tabtearoff.qml +51 -0
  463. package/ui/js/Anchor.js +379 -0
  464. package/ui/js/AnchorHold.js +162 -0
  465. package/ui/js/Archive.js +157 -0
  466. package/ui/js/ArchiveCard.js +44 -0
  467. package/ui/js/ArchiveOps.js +44 -0
  468. package/ui/js/BackReturn.js +118 -0
  469. package/ui/js/BulkRename.js +100 -0
  470. package/ui/js/Buttons.js +54 -0
  471. package/ui/js/ChromeKeys.js +116 -0
  472. package/ui/js/ClipMarks.js +73 -0
  473. package/ui/js/ClipSelection.js +67 -0
  474. package/ui/js/Clipboard.js +179 -0
  475. package/ui/js/Cloud.js +97 -0
  476. package/ui/js/CodeRuns.js +72 -0
  477. package/ui/js/Collide.js +212 -0
  478. package/ui/js/ColumnFit.js +28 -0
  479. package/ui/js/ColumnMenu.js +111 -0
  480. package/ui/js/Columns.js +298 -0
  481. package/ui/js/ColumnsCarry.js +103 -0
  482. package/ui/js/Compare.js +74 -0
  483. package/ui/js/Contrast.js +157 -0
  484. package/ui/js/ControlReader.js +42 -0
  485. package/ui/js/Convert.js +52 -0
  486. package/ui/js/CopyAs.js +52 -0
  487. package/ui/js/Crumbs.js +178 -0
  488. package/ui/js/Csv.js +231 -0
  489. package/ui/js/Density.js +44 -0
  490. package/ui/js/Devices.js +440 -0
  491. package/ui/js/DirSizes.js +180 -0
  492. package/ui/js/Drag.js +360 -0
  493. package/ui/js/DragOut.js +166 -0
  494. package/ui/js/DropDev.js +52 -0
  495. package/ui/js/Dropbox.js +41 -0
  496. package/ui/js/Eject.js +217 -0
  497. package/ui/js/Errors.js +188 -0
  498. package/ui/js/ExtThumbs.js +115 -0
  499. package/ui/js/Facts.js +402 -0
  500. package/ui/js/FigureDate.js +14 -0
  501. package/ui/js/Filter.js +285 -0
  502. package/ui/js/Find.js +46 -0
  503. package/ui/js/Flash.js +184 -0
  504. package/ui/js/FlashCard.js +79 -0
  505. package/ui/js/FlashEndings.js +125 -0
  506. package/ui/js/FlashPane.js +116 -0
  507. package/ui/js/FleaBin.js +12 -0
  508. package/ui/js/Focus.js +504 -0
  509. package/ui/js/FolderSorts.js +108 -0
  510. package/ui/js/FolderViews.js +44 -0
  511. package/ui/js/Format.js +314 -0
  512. package/ui/js/Fuzzy.js +141 -0
  513. package/ui/js/GlassTag.js +72 -0
  514. package/ui/js/Grid.js +33 -0
  515. package/ui/js/GridGeometry.js +90 -0
  516. package/ui/js/GridNames.js +153 -0
  517. package/ui/js/GvfsBridge.js +200 -0
  518. package/ui/js/HostClipboard.js +29 -0
  519. package/ui/js/Icons.js +218 -0
  520. package/ui/js/Input.js +50 -0
  521. package/ui/js/Jump.js +200 -0
  522. package/ui/js/KeyName.js +64 -0
  523. package/ui/js/Keymap.js +401 -0
  524. package/ui/js/Kinds.js +164 -0
  525. package/ui/js/LICENSES/ISC-lucide.txt +43 -0
  526. package/ui/js/LangMarkPaths.js +47 -0
  527. package/ui/js/LangMarks.js +120 -0
  528. package/ui/js/Lists.js +11 -0
  529. package/ui/js/LocalSend.js +39 -0
  530. package/ui/js/LockedMenu.js +63 -0
  531. package/ui/js/MakeDefault.js +186 -0
  532. package/ui/js/MarkBox.js +7 -0
  533. package/ui/js/Markdown.js +119 -0
  534. package/ui/js/MarkdownLists.js +86 -0
  535. package/ui/js/MarkdownMaths.js +58 -0
  536. package/ui/js/MarkdownPictures.js +32 -0
  537. package/ui/js/MarkdownPrepared.js +139 -0
  538. package/ui/js/MarkdownTableFit.js +34 -0
  539. package/ui/js/Marks.js +148 -0
  540. package/ui/js/Marquee.js +96 -0
  541. package/ui/js/Match.js +93 -0
  542. package/ui/js/Material.js +109 -0
  543. package/ui/js/MdBlocks.js +437 -0
  544. package/ui/js/MdBreak.js +71 -0
  545. package/ui/js/MdChunks.js +70 -0
  546. package/ui/js/MdContainer.js +137 -0
  547. package/ui/js/MdDocument.js +337 -0
  548. package/ui/js/MdEmph.js +97 -0
  549. package/ui/js/MdEntity.js +108 -0
  550. package/ui/js/MdEntityTable.js +223 -0
  551. package/ui/js/MdEscape.js +59 -0
  552. package/ui/js/MdFront.js +37 -0
  553. package/ui/js/MdHold.js +32 -0
  554. package/ui/js/MdHtml.js +307 -0
  555. package/ui/js/MdHtmlBlock.js +290 -0
  556. package/ui/js/MdHtmlHeading.js +53 -0
  557. package/ui/js/MdHtmlImage.js +179 -0
  558. package/ui/js/MdInline.js +154 -0
  559. package/ui/js/MdItems.js +212 -0
  560. package/ui/js/MdLeaf.js +309 -0
  561. package/ui/js/MdLink.js +196 -0
  562. package/ui/js/MdMath.js +67 -0
  563. package/ui/js/MdParagraphs.js +138 -0
  564. package/ui/js/MdRefs.js +232 -0
  565. package/ui/js/MdResolve.js +226 -0
  566. package/ui/js/MdRun.js +300 -0
  567. package/ui/js/MdUrl.js +226 -0
  568. package/ui/js/Menu.js +514 -0
  569. package/ui/js/MenuContext.js +85 -0
  570. package/ui/js/MenuFit.js +13 -0
  571. package/ui/js/MenuRefresh.js +74 -0
  572. package/ui/js/MenuWheel.js +35 -0
  573. package/ui/js/Messages.js +186 -0
  574. package/ui/js/Motion.js +16 -0
  575. package/ui/js/Mounts.js +320 -0
  576. package/ui/js/MouseNav.js +13 -0
  577. package/ui/js/Nav.js +329 -0
  578. package/ui/js/NetFs.js +26 -0
  579. package/ui/js/OpenWith.js +83 -0
  580. package/ui/js/Ops.js +585 -0
  581. package/ui/js/Palette.js +33 -0
  582. package/ui/js/PathBar.js +260 -0
  583. package/ui/js/Permissions.js +179 -0
  584. package/ui/js/Phones.js +112 -0
  585. package/ui/js/Picker.js +353 -0
  586. package/ui/js/PlaceMenu.js +96 -0
  587. package/ui/js/Places.js +265 -0
  588. package/ui/js/PreviewAsk.js +21 -0
  589. package/ui/js/PreviewKeys.js +155 -0
  590. package/ui/js/PreviewSettle.js +29 -0
  591. package/ui/js/PreviewSwap.js +101 -0
  592. package/ui/js/PropertyFacts.js +144 -0
  593. package/ui/js/Protocols.js +296 -0
  594. package/ui/js/QuickLookKinds.js +27 -0
  595. package/ui/js/QuickLookRect.js +24 -0
  596. package/ui/js/RailDrop.js +51 -0
  597. package/ui/js/RailKeys.js +87 -0
  598. package/ui/js/RailMenu.js +133 -0
  599. package/ui/js/Recent.js +135 -0
  600. package/ui/js/RecentMode.js +156 -0
  601. package/ui/js/Reload.js +60 -0
  602. package/ui/js/Renderer.js +9 -0
  603. package/ui/js/RunFile.js +143 -0
  604. package/ui/js/Scripts.js +28 -0
  605. package/ui/js/Scroll.js +304 -0
  606. package/ui/js/ScrollOff.js +69 -0
  607. package/ui/js/Search.js +478 -0
  608. package/ui/js/Selection.js +97 -0
  609. package/ui/js/Settings.js +476 -0
  610. package/ui/js/SettingsAbout.js +97 -0
  611. package/ui/js/SettingsShelf.js +52 -0
  612. package/ui/js/SheetKeys.js +42 -0
  613. package/ui/js/SheetQuery.js +281 -0
  614. package/ui/js/ShelfPile.js +27 -0
  615. package/ui/js/SlowClick.js +53 -0
  616. package/ui/js/SlowOp.js +6 -0
  617. package/ui/js/Sort.js +134 -0
  618. package/ui/js/Startup.js +63 -0
  619. package/ui/js/StateWords.js +17 -0
  620. package/ui/js/Status.js +238 -0
  621. package/ui/js/Swap.js +166 -0
  622. package/ui/js/TabMove.js +39 -0
  623. package/ui/js/Tabs.js +751 -0
  624. package/ui/js/Tags.js +134 -0
  625. package/ui/js/Taildrop.js +128 -0
  626. package/ui/js/Tap.js +180 -0
  627. package/ui/js/TextSize.js +107 -0
  628. package/ui/js/Thumbs.js +158 -0
  629. package/ui/js/Transfer.js +172 -0
  630. package/ui/js/Trash.js +84 -0
  631. package/ui/js/TrashDates.js +47 -0
  632. package/ui/js/TrashDrop.js +64 -0
  633. package/ui/js/UiState.js +438 -0
  634. package/ui/js/Unlock.js +152 -0
  635. package/ui/js/Update.js +130 -0
  636. package/ui/js/UserDirs.js +56 -0
  637. package/ui/qmldir +230 -0
@@ -0,0 +1,147 @@
1
+ import QtQuick
2
+ import "js/Columns.js" as Columns
3
+ import "js/Swap.js" as Swap
4
+
5
+ // A changing ancestor keeps its own slot's last rows until the replacement or the listing swap's cap.
6
+ Item {
7
+ id: root
8
+ property var area: null
9
+ property string target: ""
10
+ property var held: ({})
11
+ property var previous: null
12
+ property int version: 0
13
+ property bool expired: false
14
+ property bool minimum: false
15
+ property double startedAt: 0
16
+ property double markSince: 0
17
+
18
+ function begin(carry, asks) {
19
+ var now = Date.now()
20
+ var next = {}, inheritedSince = 0, old = Columns.neighbourAsks(root.area.pane.path, root.area.width, root.area.columnsLimit)
21
+ if (carry) {
22
+ for (var i = 1; i <= asks.length; i++) {
23
+ var path = asks[asks.length - i], from = old[old.length - i]
24
+ var key = root.area.peekKey(path)
25
+ var ready = root.area.peeked[key] !== undefined && root.area.peekOrders[key] === root.area.orderOf(path)
26
+ if (ready || path === carry.seed && carry.rows !== null || !from) continue
27
+ var source = root.stateFor(from), reading = source !== null && root.isLoading(source, from)
28
+ var since = reading ? source.held[from].shownAt : undefined
29
+ next[path] = { rows: root.area.rowsFor(from), mode: root.area.deniedMode(from), ready: false,
30
+ loading: reading, shownAt: since }
31
+ if (since !== undefined) inheritedSince = Math.max(inheritedSince, since)
32
+ }
33
+ }
34
+ // Only a carried superseding request keeps the previous landing's cap and shown minimum.
35
+ if (!carry) root.previous = null
36
+ else if (root.target === root.area.pane.path) {
37
+ root.previous = Object.keys(root.held).length ? {
38
+ target: root.target, held: root.held, expired: root.expired, minimum: root.minimum,
39
+ startedAt: root.startedAt, markSince: root.markSince
40
+ } : null
41
+ }
42
+ root.target = carry ? carry.target : ""
43
+ root.held = next
44
+ root.expired = false
45
+ root.minimum = inheritedSince > 0 && inheritedSince + Swap.MIN_SHOW_MS > now
46
+ root.startedAt = now
47
+ root.markSince = inheritedSince
48
+ root.version++
49
+ root.armCap(); root.armMinimum()
50
+ }
51
+ function stateFor(path) {
52
+ if (root.version < 0) return null
53
+ var state = root.area.pane.path === root.target ? root : root.previous
54
+ return state && state.target === root.area.pane.path && state.held[path] !== undefined ? state : null
55
+ }
56
+ function waiting(path) { return root.stateFor(path) !== null }
57
+ function isLoading(state, path) { return state.expired || state.held[path].loading === true }
58
+ function loading(path) { var state = root.stateFor(path); return state !== null && root.isLoading(state, path) }
59
+ function rows(path, ordinary) {
60
+ var state = root.stateFor(path)
61
+ return state === null ? ordinary : root.isLoading(state, path) ? [] : state.held[path].rows
62
+ }
63
+ function mode(path, ordinary) {
64
+ var state = root.stateFor(path)
65
+ return state === null ? ordinary : root.isLoading(state, path) ? -1 : state.held[path].mode
66
+ }
67
+
68
+ function remove(path, state) {
69
+ var next = Object.assign({}, state.held)
70
+ delete next[path]
71
+ state.held = next
72
+ if (!Object.keys(next).length) {
73
+ state.minimum = false
74
+ if (state !== root) root.previous = null
75
+ }
76
+ root.version++
77
+ root.armCap(); root.armMinimum()
78
+ }
79
+ function answered(path) {
80
+ for (var state of [root, root.previous]) {
81
+ if (!state || state.held[path] === undefined) continue
82
+ if (root.isLoading(state, path) && state.minimum) {
83
+ var next = Object.assign({}, state.held)
84
+ next[path] = Object.assign({}, next[path], { ready: true })
85
+ state.held = next
86
+ root.version++
87
+ } else root.remove(path, state)
88
+ }
89
+ }
90
+ function landed() {
91
+ if (root.area.pane.path !== root.target) return
92
+ root.previous = null
93
+ root.version++
94
+ root.armCap(); root.armMinimum()
95
+ }
96
+ // Only the LoadingState's shown signal starts the minimum, including a mark built while its column is hidden.
97
+ function markShown(path, shown) {
98
+ var state = root.stateFor(path)
99
+ if (!shown || !state || !root.isLoading(state, path)) return
100
+ // Bookkeeping must not invalidate loadingRows while its Loader reports shown.
101
+ var now = Date.now()
102
+ state.held[path].shownAt = now
103
+ state.markSince = now
104
+ state.minimum = true
105
+ root.armMinimum()
106
+ }
107
+ // The same two timers serve both landings without restarting either deadline.
108
+ function armCap() {
109
+ cap.stop()
110
+ var left = -1, now = Date.now()
111
+ for (var state of [root, root.previous]) {
112
+ if (!state || state.expired || !Object.keys(state.held).length) continue
113
+ var owed = Math.max(0, state.startedAt + Swap.CAP_MS - now)
114
+ left = left < 0 ? owed : Math.min(left, owed)
115
+ }
116
+ if (left >= 0) { cap.interval = left; cap.start() }
117
+ }
118
+ function armMinimum() {
119
+ minShow.stop()
120
+ var left = -1, now = Date.now()
121
+ for (var state of [root, root.previous]) {
122
+ if (!state || !state.minimum) continue
123
+ var owed = Math.max(0, state.markSince + Swap.MIN_SHOW_MS - now)
124
+ left = left < 0 ? owed : Math.min(left, owed)
125
+ }
126
+ if (left >= 0) { minShow.interval = left; minShow.start() }
127
+ }
128
+ function expire() {
129
+ var now = Date.now()
130
+ for (var state of [root, root.previous])
131
+ if (state && !state.expired && state.startedAt + Swap.CAP_MS <= now) state.expired = true
132
+ root.version++
133
+ root.armCap()
134
+ }
135
+ function releaseMinimum() {
136
+ var now = Date.now()
137
+ for (var state of [root, root.previous]) {
138
+ if (!state || !state.minimum || state.markSince + Swap.MIN_SHOW_MS > now) continue
139
+ state.minimum = false
140
+ var paths = Object.keys(state.held)
141
+ for (var path of paths) if (state.held[path].ready) root.remove(path, state)
142
+ }
143
+ root.armMinimum()
144
+ }
145
+ Timer { id: cap; onTriggered: root.expire() }
146
+ Timer { id: minShow; onTriggered: root.releaseMinimum() }
147
+ }
@@ -0,0 +1,321 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+ import "." as Flea
4
+ import "js/CodeRuns.js" as CodeRuns
5
+ import "js/Compare.js" as Compare
6
+ import "js/Icons.js" as Icons
7
+ import "js/Kinds.js" as Kinds
8
+
9
+ // Quick Look's Compare kind: the unified diff of two files, coloured by ink alone, or the sentence that says why there is none.
10
+ Item {
11
+ id: root
12
+ readonly property alias viewport: view
13
+
14
+ // The backend asks and answers the diff; the opener holds the text copy route Copy as Path uses.
15
+ property var backend: null
16
+ property var opener: null
17
+ property bool active: false
18
+ property string pathA: ""
19
+ property string pathB: ""
20
+ property string iconName: ""
21
+
22
+ // "" until the backend has answered, then diff, identical, binary, over or failed.
23
+ property string answer: ""
24
+ property string patch: ""
25
+ // The token of the ask in flight, 0 when none: an answer for any other token is dropped.
26
+ property int token: 0
27
+ // Asks made, so a suite can tell one run of diff per open.
28
+ property int asks: 0
29
+ readonly property bool hasPatch: root.answer === "diff"
30
+ readonly property var rows: root.hasPatch ? Compare.rows(root.patch) : []
31
+ readonly property string titleText: Compare.title(Compare.leaf(root.pathA), Compare.leaf(root.pathB),
32
+ root.hasPatch ? Compare.changed(root.rows) : null)
33
+ // Quick Look reads this to hold the card back until the diff or the sentence can draw whole.
34
+ readonly property string status: root.answer === "" ? "loading" : "compare"
35
+ // Indexed by the code reply's role: the foreground, then red, green, yellow, blue, magenta and cyan.
36
+ readonly property var inks: CodeRuns.inks(Theme.palette, Theme.fallbackColor, String(Theme.color.foreground))
37
+ readonly property bool engine: root.backend !== null && typeof root.backend.askCompare === "function"
38
+
39
+ // Compare.html resolves its pixels at body 14, and each one follows the body from there.
40
+ readonly property int boardBodyPx: 14
41
+ readonly property int numberBoardWidth: 34
42
+ readonly property int columnBoardGap: 10
43
+ readonly property int signBoardWidth: 9
44
+ readonly property int copyPaddingBoardPx: 8
45
+ readonly property int contentMarginBoardPx: 12
46
+ readonly property int contentPaddingBoardPx: 16
47
+ readonly property real rowLineHeightFactor: 1.45
48
+ function boardPx(px) {
49
+ return Math.round(px * Theme.font.body / root.boardBodyPx)
50
+ }
51
+ readonly property int numberWidth: root.boardPx(root.numberBoardWidth)
52
+ readonly property int columnGap: root.boardPx(root.columnBoardGap)
53
+ readonly property int signWidth: root.boardPx(root.signBoardWidth)
54
+ readonly property int textX: 2 * root.numberWidth + root.signWidth + 3 * root.columnGap
55
+ readonly property int rowHeight: Math.round(Theme.font.body * root.rowLineHeightFactor) + 2 * Theme.spacing.hairline
56
+
57
+ signal closeRequested
58
+
59
+ function copyPatch() {
60
+ if (root.hasPatch && root.opener)
61
+ root.opener.copyText(root.patch)
62
+ }
63
+
64
+ // The pane consumes preview Tab, so Compare enters and cycles its own real controls.
65
+ function stepFocus(back) {
66
+ if (!root.active) return
67
+ var controls = root.hasPatch ? [copyButton, barClose] : [barClose]
68
+ var at = controls.indexOf(copyButton.activeFocus ? copyButton : barClose.activeFocus ? barClose : null)
69
+ var next = at < 0 ? (back ? controls.length - 1 : 0)
70
+ : (at + (back ? -1 : 1) + controls.length) % controls.length
71
+ controls[next].forceActiveFocus(back ? Qt.BacktabFocusReason : Qt.TabFocusReason)
72
+ }
73
+
74
+ // A new pair starts a new ask; the first waits for the end of the turn so one change of several properties asks once.
75
+ function fresh() {
76
+ root.answer = ""
77
+ root.patch = ""
78
+ root.token = 0
79
+ if (root.active && root.engine)
80
+ Qt.callLater(root.ask)
81
+ }
82
+
83
+ function ask() {
84
+ if (!root.active || !root.engine || root.token !== 0 || root.answer !== "" || root.pathA.length === 0 || root.pathB.length === 0)
85
+ return
86
+ root.asks += 1
87
+ root.token = root.backend.askCompare(root.pathA, root.pathB)
88
+ }
89
+
90
+ function answered(message) {
91
+ if (root.token === 0 || message.token !== root.token)
92
+ return
93
+ root.token = 0
94
+ root.patch = message.patch || ""
95
+ root.answer = message.state
96
+ }
97
+
98
+ function inkOf(kind) {
99
+ if (kind === "removed")
100
+ return root.inks[1]
101
+ if (kind === "added")
102
+ return root.inks[2]
103
+ if (kind === "hunk")
104
+ return root.inks[6]
105
+ return kind === "note" ? Theme.color.muted : Theme.color.foreground
106
+ }
107
+
108
+ // The render suite reads the bar's order and size off these, the way MarkdownPane hands its bar over.
109
+ function barGeometry() {
110
+ return { bar: bar, mark: barMark, markName: barMark.name, title: barTitle, copy: copyButton, close: barClose, ready: root.answer !== "" }
111
+ }
112
+
113
+ onPathAChanged: root.fresh()
114
+ onPathBChanged: root.fresh()
115
+ onActiveChanged: root.fresh()
116
+ onEngineChanged: root.fresh()
117
+
118
+ Connections {
119
+ target: root.engine ? root.backend : null
120
+ function onCompareResult(message) { root.answered(message) }
121
+ }
122
+
123
+ // No fill of its own: Quick Look's surface is already the chrome colour and rounds the corners this bar sits under.
124
+ Item {
125
+ id: bar
126
+ anchors.top: parent.top
127
+ anchors.left: parent.left
128
+ anchors.right: parent.right
129
+ height: Theme.chromeHeight
130
+
131
+ Rectangle {
132
+ anchors.bottom: parent.bottom
133
+ anchors.left: parent.left
134
+ anchors.right: parent.right
135
+ height: Theme.spacing.hairline
136
+ color: Theme.color.foreground
137
+ opacity: 0.12
138
+ }
139
+
140
+ // File a's kind mark, in foreground and centred above the rule like the Markdown bar's.
141
+ Flea.Glyph {
142
+ id: barMark
143
+ anchors.left: parent.left
144
+ anchors.leftMargin: Theme.spacing.rowPaddingX
145
+ y: Math.round((parent.height - Theme.spacing.hairline - height) / 2)
146
+ width: Theme.chromeMarkSize
147
+ height: Theme.chromeMarkSize
148
+ name: Kinds.isMarkdown(root.pathA) ? "markdown" : Icons.glyphFor(root.iconName)
149
+ color: Theme.color.foreground
150
+ }
151
+
152
+ // corner: a filename is arbitrary text, so PlainText, the same rule every name on this surface follows.
153
+ Text {
154
+ id: barTitle
155
+ anchors.left: barMark.right
156
+ anchors.leftMargin: Theme.spacing.gap
157
+ anchors.verticalCenter: parent.verticalCenter
158
+ width: Math.min(implicitWidth, Math.max(0, (root.hasPatch ? copyButton.x : barClose.x) - x - Theme.spacing.gap))
159
+ text: root.titleText
160
+ color: Theme.color.foreground
161
+ font.family: Theme.font.family
162
+ font.pixelSize: Theme.font.caption
163
+ textFormat: Text.PlainText
164
+ elide: Text.ElideMiddle
165
+ }
166
+
167
+ // The strip's shared button, so its rest, hover, focus, press and disabled looks are the recipe every strip button draws.
168
+ Flea.DialogButton {
169
+ id: copyButton
170
+ visible: root.hasPatch
171
+ anchors.right: barClose.left
172
+ anchors.rightMargin: Theme.spacing.gap
173
+ anchors.verticalCenter: parent.verticalCenter
174
+ label: "Copy patch"
175
+ inStrip: true
176
+ tabHandle: true
177
+ // Compare.html pads the label 8 either side of its 1 px frame; the recipe's own padding is the gap.
178
+ horizontalPadding: root.boardPx(root.copyPaddingBoardPx)
179
+ onActivated: root.copyPatch()
180
+ onTabbed: function(from, back) { root.stepFocus(back) }
181
+ }
182
+
183
+ Flea.ChromeButton {
184
+ id: barClose
185
+ gesturePolicy: TapHandler.ReleaseWithinBounds
186
+ ruleRows: Theme.spacing.hairline
187
+ anchors.right: parent.right
188
+ anchors.rightMargin: Theme.spacing.rowPaddingX
189
+ anchors.verticalCenter: parent.verticalCenter
190
+ glyph: "x"
191
+ accessName: "Close"
192
+ activeFocusOnTab: true
193
+ keyboardFocused: barClose.activeFocus
194
+ Keys.onTabPressed: function(event) { root.stepFocus((event.modifiers & Qt.ShiftModifier) !== 0) }
195
+ Keys.onBacktabPressed: root.stepFocus(true)
196
+ onActivated: root.closeRequested()
197
+ }
198
+ }
199
+
200
+ // A pair with no patch says why, in the board's one muted sentence.
201
+ Text {
202
+ visible: root.answer !== "" && !root.hasPatch
203
+ anchors.top: bar.bottom
204
+ anchors.bottom: parent.bottom
205
+ anchors.left: parent.left
206
+ anchors.right: parent.right
207
+ anchors.leftMargin: Theme.spacing.rowPaddingX
208
+ anchors.rightMargin: Theme.spacing.rowPaddingX
209
+ horizontalAlignment: Text.AlignHCenter
210
+ verticalAlignment: Text.AlignVCenter
211
+ text: Compare.sentence(root.answer)
212
+ color: Theme.color.muted
213
+ font.family: Theme.font.family
214
+ font.pixelSize: Theme.font.caption
215
+ textFormat: Text.PlainText
216
+ wrapMode: Text.Wrap
217
+ }
218
+
219
+ TextMetrics {
220
+ id: widest
221
+ font.family: Theme.font.family
222
+ font.pixelSize: Theme.font.body
223
+ text: root.hasPatch ? root.widestLine() : ""
224
+ }
225
+
226
+ function widestLine() {
227
+ var best = ""
228
+ for (var i = 0; i < root.rows.length; i++)
229
+ if (root.rows[i].text.length > best.length)
230
+ best = root.rows[i].text
231
+ return best
232
+ }
233
+
234
+ ListView {
235
+ id: view
236
+ visible: root.hasPatch
237
+ anchors.top: bar.bottom
238
+ anchors.bottom: parent.bottom
239
+ anchors.left: parent.left
240
+ anchors.right: parent.right
241
+ clip: true
242
+ topMargin: root.boardPx(root.contentMarginBoardPx)
243
+ bottomMargin: root.boardPx(root.contentMarginBoardPx)
244
+ boundsBehavior: Flickable.StopAtBounds
245
+ flickableDirection: Flickable.AutoFlickDirection
246
+ contentWidth: root.textX + widest.advanceWidth + root.boardPx(root.contentPaddingBoardPx)
247
+ model: root.rows
248
+
249
+ delegate: Item {
250
+ id: line
251
+ required property var modelData
252
+ // The delegate's one read of the overlay and of the list, so every other read below is qualified.
253
+ readonly property var host: root
254
+ readonly property var strip: view
255
+ readonly property color ink: line.host.inkOf(line.modelData.kind)
256
+ readonly property bool numbered: line.modelData.kind === "context" || line.modelData.kind === "removed" || line.modelData.kind === "added"
257
+ width: Math.max(line.strip.width, line.strip.contentWidth)
258
+ height: line.host.rowHeight
259
+
260
+ Text {
261
+ visible: line.numbered && line.modelData.oldNo > 0
262
+ x: 0
263
+ width: line.host.numberWidth
264
+ anchors.verticalCenter: parent.verticalCenter
265
+ horizontalAlignment: Text.AlignRight
266
+ text: String(line.modelData.oldNo)
267
+ color: Theme.color.muted
268
+ font.family: Theme.font.family
269
+ font.pixelSize: Theme.font.body
270
+ textFormat: Text.PlainText
271
+ }
272
+
273
+ Text {
274
+ visible: line.numbered && line.modelData.newNo > 0
275
+ x: line.host.numberWidth + line.host.columnGap
276
+ width: line.host.numberWidth
277
+ anchors.verticalCenter: parent.verticalCenter
278
+ horizontalAlignment: Text.AlignRight
279
+ text: String(line.modelData.newNo)
280
+ color: Theme.color.muted
281
+ font.family: Theme.font.family
282
+ font.pixelSize: Theme.font.body
283
+ textFormat: Text.PlainText
284
+ }
285
+
286
+ Text {
287
+ x: 2 * (line.host.numberWidth + line.host.columnGap)
288
+ width: line.host.signWidth
289
+ anchors.verticalCenter: parent.verticalCenter
290
+ text: line.modelData.kind === "removed" ? "-" : line.modelData.kind === "added" ? "+" : ""
291
+ color: line.ink
292
+ font.family: Theme.font.family
293
+ font.pixelSize: Theme.font.body
294
+ textFormat: Text.PlainText
295
+ }
296
+
297
+ // corner: file contents are arbitrary text, so PlainText, and the whitespace is kept as the diff has it.
298
+ Text {
299
+ x: line.host.textX
300
+ anchors.verticalCenter: parent.verticalCenter
301
+ text: line.modelData.text
302
+ color: line.ink
303
+ font.family: Theme.font.family
304
+ font.pixelSize: Theme.font.body
305
+ textFormat: Text.PlainText
306
+ wrapMode: Text.NoWrap
307
+ }
308
+ }
309
+
310
+ // The wheel and momentum are the text preview's own, so the diff takes the same notch as the code it sits beside.
311
+ Flea.FastScrollHandler {
312
+ parent: view
313
+ flickable: view
314
+ }
315
+
316
+ Flea.ViewportScrollBars {
317
+ parent: view
318
+ flickable: view
319
+ }
320
+ }
321
+ }