flea-qml 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (625) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +478 -2
  3. package/THIRD-PARTY-NOTICES.md +29 -0
  4. package/demos/App.java +5 -0
  5. package/demos/Dockerfile +4 -0
  6. package/demos/Main.kt +3 -0
  7. package/demos/Program.cs +1 -0
  8. package/demos/README.md +12 -0
  9. package/demos/app.dart +3 -0
  10. package/demos/app.deb +0 -0
  11. package/demos/app.js +1 -0
  12. package/demos/backup.tar +0 -0
  13. package/demos/budget.xlsx +0 -0
  14. package/demos/build.sh +2 -0
  15. package/demos/bundle.zip +0 -0
  16. package/demos/clip.mp4 +0 -0
  17. package/demos/data.sqlite +0 -0
  18. package/demos/disk.iso +0 -0
  19. package/demos/engine.cpp +5 -0
  20. package/demos/firmware.bin +0 -0
  21. package/demos/flake.nix +4 -0
  22. package/demos/folder/inside.txt +1 -0
  23. package/demos/font.ttf +0 -0
  24. package/demos/index.html +5 -0
  25. package/demos/index.php +2 -0
  26. package/demos/init.lua +1 -0
  27. package/demos/letter.docx +0 -0
  28. package/demos/lib.rs +3 -0
  29. package/demos/main.c +6 -0
  30. package/demos/main.h +3 -0
  31. package/demos/math-and-diagrams.md +200 -0
  32. package/demos/notes.tar.gz +0 -0
  33. package/demos/notes.txt +3 -0
  34. package/demos/photo.png +0 -0
  35. package/demos/program +2 -0
  36. package/demos/report.pdf +32 -0
  37. package/demos/script.py +1 -0
  38. package/demos/server.go +7 -0
  39. package/demos/settings.json +4 -0
  40. package/demos/slides.pptx +0 -0
  41. package/demos/song.mp3 +0 -0
  42. package/demos/style.css +4 -0
  43. package/demos/tool.rb +1 -0
  44. package/demos/types.ts +2 -0
  45. package/docs/pele.md +23 -0
  46. package/docs/protocol.md +3420 -0
  47. package/docs/temml.md +63 -0
  48. package/index.js +107 -0
  49. package/package.json +34 -4
  50. package/src/archive.js +402 -0
  51. package/src/archiveops.js +697 -0
  52. package/src/backend.js +369 -0
  53. package/src/bulkrename.js +95 -0
  54. package/src/clip-host.js +76 -0
  55. package/src/clip.js +462 -0
  56. package/src/code.js +168 -0
  57. package/src/compare.js +74 -0
  58. package/src/create.js +128 -0
  59. package/src/dirsize.js +147 -0
  60. package/src/figure-svg.js +530 -0
  61. package/src/figure-thread.js +23 -0
  62. package/src/figure.js +132 -0
  63. package/src/find.js +55 -0
  64. package/src/flea.js +39 -0
  65. package/src/fsinfo.js +39 -0
  66. package/src/highlight.js +141 -0
  67. package/src/html.js +52 -0
  68. package/src/kinds.js +89 -0
  69. package/src/listing.js +130 -0
  70. package/src/markdown-html.js +317 -0
  71. package/src/mathml.js +186 -0
  72. package/src/menu.js +180 -0
  73. package/src/meta.js +129 -0
  74. package/src/office.js +810 -0
  75. package/src/order.js +100 -0
  76. package/src/peek.js +49 -0
  77. package/src/pele-wrapper.js +695 -0
  78. package/src/permissions.js +180 -0
  79. package/src/places.js +313 -0
  80. package/src/preview-language.js +10 -0
  81. package/src/transfer.js +669 -0
  82. package/src/trash-record.js +41 -0
  83. package/src/trash.js +210 -0
  84. package/src/trashbrowse.js +326 -0
  85. package/src/uistate.js +393 -0
  86. package/src/uistore.js +168 -0
  87. package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
  88. package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
  89. package/src/vendor/LICENSES/MIT-katex.txt +21 -0
  90. package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
  91. package/src/vendor/LICENSES/MIT-pele.txt +40 -0
  92. package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
  93. package/src/vendor/LICENSES/MIT-temml.txt +21 -0
  94. package/src/vendor/pele.js +145 -0
  95. package/src/vendor/temml.mjs +14708 -0
  96. package/src/watch.js +98 -0
  97. package/src/wayland/client.js +109 -0
  98. package/src/wayland/protocol.js +55 -0
  99. package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
  100. package/src/wayland/protocols/wayland.xml +3248 -0
  101. package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
  102. package/src/wayland/resource-io.js +6 -0
  103. package/src/wayland/socket-discovery.js +26 -0
  104. package/src/wayland/transport-posix.js +120 -0
  105. package/src/wayland/transport-win32.js +11 -0
  106. package/src/wayland/transport.js +3 -0
  107. package/src/wayland/win32-resources.js +80 -0
  108. package/src/wayland/win32-wire.js +62 -0
  109. package/test/archive.test.js +80 -0
  110. package/test/bench-markdown-scroll.mjs +190 -0
  111. package/test/clip-host.test.js +113 -0
  112. package/test/code-preview.test.js +35 -0
  113. package/test/compare-ui-paths.test.js +24 -0
  114. package/test/compare.test.js +54 -0
  115. package/test/delete-trash.test.js +67 -0
  116. package/test/dirsize.test.js +138 -0
  117. package/test/file-ops.test.js +241 -0
  118. package/test/find-contents.test.js +161 -0
  119. package/test/find-input.test.js +66 -0
  120. package/test/fixtures/pele-parity.json +1006 -0
  121. package/test/highlight-launcher.test.js +35 -0
  122. package/test/html-preview.test.js +22 -0
  123. package/test/input.test.js +15 -0
  124. package/test/keymap.test.js +26 -0
  125. package/test/language-icons.test.js +36 -0
  126. package/test/launcher.test.js +51 -0
  127. package/test/manual-code-scroll.mjs +28 -0
  128. package/test/manual-column-scroll.mjs +24 -0
  129. package/test/manual-compare-ui.mjs +20 -0
  130. package/test/manual-find-status.mjs +37 -0
  131. package/test/manual-html-security.mjs +23 -0
  132. package/test/manual-html-ui.mjs +30 -0
  133. package/test/manual-syntax-preview.mjs +26 -0
  134. package/test/manual-trash-ui.mjs +86 -0
  135. package/test/markdown-diagrams.test.js +93 -0
  136. package/test/markdown-html.test.js +105 -0
  137. package/test/mathml.test.js +92 -0
  138. package/test/menu-transfer.test.js +57 -0
  139. package/test/office-preview.test.js +154 -0
  140. package/test/pele-parity.test.js +28 -0
  141. package/test/places.test.js +134 -0
  142. package/test/preview-keys.test.js +60 -0
  143. package/test/preview-language.test.js +22 -0
  144. package/test/status-filename.test.js +20 -0
  145. package/test/transfer-replace-merge.test.js +187 -0
  146. package/test/trash-address.test.js +23 -0
  147. package/test/trash-view.test.js +37 -0
  148. package/test/trashbrowse.test.js +135 -0
  149. package/ui/AboutFacts.qml +78 -0
  150. package/ui/ArchiveCards.qml +68 -0
  151. package/ui/ArchiveCompressDialog.qml +378 -0
  152. package/ui/ArchivePasswordDialog.qml +257 -0
  153. package/ui/Backend.qml +771 -0
  154. package/ui/BulkOldNames.qml +47 -0
  155. package/ui/BulkRenameDialog.qml +380 -0
  156. package/ui/CardFrame.qml +67 -0
  157. package/ui/CardScroll.qml +79 -0
  158. package/ui/CheckBox.qml +73 -0
  159. package/ui/ChromeBar.qml +360 -0
  160. package/ui/ChromeButton.qml +131 -0
  161. package/ui/ChromeModes.qml +43 -0
  162. package/ui/CodeLines.qml +256 -0
  163. package/ui/CodeRefusal.qml +52 -0
  164. package/ui/CollideConfirm.qml +147 -0
  165. package/ui/CollideHost.qml +167 -0
  166. package/ui/ColumnPane.qml +523 -0
  167. package/ui/ColumnRow.qml +380 -0
  168. package/ui/ColumnsArea.qml +594 -0
  169. package/ui/ColumnsLanding.qml +147 -0
  170. package/ui/CompareView.qml +321 -0
  171. package/ui/ContextMenu.qml +743 -0
  172. package/ui/ConvertDialog.qml +456 -0
  173. package/ui/CountedWorker.qml +7 -0
  174. package/ui/Crumb.qml +64 -0
  175. package/ui/CrumbDrop.qml +25 -0
  176. package/ui/CsvTable.qml +394 -0
  177. package/ui/CursorMark.qml +41 -0
  178. package/ui/DefaultClaim.qml +130 -0
  179. package/ui/DeviceLock.qml +47 -0
  180. package/ui/DeviceMounts.qml +540 -0
  181. package/ui/DialogButton.qml +150 -0
  182. package/ui/DialogField.qml +147 -0
  183. package/ui/DialogHeader.qml +31 -0
  184. package/ui/DialogScrim.qml +20 -0
  185. package/ui/DialogTitle.qml +37 -0
  186. package/ui/Divider.qml +9 -0
  187. package/ui/DropInto.qml +126 -0
  188. package/ui/DropTarget.qml +35 -0
  189. package/ui/DropboxMark.qml +60 -0
  190. package/ui/EmptyState.qml +150 -0
  191. package/ui/EscapeHint.qml +11 -0
  192. package/ui/FactsTable.qml +54 -0
  193. package/ui/FastScrollHandler.qml +476 -0
  194. package/ui/FatNamesConfirm.qml +157 -0
  195. package/ui/Favourites.qml +143 -0
  196. package/ui/FigureService.qml +120 -0
  197. package/ui/FileDrag.qml +267 -0
  198. package/ui/FilterStrip.qml +133 -0
  199. package/ui/FitMetrics.qml +22 -0
  200. package/ui/FlashDriveRows.qml +137 -0
  201. package/ui/FlashHost.qml +72 -0
  202. package/ui/FlashImageRow.qml +104 -0
  203. package/ui/FlashRunner.qml +119 -0
  204. package/ui/FlashStepRow.qml +172 -0
  205. package/ui/FlashStrip.qml +38 -0
  206. package/ui/FlashView.qml +397 -0
  207. package/ui/FleaMark.qml +88 -0
  208. package/ui/FlyoutFade.qml +23 -0
  209. package/ui/FontPane.qml +170 -0
  210. package/ui/Glass.qml +114 -0
  211. package/ui/GlassTagger.qml +59 -0
  212. package/ui/Glyph.qml +64 -0
  213. package/ui/GlyphSolid.qml +22 -0
  214. package/ui/GridArea.qml +664 -0
  215. package/ui/GridTile.qml +325 -0
  216. package/ui/GvfsBridge.qml +164 -0
  217. package/ui/Header.qml +433 -0
  218. package/ui/HoverTimers.qml +39 -0
  219. package/ui/HtmlClip.qml +30 -0
  220. package/ui/HtmlPane.qml +63 -0
  221. package/ui/HyprlandMark.qml +45 -0
  222. package/ui/Ipc.qml +1005 -0
  223. package/ui/IpcControls.qml +7 -0
  224. package/ui/IpcMenuState.qml +48 -0
  225. package/ui/IpcPreviewState.qml +185 -0
  226. package/ui/JumpPath.qml +51 -0
  227. package/ui/KeymapSheet.qml +561 -0
  228. package/ui/KeymapSheetResult.qml +89 -0
  229. package/ui/KindStack.qml +40 -0
  230. package/ui/LangMark.qml +51 -0
  231. package/ui/LangMarkLoader.qml +26 -0
  232. package/ui/List.qml +480 -0
  233. package/ui/LoadingState.qml +54 -0
  234. package/ui/LocalSend.qml +56 -0
  235. package/ui/LocalSendMark.qml +73 -0
  236. package/ui/MarkdownBlockView.qml +311 -0
  237. package/ui/MarkdownBlocks.qml +35 -0
  238. package/ui/MarkdownFigure.qml +254 -0
  239. package/ui/MarkdownImages.qml +72 -0
  240. package/ui/MarkdownList.qml +81 -0
  241. package/ui/MarkdownMathsText.qml +97 -0
  242. package/ui/MarkdownPane.qml +83 -0
  243. package/ui/MarkdownPictures.qml +41 -0
  244. package/ui/MarkdownQuote.qml +52 -0
  245. package/ui/MarkdownRemote.qml +82 -0
  246. package/ui/MarkdownSource.qml +155 -0
  247. package/ui/MarkdownTable.qml +222 -0
  248. package/ui/MarkdownTableScroll.qml +64 -0
  249. package/ui/MarkdownTableWheel.qml +126 -0
  250. package/ui/MarkdownText.qml +87 -0
  251. package/ui/MarkdownWorker.js +132 -0
  252. package/ui/MatchText.qml +99 -0
  253. package/ui/MediaSession.qml +38 -0
  254. package/ui/MediaSound.qml +26 -0
  255. package/ui/MediaStrip.qml +191 -0
  256. package/ui/MediaTrack.qml +36 -0
  257. package/ui/MediaVolume.qml +54 -0
  258. package/ui/MenuActionDialog.qml +396 -0
  259. package/ui/MenuEdgeFade.qml +24 -0
  260. package/ui/MenuHost.qml +227 -0
  261. package/ui/MenuRow.qml +351 -0
  262. package/ui/MountListing.qml +100 -0
  263. package/ui/NetworkDialog.qml +435 -0
  264. package/ui/NetworkForm.qml +426 -0
  265. package/ui/NetworkMounts.qml +913 -0
  266. package/ui/NetworkPlaces.qml +127 -0
  267. package/ui/OpenWithDialog.qml +613 -0
  268. package/ui/Opener.qml +115 -0
  269. package/ui/Pane.qml +1296 -0
  270. package/ui/PaneMenuActions.qml +527 -0
  271. package/ui/PanePath.qml +90 -0
  272. package/ui/PaneRail.qml +239 -0
  273. package/ui/PaneStates.qml +88 -0
  274. package/ui/PaneSwap.qml +339 -0
  275. package/ui/PaneWire.qml +605 -0
  276. package/ui/ParkedWait.qml +9 -0
  277. package/ui/PathEntry.qml +186 -0
  278. package/ui/PathJump.qml +400 -0
  279. package/ui/PdfViewer.qml +297 -0
  280. package/ui/PermissionsDialog.qml +658 -0
  281. package/ui/PermissionsHeadings.qml +31 -0
  282. package/ui/PhoneMounts.qml +67 -0
  283. package/ui/PickerAnswers.qml +75 -0
  284. package/ui/PickerBox.qml +26 -0
  285. package/ui/PickerChrome.qml +295 -0
  286. package/ui/PickerFilter.qml +97 -0
  287. package/ui/PickerGrid.qml +308 -0
  288. package/ui/PickerHeader.qml +28 -0
  289. package/ui/PickerLifecycle.qml +27 -0
  290. package/ui/PickerList.qml +218 -0
  291. package/ui/PickerListing.qml +149 -0
  292. package/ui/PickerPathBar.qml +127 -0
  293. package/ui/PickerPlaces.qml +189 -0
  294. package/ui/PickerRecent.qml +92 -0
  295. package/ui/PickerSave.qml +101 -0
  296. package/ui/PickerSelection.qml +155 -0
  297. package/ui/PickerWindow.qml +846 -0
  298. package/ui/PowerSectorsReader.qml +10 -0
  299. package/ui/PrebuildDriver.qml +146 -0
  300. package/ui/Preview.qml +1004 -0
  301. package/ui/PreviewAnimation.qml +24 -0
  302. package/ui/PreviewArchive.qml +66 -0
  303. package/ui/PreviewColumn.qml +551 -0
  304. package/ui/PreviewEdge.qml +63 -0
  305. package/ui/PreviewFacts.qml +30 -0
  306. package/ui/PreviewFactsLine.qml +34 -0
  307. package/ui/PreviewHtml.qml +233 -0
  308. package/ui/PreviewImage.qml +253 -0
  309. package/ui/PreviewImagePan.qml +13 -0
  310. package/ui/PreviewImageSharp.qml +32 -0
  311. package/ui/PreviewLines.qml +106 -0
  312. package/ui/PreviewMarkdown.qml +706 -0
  313. package/ui/PreviewMedia.qml +250 -0
  314. package/ui/PreviewPdf.qml +482 -0
  315. package/ui/PreviewScroll.qml +201 -0
  316. package/ui/PreviewSwap.qml +335 -0
  317. package/ui/PreviewText.qml +149 -0
  318. package/ui/ProtocolChip.qml +18 -0
  319. package/ui/QuickLookArchive.qml +38 -0
  320. package/ui/QuickLookBar.qml +103 -0
  321. package/ui/QuickLookPrepare.qml +355 -0
  322. package/ui/QuickLookSwap.qml +10 -0
  323. package/ui/QuickLookWarm.qml +65 -0
  324. package/ui/RailDrop.qml +155 -0
  325. package/ui/RailHeading.qml +19 -0
  326. package/ui/RailPlaces.qml +38 -0
  327. package/ui/RailTrashRow.qml +67 -0
  328. package/ui/RenameField.qml +353 -0
  329. package/ui/RendererRetry.qml +11 -0
  330. package/ui/ResizeHandle.qml +52 -0
  331. package/ui/Reveal.qml +54 -0
  332. package/ui/Row.qml +476 -0
  333. package/ui/RowDrag.qml +213 -0
  334. package/ui/RowDropTarget.qml +27 -0
  335. package/ui/RunCard.qml +286 -0
  336. package/ui/Scripts.qml +65 -0
  337. package/ui/SearchStrip.qml +232 -0
  338. package/ui/SelectionBand.qml +140 -0
  339. package/ui/SelectionPreview.qml +370 -0
  340. package/ui/SettingsFavourite.qml +122 -0
  341. package/ui/SettingsGroup.qml +96 -0
  342. package/ui/SettingsHint.qml +12 -0
  343. package/ui/SettingsMetrics.qml +29 -0
  344. package/ui/SettingsPane.qml +178 -0
  345. package/ui/SettingsPanel.qml +547 -0
  346. package/ui/SettingsRail.qml +128 -0
  347. package/ui/SettingsRow.qml +409 -0
  348. package/ui/SettingsRuler.qml +85 -0
  349. package/ui/SettingsSegment.qml +85 -0
  350. package/ui/ShareBrowser.qml +113 -0
  351. package/ui/ShareLink.qml +67 -0
  352. package/ui/ShelfPins.qml +101 -0
  353. package/ui/Sidebar.qml +732 -0
  354. package/ui/SidebarRow.qml +358 -0
  355. package/ui/Spinner.qml +60 -0
  356. package/ui/StableModel.qml +89 -0
  357. package/ui/StateMessage.qml +84 -0
  358. package/ui/StatusBar.qml +512 -0
  359. package/ui/StatusFileName.qml +27 -0
  360. package/ui/TabBar.qml +673 -0
  361. package/ui/TabDragGeometry.qml +60 -0
  362. package/ui/TagMenuMark.qml +52 -0
  363. package/ui/TagRailSection.qml +53 -0
  364. package/ui/TagSlot.qml +40 -0
  365. package/ui/TagState.qml +150 -0
  366. package/ui/TagSwatch.qml +28 -0
  367. package/ui/Taildrop.qml +86 -0
  368. package/ui/TailscaleMark.qml +50 -0
  369. package/ui/Theme.qml +460 -0
  370. package/ui/ThemeColors.qml +43 -0
  371. package/ui/TransferCard.qml +239 -0
  372. package/ui/TrashConfirm.qml +129 -0
  373. package/ui/TrashDropHandler.qml +11 -0
  374. package/ui/TrashHost.qml +202 -0
  375. package/ui/TrashMonitor.qml +30 -0
  376. package/ui/TrashToolbar.qml +19 -0
  377. package/ui/TrashView.qml +492 -0
  378. package/ui/UnlockDialog.qml +450 -0
  379. package/ui/UnlockHost.qml +206 -0
  380. package/ui/UpdateCheck.qml +97 -0
  381. package/ui/UserDirs.qml +25 -0
  382. package/ui/ViewState.qml +565 -0
  383. package/ui/ViewportScrollBar.qml +195 -0
  384. package/ui/ViewportScrollBars.qml +25 -0
  385. package/ui/WebPreview.qml +33 -0
  386. package/ui/WebPreviewView.qml +26 -0
  387. package/ui/WindowBody.qml +827 -0
  388. package/ui/WindowDrag.qml +35 -0
  389. package/ui/boot/Commons/AudioNodes.qml +50 -0
  390. package/ui/boot/Commons/AudioNodesModel.js +96 -0
  391. package/ui/boot/Commons/Border.qml +243 -0
  392. package/ui/boot/Commons/BorderGeometry.js +373 -0
  393. package/ui/boot/Commons/Color.qml +258 -0
  394. package/ui/boot/Commons/I18n.qml +118 -0
  395. package/ui/boot/Commons/InputDevices.qml +112 -0
  396. package/ui/boot/Commons/InputMethodState.qml +38 -0
  397. package/ui/boot/Commons/IpcRegistry.qml +77 -0
  398. package/ui/boot/Commons/Numbers.js +19 -0
  399. package/ui/boot/Commons/Plural.js +91 -0
  400. package/ui/boot/Commons/ShellIpc.qml +12 -0
  401. package/ui/boot/Commons/Style.qml +561 -0
  402. package/ui/boot/Commons/Translations.qml +100 -0
  403. package/ui/boot/Commons/UntypedInput.qml +152 -0
  404. package/ui/boot/Commons/Util.qml +188 -0
  405. package/ui/boot/Commons/qmldir +13 -0
  406. package/ui/boot/LICENSE-omarchy +20 -0
  407. package/ui/boot/Ui/BackgroundMedia.qml +49 -0
  408. package/ui/boot/Ui/BarIconButton.qml +106 -0
  409. package/ui/boot/Ui/BarIconContent.qml +38 -0
  410. package/ui/boot/Ui/BarIndicator.qml +53 -0
  411. package/ui/boot/Ui/BarWidget.qml +50 -0
  412. package/ui/boot/Ui/BorderOverlay.qml +54 -0
  413. package/ui/boot/Ui/BorderSurface.qml +40 -0
  414. package/ui/boot/Ui/Button.qml +224 -0
  415. package/ui/boot/Ui/ButtonGroup.qml +131 -0
  416. package/ui/boot/Ui/ConfirmDialog.qml +134 -0
  417. package/ui/boot/Ui/CursorSurface.qml +42 -0
  418. package/ui/boot/Ui/Dropdown.qml +245 -0
  419. package/ui/boot/Ui/FilterInput.qml +26 -0
  420. package/ui/boot/Ui/IconContentBounds.qml +141 -0
  421. package/ui/boot/Ui/KeyboardPanel.qml +453 -0
  422. package/ui/boot/Ui/MultiSelect.qml +624 -0
  423. package/ui/boot/Ui/NumberField.qml +86 -0
  424. package/ui/boot/Ui/OpticalGlyph.qml +68 -0
  425. package/ui/boot/Ui/OverlayWindow.qml +102 -0
  426. package/ui/boot/Ui/Panel.qml +60 -0
  427. package/ui/boot/Ui/PanelActionButton.qml +105 -0
  428. package/ui/boot/Ui/PanelController.qml +16 -0
  429. package/ui/boot/Ui/PanelHero.qml +112 -0
  430. package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
  431. package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
  432. package/ui/boot/Ui/PanelSeparator.qml +19 -0
  433. package/ui/boot/Ui/PanelSlider.qml +156 -0
  434. package/ui/boot/Ui/PanelToolTip.qml +50 -0
  435. package/ui/boot/Ui/PluginBarApi.qml +89 -0
  436. package/ui/boot/Ui/PointerMoveGate.qml +54 -0
  437. package/ui/boot/Ui/PopupCard.qml +181 -0
  438. package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
  439. package/ui/boot/Ui/SearchableDropdown.qml +354 -0
  440. package/ui/boot/Ui/SizedImage.qml +125 -0
  441. package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
  442. package/ui/boot/Ui/TextField.qml +58 -0
  443. package/ui/boot/Ui/Toggle.qml +118 -0
  444. package/ui/boot/Ui/ToggleSwitch.qml +115 -0
  445. package/ui/boot/Ui/WidgetButton.qml +172 -0
  446. package/ui/boot/Ui/qmldir +41 -0
  447. package/ui/boot/fleatab.qml +50 -0
  448. package/ui/boot/picker.qml +39 -0
  449. package/ui/boot/shell.qml +122 -0
  450. package/ui/boot/tabtearoff.qml +51 -0
  451. package/ui/js/Anchor.js +379 -0
  452. package/ui/js/AnchorHold.js +162 -0
  453. package/ui/js/Archive.js +157 -0
  454. package/ui/js/ArchiveCard.js +44 -0
  455. package/ui/js/ArchiveOps.js +44 -0
  456. package/ui/js/BackReturn.js +118 -0
  457. package/ui/js/BulkRename.js +100 -0
  458. package/ui/js/Buttons.js +54 -0
  459. package/ui/js/ChromeKeys.js +116 -0
  460. package/ui/js/ClipMarks.js +73 -0
  461. package/ui/js/ClipSelection.js +67 -0
  462. package/ui/js/Clipboard.js +179 -0
  463. package/ui/js/Cloud.js +97 -0
  464. package/ui/js/CodeRuns.js +72 -0
  465. package/ui/js/Collide.js +212 -0
  466. package/ui/js/ColumnFit.js +28 -0
  467. package/ui/js/ColumnMenu.js +111 -0
  468. package/ui/js/Columns.js +298 -0
  469. package/ui/js/ColumnsCarry.js +103 -0
  470. package/ui/js/Compare.js +74 -0
  471. package/ui/js/Contrast.js +157 -0
  472. package/ui/js/ControlReader.js +42 -0
  473. package/ui/js/Convert.js +52 -0
  474. package/ui/js/CopyAs.js +52 -0
  475. package/ui/js/Crumbs.js +178 -0
  476. package/ui/js/Csv.js +231 -0
  477. package/ui/js/Density.js +44 -0
  478. package/ui/js/Devices.js +440 -0
  479. package/ui/js/DirSizes.js +180 -0
  480. package/ui/js/Drag.js +364 -0
  481. package/ui/js/DragOut.js +166 -0
  482. package/ui/js/DropDev.js +52 -0
  483. package/ui/js/Dropbox.js +41 -0
  484. package/ui/js/Eject.js +217 -0
  485. package/ui/js/Errors.js +188 -0
  486. package/ui/js/ExtThumbs.js +115 -0
  487. package/ui/js/Facts.js +402 -0
  488. package/ui/js/FigureDate.js +14 -0
  489. package/ui/js/Filter.js +285 -0
  490. package/ui/js/Find.js +46 -0
  491. package/ui/js/Flash.js +184 -0
  492. package/ui/js/FlashCard.js +79 -0
  493. package/ui/js/FlashEndings.js +125 -0
  494. package/ui/js/FlashPane.js +116 -0
  495. package/ui/js/FleaBin.js +12 -0
  496. package/ui/js/Focus.js +502 -0
  497. package/ui/js/FolderSorts.js +108 -0
  498. package/ui/js/FolderViews.js +44 -0
  499. package/ui/js/Format.js +305 -0
  500. package/ui/js/Fuzzy.js +141 -0
  501. package/ui/js/GlassTag.js +72 -0
  502. package/ui/js/Grid.js +33 -0
  503. package/ui/js/GridGeometry.js +90 -0
  504. package/ui/js/GridNames.js +153 -0
  505. package/ui/js/GvfsBridge.js +200 -0
  506. package/ui/js/HostClipboard.js +29 -0
  507. package/ui/js/Icons.js +218 -0
  508. package/ui/js/Input.js +50 -0
  509. package/ui/js/Jump.js +200 -0
  510. package/ui/js/KeyName.js +64 -0
  511. package/ui/js/Keymap.js +401 -0
  512. package/ui/js/Kinds.js +164 -0
  513. package/ui/js/LICENSES/ISC-lucide.txt +43 -0
  514. package/ui/js/LangMarkPaths.js +47 -0
  515. package/ui/js/LangMarks.js +120 -0
  516. package/ui/js/Lists.js +11 -0
  517. package/ui/js/LocalSend.js +39 -0
  518. package/ui/js/LockedMenu.js +63 -0
  519. package/ui/js/MakeDefault.js +186 -0
  520. package/ui/js/MarkBox.js +7 -0
  521. package/ui/js/Markdown.js +119 -0
  522. package/ui/js/MarkdownLists.js +86 -0
  523. package/ui/js/MarkdownMaths.js +58 -0
  524. package/ui/js/MarkdownPictures.js +32 -0
  525. package/ui/js/MarkdownPrepared.js +139 -0
  526. package/ui/js/MarkdownTableFit.js +34 -0
  527. package/ui/js/Marks.js +148 -0
  528. package/ui/js/Marquee.js +96 -0
  529. package/ui/js/Match.js +93 -0
  530. package/ui/js/Material.js +109 -0
  531. package/ui/js/MdBlocks.js +437 -0
  532. package/ui/js/MdBreak.js +71 -0
  533. package/ui/js/MdChunks.js +70 -0
  534. package/ui/js/MdContainer.js +137 -0
  535. package/ui/js/MdDocument.js +337 -0
  536. package/ui/js/MdEmph.js +97 -0
  537. package/ui/js/MdEntity.js +108 -0
  538. package/ui/js/MdEntityTable.js +223 -0
  539. package/ui/js/MdEscape.js +59 -0
  540. package/ui/js/MdFront.js +37 -0
  541. package/ui/js/MdHold.js +32 -0
  542. package/ui/js/MdHtml.js +307 -0
  543. package/ui/js/MdHtmlBlock.js +290 -0
  544. package/ui/js/MdHtmlHeading.js +53 -0
  545. package/ui/js/MdHtmlImage.js +179 -0
  546. package/ui/js/MdInline.js +154 -0
  547. package/ui/js/MdItems.js +212 -0
  548. package/ui/js/MdLeaf.js +309 -0
  549. package/ui/js/MdLink.js +196 -0
  550. package/ui/js/MdMath.js +67 -0
  551. package/ui/js/MdParagraphs.js +138 -0
  552. package/ui/js/MdRefs.js +232 -0
  553. package/ui/js/MdResolve.js +226 -0
  554. package/ui/js/MdRun.js +300 -0
  555. package/ui/js/MdUrl.js +226 -0
  556. package/ui/js/Menu.js +514 -0
  557. package/ui/js/MenuContext.js +85 -0
  558. package/ui/js/MenuFit.js +13 -0
  559. package/ui/js/MenuRefresh.js +74 -0
  560. package/ui/js/MenuWheel.js +35 -0
  561. package/ui/js/Messages.js +186 -0
  562. package/ui/js/Motion.js +16 -0
  563. package/ui/js/Mounts.js +320 -0
  564. package/ui/js/MouseNav.js +13 -0
  565. package/ui/js/Nav.js +329 -0
  566. package/ui/js/NetFs.js +26 -0
  567. package/ui/js/OpenWith.js +83 -0
  568. package/ui/js/Ops.js +585 -0
  569. package/ui/js/Palette.js +33 -0
  570. package/ui/js/PathBar.js +260 -0
  571. package/ui/js/Permissions.js +179 -0
  572. package/ui/js/Phones.js +112 -0
  573. package/ui/js/Picker.js +353 -0
  574. package/ui/js/PlaceMenu.js +96 -0
  575. package/ui/js/Places.js +265 -0
  576. package/ui/js/PreviewAsk.js +21 -0
  577. package/ui/js/PreviewKeys.js +155 -0
  578. package/ui/js/PreviewSettle.js +29 -0
  579. package/ui/js/PreviewSwap.js +101 -0
  580. package/ui/js/PropertyFacts.js +144 -0
  581. package/ui/js/Protocols.js +296 -0
  582. package/ui/js/QuickLookKinds.js +27 -0
  583. package/ui/js/QuickLookRect.js +24 -0
  584. package/ui/js/RailDrop.js +51 -0
  585. package/ui/js/RailKeys.js +87 -0
  586. package/ui/js/RailMenu.js +133 -0
  587. package/ui/js/Recent.js +135 -0
  588. package/ui/js/RecentMode.js +156 -0
  589. package/ui/js/Reload.js +60 -0
  590. package/ui/js/Renderer.js +9 -0
  591. package/ui/js/RunFile.js +143 -0
  592. package/ui/js/Scripts.js +28 -0
  593. package/ui/js/Scroll.js +304 -0
  594. package/ui/js/ScrollOff.js +69 -0
  595. package/ui/js/Search.js +478 -0
  596. package/ui/js/Selection.js +97 -0
  597. package/ui/js/Settings.js +476 -0
  598. package/ui/js/SettingsAbout.js +97 -0
  599. package/ui/js/SettingsShelf.js +52 -0
  600. package/ui/js/SheetKeys.js +42 -0
  601. package/ui/js/SheetQuery.js +281 -0
  602. package/ui/js/ShelfPile.js +27 -0
  603. package/ui/js/SlowClick.js +53 -0
  604. package/ui/js/SlowOp.js +6 -0
  605. package/ui/js/Sort.js +134 -0
  606. package/ui/js/Startup.js +63 -0
  607. package/ui/js/StateWords.js +17 -0
  608. package/ui/js/Status.js +238 -0
  609. package/ui/js/Swap.js +166 -0
  610. package/ui/js/TabMove.js +39 -0
  611. package/ui/js/Tabs.js +736 -0
  612. package/ui/js/Tags.js +134 -0
  613. package/ui/js/Taildrop.js +128 -0
  614. package/ui/js/Tap.js +174 -0
  615. package/ui/js/TextSize.js +107 -0
  616. package/ui/js/Thumbs.js +158 -0
  617. package/ui/js/Transfer.js +172 -0
  618. package/ui/js/Trash.js +81 -0
  619. package/ui/js/TrashDates.js +47 -0
  620. package/ui/js/TrashDrop.js +64 -0
  621. package/ui/js/UiState.js +438 -0
  622. package/ui/js/Unlock.js +152 -0
  623. package/ui/js/Update.js +130 -0
  624. package/ui/js/UserDirs.js +56 -0
  625. package/ui/qmldir +228 -0
@@ -0,0 +1,594 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+ import "." as Flea
4
+ import "js/Columns.js" as Columns
5
+ import "js/ColumnsCarry.js" as Carry
6
+ import "js/ColumnMenu.js" as ColumnMenu
7
+ import "js/ExtThumbs.js" as ExtThumbs
8
+ import "js/Filter.js" as Filter
9
+ import "js/Focus.js" as Focus
10
+ import "js/Nav.js" as Nav
11
+ import "js/Search.js" as Search
12
+ import "js/Swap.js" as Swap
13
+ import "js/Tap.js" as Tap
14
+
15
+ // Miller columns peek their neighbours; the active listing shares List's cursor, selection and row operations.
16
+ Item {
17
+ id: root
18
+
19
+ property var pane: null
20
+ property var menu: null
21
+ // The active column's thumbnail plan, relayed for ui/Pane.qml to write, the grid's own contract.
22
+ signal thumbsApplied(var work)
23
+ signal dirSizesApplied(var ask)
24
+ // Whichever view is up owns the keyboard, and Focus.handleKey is the one route all three take.
25
+ Keys.onPressed: function (event) { event.accepted = Focus.handleKey(event, root.pane, root.pane.sidebar) }
26
+
27
+ // peekKey -> answered rows and outstanding asks; a landing retains drawn folders under the same key and order.
28
+ property var peeked: ({})
29
+ property var pending: ({})
30
+ // peekKey -> the mode of a peek that came back denied, which answers zero rows as an empty one does.
31
+ property var denials: ({})
32
+ // peekKey -> the folder order its held rows were sorted under, so a re-sort with the path unchanged re-asks the column.
33
+ property var peekOrders: ({})
34
+ // path -> {v, w}: the device and writability its last peek named, which a drag from that column carries.
35
+ property var peekFacts: ({})
36
+ property int peekVersion: 0
37
+ // The column directories drawn at the last refresh, which every watching peek names so the backend unwatches the rest.
38
+ readonly property var keep: ({ drawn: [] })
39
+ // A navigation's plan from its request to its flight's end, ui/js/ColumnsCarry.js plan.
40
+ property var carry: null
41
+ Flea.ColumnsLanding { id: neighbourLanding; area: root }
42
+ readonly property var landing: neighbourLanding
43
+
44
+ readonly property string parentPath: Nav.parentOf(root.pane.path)
45
+ // Extra columns are ancestors, oldest first, each with the parent column's own peek.
46
+ readonly property string grandparentPath: Nav.parentOf(root.parentPath)
47
+ readonly property string greatGrandparentPath: Nav.parentOf(root.grandparentPath)
48
+ // The meta the preview column names: pixels, line count, symlink target, for the cursor row only.
49
+ property var cursorMeta: null
50
+ readonly property var cursorRow: Filter.cursorShown(root.pane) ? root.pane.rowFor(root.pane.cursorIndex) : null
51
+ readonly property bool cursorIsDir: root.cursorRow !== null && root.cursorRow.d === true
52
+ readonly property string childPath: root.cursorIsDir
53
+ ? root.pane.join(Search.baseOf(root.pane), root.cursorRow.n) : ""
54
+
55
+ // What the third column shows: the cursor row as of the last swap, so a picture is taken before it changes.
56
+ property bool shownHasRow: false
57
+ property bool shownIsDir: false
58
+ property string shownChildPath: ""
59
+ // The swap's answer for the third column: the folder's rows in, or the file's preview whole.
60
+ readonly property bool thirdReady: root.shownIsDir ? root.answered(root.shownChildPath)
61
+ : (!root.shownHasRow || !ViewState.previewColumn || preview.ready)
62
+ // True while an unanswered folder waits under the live picture: the file work's readiness and cap stay out of the swap.
63
+ readonly property bool folderWaiting: Columns.folderDataHold(root.cursorIsDir, root.answered(root.childPath))
64
+
65
+ // The raw stored value, so cappedLimit reads a missing key or a hand-edited false or "" as the shipped default instead of the 0 an int property coerces.
66
+ readonly property var columnsLimit: ViewState.state.columnsLimit
67
+ readonly property int columnCount: Columns.columnCountForWidth(root.width, root.columnsLimit)
68
+ // One columnWidth per shown column from the window width (ColumnsWidth board #167 and #69); the third column takes the remainder at activeX, and resizing re-lays widths in one frame with no re-read.
69
+ readonly property int defaultColumn: Math.max(1, Math.floor(root.width / Math.max(1, root.columnCount)))
70
+ // preview.width: the last column's share of the area, 0 for the default third; a drag holds its live pixels in dragLast until release.
71
+ property int dragLast: -1
72
+ property int dragFrom: 0
73
+ readonly property int storedLast: root.dragLast >= 0 ? root.dragLast : Math.round(root.width * ViewState.previewWidth / 100)
74
+ // Each shown column keeps the narrowest one the count rule lays out: COUNT_NARROW_AT over the default 3, or less when the window is narrower.
75
+ readonly property int minColumn: Math.min(Math.floor(Columns.COUNT_NARROW_AT / Columns.COUNT_DEFAULT), root.defaultColumn)
76
+ readonly property int columnWidth: root.storedLast <= 0 ? root.defaultColumn
77
+ : Math.max(1, Math.floor((root.width - root.clampLast(root.storedLast)) / root.shownBefore))
78
+ readonly property int thirdWidth: root.width - root.shownBefore * root.columnWidth
79
+ function clampLast(px) { return Math.max(root.minColumn, Math.min(px, root.width - root.shownBefore * root.minColumn)) }
80
+ // Ancestors shown oldest first: 2 hides the parent, 5 adds the great-grandparent.
81
+ readonly property bool showGreatGrandparent: root.columnCount >= 5
82
+ readonly property bool showGrandparent: root.columnCount >= 4
83
+ readonly property bool showParent: root.columnCount >= 3
84
+ // The climb stops at /, so a shown slot with no distinct ancestor stays blank and keeps its width.
85
+ readonly property bool parentShown: Columns.ancestorShown(root.pane.path, 1)
86
+ readonly property bool grandparentShown: Columns.ancestorShown(root.pane.path, 2)
87
+ readonly property bool greatGrandparentShown: Columns.ancestorShown(root.pane.path, 3)
88
+ readonly property int shownBefore: (root.showGreatGrandparent ? 1 : 0) + (root.showGrandparent ? 1 : 0) + (root.showParent ? 1 : 0) + 1
89
+ readonly property int activeX: (root.shownBefore - 1) * root.columnWidth
90
+ // The preview column counts as shown when the child folder or the file preview draws, else the active pane is rightmost.
91
+ readonly property bool thirdShown: root.shownIsDir || (root.shownHasRow && !root.shownIsDir && ViewState.previewColumn)
92
+
93
+ // The key a column's rows are kept under: the path and the order that sorted them.
94
+ function peekKey(path) {
95
+ return Columns.peekKey(path, root.pane.showHidden, ViewState.state.hiddenLast === true)
96
+ }
97
+
98
+ // The folder order a column asks under, read from the state Backend.peek reads when it sends.
99
+ function orderOf(path) { return Carry.orderOf(ViewState.state, path, root.keep.drawn, UserDirs.newestFolders) }
100
+
101
+ // A read of peeked that a binding re-evaluates when a peek lands; peekVersion is the trigger.
102
+ function rowsFor(path) { return neighbourLanding.rows(path, Carry.rowsFor(root.peeked, root.peekKey(path), path, root.peekVersion)) }
103
+
104
+ // What a drag from a peek column's row needs: the window pane, the column's directory and its peeked device and writability.
105
+ function peekSource(path) { return Carry.peekSource(root.pane, path, root.peekFacts, root.peekVersion) }
106
+
107
+ function deniedMode(path) { return neighbourLanding.mode(path, Carry.deniedMode(root.denials, root.peekKey(path), root.peekVersion)) }
108
+
109
+ // A peek still out answers zero rows the way an empty directory does, so a column holds its empty tile back until the reply has actually landed for that path.
110
+ function answered(path) {
111
+ var key = root.peekKey(path)
112
+ return root.peekVersion >= 0 && path.length > 0 && root.peeked[key] !== undefined
113
+ }
114
+
115
+ // again re-asks a column already held, the rows staying until the reply replaces them, as a column held under an order its folder has left does; rearm asks even with the first ask out, because the backend unwatched the column when it left the drawn set.
116
+ function ask(path, again, rearm) {
117
+ var key = root.peekKey(path), order = root.orderOf(path), sent = Columns.sentKey(key, root.pane.windowSize, order)
118
+ if (path.length > 0 && (again === true || root.peeked[key] === undefined || root.peekOrders[key] !== order) && (rearm === true || !Columns.hasAsk(root.pending, sent))) {
119
+ root.pending = Columns.trackAsk(root.pending, sent)
120
+ root.pane.backend.peek(path, root.pane.windowSize, root.pane.showHidden, undefined, root.keep.drawn)
121
+ }
122
+ }
123
+
124
+ // Hidden view asks nothing, nor does a carried navigation before its rows and cursor are in; the gates are computed fresh, so a handler mid-notify cannot read a stale sibling binding.
125
+ function refreshNeighbours() { if (!root.visible || root.carry !== null && root.pane.listInFlight) return
126
+ var asks = Columns.keepAsks(root.keep, Columns.neighbourAsks(root.pane.path, root.width, root.columnsLimit), root.childPath)
127
+ if (root.shownIsDir && root.shownChildPath && root.keep.drawn.indexOf(root.shownChildPath) < 0)
128
+ root.keep.drawn = root.keep.drawn.concat([root.shownChildPath])
129
+ asks.forEach(function (one) { root.ask(one.path, one.again, one.again) })
130
+ root.askMeta()
131
+ root.askThumb()
132
+ }
133
+
134
+ // One row, only when the preview column is actually the surface showing: the same no-sweep rule
135
+ // thumb and dirsize already follow.
136
+ function askMeta() { preview.followSelection() }
137
+
138
+ // A stale queued show never draws an unanswered folder; the cap's own pending show passes force.
139
+ function showCursorRow(force) {
140
+ if (force !== true && Columns.folderDataHold(root.cursorIsDir, root.answered(root.childPath))) return
141
+ root.shownHasRow = root.cursorRow !== null
142
+ root.shownIsDir = root.cursorIsDir
143
+ root.shownChildPath = root.childPath
144
+ }
145
+
146
+ // An unanswered folder shows its pending state at the cap; a live picture ends before that wait starts.
147
+ Timer {
148
+ id: folderFallback
149
+ interval: Swap.HOLD_MS
150
+ repeat: false
151
+ onTriggered: if (root.cursorIsDir && !root.answered(root.childPath)) { thirdSwap.cancel(); root.showCursorRow(true) }
152
+ }
153
+
154
+ // Only a file load takes a hold and an unanswered folder waits by data; a manual load, a hidden preview column or a held frame lands at once, or the cap would never arm and the frozen picture would block the pointer.
155
+ function moveThird(settled) {
156
+ if (root.cursorIsDir === root.shownIsDir && root.childPath === root.shownChildPath
157
+ && (root.cursorRow !== null) === root.shownHasRow)
158
+ return
159
+ // A carried landing empties the rows before it fills them, so the third column keeps its content through that gap.
160
+ if (root.carry !== null && root.pane.listInFlight && root.cursorRow === null) return
161
+ // Filter.apply writes the query before it moves a cursor the query hid, so that pass never lands; a cursor nothing moves lands one event later.
162
+ if (settled !== true && !Filter.cursorShown(root.pane) && root.pane.shown !== null && root.pane.shown.length > 0) {
163
+ Qt.callLater(root.settleThird)
164
+ return
165
+ }
166
+ var idle = !thirdSwap.capturing && !thirdSwap.holding
167
+ // Unknown is never held: the class has not named its verdict yet, so a file waits
168
+ // for it the way a load does and onStorageKnownChanged decides when it lands.
169
+ var held = ExtThumbs.manualHold(root.pane.storageClass, ViewState.preview)
170
+ // A null row is never a file load: the rows have not landed yet, so a hold here would show the folder with no cap.
171
+ var fileLoad = Columns.isFileRow(root.cursorRow) && ViewState.previewColumn && ViewState.previewAutomatic && !held
172
+ // An unanswered folder waits by data under the live picture, which the landing or the cap releases with the folder in one pass.
173
+ if (Columns.folderDataHold(root.cursorIsDir, root.answered(root.childPath))) {
174
+ thirdSwap.stopCap()
175
+ folderFallback.restart()
176
+ return
177
+ }
178
+ folderFallback.stop()
179
+ if (!fileLoad) {
180
+ // A hold already live owns the picture, so the no-load change joins it under
181
+ // the cap; landing it at once would freeze the column and block the pointer.
182
+ if (!idle) {
183
+ thirdSwap.hold(root.showCursorRow, root.swapKey())
184
+ thirdSwap.start(false)
185
+ if (!root.cursorIsDir) preview.followSelection()
186
+ } else {
187
+ root.showCursorRow()
188
+ if (!root.cursorIsDir) preview.followSelection()
189
+ }
190
+ return
191
+ }
192
+ thirdSwap.hold(root.showCursorRow, root.swapKey())
193
+ // A file's work starts with its settle, which runs from the key.
194
+ preview.armSettle()
195
+ }
196
+
197
+ function settleThird() { if (!Filter.cursorShown(root.pane)) root.moveThird(true) }
198
+
199
+ function swapKey() { return root.pane.path + "\n" + root.pane.cursorIndex }
200
+
201
+ // The third column first, so a hold is in place before the preview clears under it.
202
+ function followCursor() {
203
+ // The thumbnail ask needs no pixel, so an idle press sends it before the capture it then overlaps.
204
+ preview.askCursorThumb()
205
+ root.moveThird()
206
+ root.askMeta()
207
+ }
208
+
209
+ function swapState() { return thirdSwap.describe() }
210
+
211
+ // The listArea contract every caller of the pane's own navigation uses: the listing's column plans its own viewport's thumbnails, the way the list and the grid do.
212
+ function primeSettle() { active.primeSettle() }
213
+ function restartCoalesce() { active.restartCoalesce() }
214
+ function restartSettle() { active.restartSettle() }
215
+ function positionViewAtIndex(index, mode) { active.positionViewAtIndex(index, mode) }
216
+ // The one column whose rows are the pane's own, for ui/Ipc.qml: a neighbour column's background navigates to its drawn directory first, so no peek lands a background right click at once.
217
+ function activeColumn() { return active }
218
+ readonly property var scrollBar: active.scrollBar
219
+ readonly property bool fileDragActive: active.fileDragActive || parentColumn.fileDragActive || childColumn.fileDragActive
220
+ || !!(grandparentLoader.item && grandparentLoader.item.fileDragActive)
221
+ || !!(greatGrandparentLoader.item && greatGrandparentLoader.item.fileDragActive)
222
+ // All active views accept a view position; the pane maps filtered listing indices before calling.
223
+ function itemAtIndex(index) { return active.itemAtIndex(index) }
224
+ function activeContentY() { return active.contentY() }
225
+
226
+ // A neighbour column's row, which the pane has no cursor on: a directory becomes the pane's own
227
+ // listing, which is this view's reveal, and a file goes to the opener.
228
+ // The peek's directory becomes the listing; Nav.applyPendingSelect puts the cursor on the row and opens the menu once the rows land.
229
+ function menuOnNeighbour(base, name) {
230
+ root.pane.pendingSelect = root.pane.join(base, name)
231
+ root.pane.pendingMenu = true
232
+ root.pane.open(base)
233
+ }
234
+
235
+ // A neighbour column's empty space delegates to the tested routing: busy refuses before any intent, the shown folder opens where it stands, and any other drawn target navigates with its menu waiting on the rows.
236
+ function menuOnNeighbourBackground(base, eventPoint) {
237
+ ColumnMenu.routeBackground(root.pane, base, eventPoint ? eventPoint.scenePosition : null, root.menu)
238
+ }
239
+
240
+ // For ui/Ipc.qml: the peek columns' rows and the child's empty tile; the two eldest answer null while their Loader is unbuilt.
241
+ function parentItemAt(index) { return (root.showParent && root.parentShown) ? parentColumn.itemAtIndex(index) : null }
242
+ function grandparentItemAt(index) { var col = grandparentLoader.item; return (root.showGrandparent && root.grandparentShown && col) ? col.itemAtIndex(index) : null }
243
+ function greatGrandparentItemAt(index) { var col = greatGrandparentLoader.item; return (root.showGreatGrandparent && root.greatGrandparentShown && col) ? col.itemAtIndex(index) : null }
244
+ function childItemAt(index) { return childColumn.itemAtIndex(index) }
245
+ function childEmptyItem() { return childColumn.emptyItem }
246
+ function frameItem() { return preview.frameItem }
247
+ function pictureItem() { return preview.pictureItem }
248
+ function playerLoaded() { return preview.playerLoaded() }
249
+ readonly property int previewIndex: preview.visible ? preview.loadedIndex : -1
250
+ function thumbShown() { return preview.thumbShown }
251
+ function frameReady() { return preview.frameStatus === Image.Ready }
252
+ function textLines() { return preview.textLines() }
253
+ function markdownText() { return preview.markdownText() }
254
+ function linesItem() { return preview.linesItem }
255
+ function archiveItem() { return preview.archiveItem }
256
+ function archiveNames() { return preview.archiveNames() }
257
+ function failureText() { return preview.failureText() }
258
+
259
+ function activateNeighbour(base, name, isDir) {
260
+ var target = root.pane.join(base, name)
261
+ if (isDir)
262
+ Nav.openPlace(root.pane, target)
263
+ else
264
+ root.pane.openFile(target)
265
+ }
266
+
267
+ function askThumb() { active.restartSettle() }
268
+ function loadSelection() { preview.loadSelection() }
269
+ function focusPreview() { if (preview.visible) preview.forceActiveFocus() }
270
+
271
+ // "Kind=MPEG-4 video|Duration=1:12|...", so a test reads the preview column's own table.
272
+ function factsLine() {
273
+ if (root.cursorIsDir)
274
+ return ""
275
+ var f = preview.factRows
276
+ var out = []
277
+ for (var i = 0; i < f.length; i++) out.push(f[i].label + "=" + f[i].value)
278
+ return out.join("|")
279
+ }
280
+
281
+ // Empty while the cursor is on a directory: the third column is that directory's own rows then,
282
+ // and reporting a hidden preview's state would read as if one were showing.
283
+ function previewStateName() { return root.cursorIsDir ? "" : preview.previewState }
284
+ function mediaPlaying() { return preview.mediaPlaying() }
285
+ function mediaPosition() { return preview.mediaPosition() }
286
+ function mediaStrip() { return preview.mediaStripItem() }
287
+ function pdfPage() { return preview.pdfPage() }
288
+ readonly property alias previewColumn: preview
289
+ function pdfPages() { return preview.pdfPages }
290
+ function pdfLoaded() { return preview.pdfLoaded() }
291
+
292
+ // The kind string the backend already sent for this row, never one the column re-derives.
293
+ function kindName(index) {
294
+ var row = root.pane.rowFor(index)
295
+ return row && root.pane.kindNames[row.k] !== undefined ? root.pane.kindNames[row.k] : ""
296
+ }
297
+
298
+ function selectedRowObjects() {
299
+ var out = []
300
+ var idx = root.pane.selectedIndices()
301
+ for (var i = 0; i < idx.length; i++) {
302
+ var row = root.pane.rowFor(idx[i])
303
+ if (row)
304
+ out.push(row)
305
+ }
306
+ return out
307
+ }
308
+
309
+ onParentPathChanged: root.refreshNeighbours()
310
+ // Toggling Hidden files re-asks the shown ancestors under the new key, or every column goes blank.
311
+ readonly property string peekOrder: (root.pane.showHidden === true ? "1" : "0") + (ViewState.state.hiddenLast === true ? "1" : "0")
312
+ onPeekOrderChanged: if (visible) root.refreshNeighbours()
313
+ // A folder's remembered order changes with the path unchanged from another window, the Settings switch or a sort, so each shown column held under another order re-asks.
314
+ Connections {
315
+ target: ViewState
316
+ function onStateChanged() { if (root.visible) root.keep.drawn.forEach(function (path) { root.ask(path) }) }
317
+ }
318
+ Connections {
319
+ target: UserDirs
320
+ function onNewestFoldersChanged() { if (root.visible) root.keep.drawn.forEach(function (path) { root.ask(path) }) }
321
+ }
322
+ // The rows/cursor move can early-return on values this binding had not settled yet, so its own change re-moves with fresh ones.
323
+ onChildPathChanged: { preview.askCursorThumb(); root.refreshNeighbours(); root.moveThird() }
324
+ onShownChildPathChanged: root.refreshNeighbours()
325
+ // A row going to none or back under an unmoved index (a search answer with no rows, then rows again) can leave childPath "" as it was, so that change re-moves too, once the bindings it reads have settled.
326
+ onCursorRowChanged: if ((root.cursorRow !== null) !== root.shownHasRow) Qt.callLater(root.moveThird)
327
+ // Widening over a step shows an ancestor never asked for; ask() stays a no-op for the rest.
328
+ onColumnCountChanged: root.refreshNeighbours()
329
+ Connections {
330
+ target: root.pane
331
+ function onCursorIndexChanged() { root.followCursor() }
332
+ // A meta asked before the new listing landed is answered with silence, because the row index
333
+ // is outside the listing the backend still holds. The rows arriving re-asks through
334
+ // followCursor, and preview.followSelection keeps a held or loaded identity rather than
335
+ // clearing it, so a landing that already has its facts does not race its own reply.
336
+ function onRowsChanged() { root.followCursor() }
337
+ }
338
+ Component.onCompleted: { root.showCursorRow(); root.refreshNeighbours() }
339
+ // The view is built with the pane and only shown later, so neither path nor cursor has changed
340
+ // by the time it first appears; becoming visible is the trigger that asks for everything.
341
+ onVisibleChanged: if (visible) root.refreshNeighbours()
342
+
343
+ Connections {
344
+ target: root.pane.backend
345
+
346
+ // The backend watches each column's directory and says so with the line the listed folder gets; the pane's own path is PaneWire's.
347
+ function onChanged(path) { if (root.keep.drawn.indexOf(path) >= 0 && root.peeked[root.peekKey(path)] !== undefined) root.ask(path, true) }
348
+
349
+ // hidden, hiddenLast, first, by and desc are the request's own, echoed; first keeps a 1 or 512 repair peek out of a column waiting on the window size.
350
+ function onPeeked(path, hidden, total, rows, readFailed, mode, hiddenLast, first, dev, writable, by, desc) {
351
+ var key = Columns.peekKey(path, hidden, hiddenLast), order = Columns.orderTag(by, desc), sent = Columns.sentKey(key, first, order)
352
+ if (!Columns.hasAsk(root.pending, sent)) return
353
+ root.pending = Columns.dropAsk(root.pending, sent)
354
+ // Rows sorted under an order the folder has since left never land; the column asks again under its new order.
355
+ if (order !== root.orderOf(path)) return
356
+ // A data-held empty folder lands whole, the settled frame the picture hold revealed.
357
+ var heroSettles = Columns.shouldSettleHero(root.cursorIsDir, path, root.childPath, readFailed, rows.length)
358
+ if (heroSettles) childColumn.emptyItem.animateEntrance = false
359
+ var next = root.peeked
360
+ next[key] = rows
361
+ root.peeked = next
362
+ root.peekOrders[key] = order
363
+ var facts = root.peekFacts
364
+ facts[path] = { v: dev || 0, w: writable !== false }
365
+ root.peekFacts = facts
366
+ if (readFailed) {
367
+ var locked = root.denials
368
+ locked[key] = mode
369
+ root.denials = locked
370
+ } else delete root.denials[key]
371
+ root.peekVersion += 1
372
+ root.landing.answered(path)
373
+ // A landed peek shows the waiting folder whole; a live picture ends before those rows do.
374
+ if (Columns.showFolderOnPeek(root.childPath, root.shownChildPath, root.answered(root.childPath))) {
375
+ thirdSwap.cancel()
376
+ root.showCursorRow()
377
+ }
378
+ if (heroSettles) { childColumn.emptyItem.markItem.settle(); childColumn.emptyItem.animateEntrance = true }
379
+ if (root.answered(root.childPath))
380
+ folderFallback.stop()
381
+ }
382
+ }
383
+
384
+ // A new listing refreshes drawn columns in place, keeping their watched rows until the replacement lands.
385
+ Connections {
386
+ target: root.pane
387
+ // The request asks incoming ancestors before the list goes out, each drawn column staying watched until the landing names its own.
388
+ function onListingPathChanged() {
389
+ root.carry = root.visible ? Carry.plan(root, Columns.neighbourAsks(root.pane.listingPath, root.width, root.columnsLimit), ViewState.state) : null
390
+ root.landing.begin(root.carry, Columns.neighbourAsks(root.pane.listingPath, root.width, root.columnsLimit))
391
+ if (root.carry !== null) root.carry.pre.forEach(function (path) { if (root.keep.drawn.indexOf(path) < 0) root.keep.drawn = root.keep.drawn.concat([path]); root.ask(path, true) })
392
+ }
393
+ function onPathChanged() {
394
+ var kept = Carry.landing(root.carry, root, Columns.neighbourAsks(root.pane.path, root.width, root.columnsLimit))
395
+ root.peeked = kept.peeked
396
+ root.pending = kept.pending
397
+ root.denials = kept.denials
398
+ root.peekOrders = kept.orders
399
+ root.peekFacts = kept.facts
400
+ root.peekVersion += 1
401
+ root.landing.landed()
402
+ root.refreshNeighbours()
403
+ }
404
+ // The flight's end: the landed cursor moves the third column, then one refresh asks what the landing still lacks.
405
+ function onListInFlightChanged() { if (!root.pane.listInFlight && root.carry !== null) { root.carry = null; root.moveThird(); root.refreshNeighbours() } }
406
+ }
407
+
408
+ Row {
409
+ anchors.fill: parent
410
+
411
+ // The great-grandparent, built only on a window wide enough for five columns, so the shipped 3 never builds it.
412
+ Loader {
413
+ id: greatGrandparentLoader
414
+ active: root.showGreatGrandparent
415
+ width: root.showGreatGrandparent ? root.columnWidth : 0
416
+ height: parent.height
417
+ sourceComponent: Flea.ColumnPane {
418
+ anchors.fill: parent
419
+ rows: root.greatGrandparentShown ? root.rowsFor(root.greatGrandparentPath) : []
420
+ enabled: !neighbourLanding.waiting(root.greatGrandparentPath)
421
+ loadingRows: neighbourLanding.loading(root.greatGrandparentPath)
422
+ onLoadingShown: function (shown) { neighbourLanding.markShown(root.greatGrandparentPath, shown) }
423
+ peekSource: root.peekSource(root.greatGrandparentPath)
424
+ lockedMode: root.greatGrandparentShown ? root.deniedMode(root.greatGrandparentPath) : -1
425
+ drawsEmpty: root.greatGrandparentShown && root.answered(root.greatGrandparentPath) && !neighbourLanding.waiting(root.greatGrandparentPath)
426
+ liftedName: root.greatGrandparentShown ? Nav.leafOf(root.grandparentPath) : ""
427
+ dim: true
428
+ showDivider: true
429
+ onActivated: function (name, isDir) { root.activateNeighbour(root.greatGrandparentPath, name, isDir) }
430
+ onRowPressed: root.pane.pressSlowClick()
431
+ onNeighbourMenuRequested: function (name) { root.menuOnNeighbour(root.greatGrandparentPath, name) }
432
+ onNeighbourBackgroundRequested: function (eventPoint) {
433
+ if (root.showGreatGrandparent && root.greatGrandparentShown)
434
+ root.menuOnNeighbourBackground(root.greatGrandparentPath, eventPoint)
435
+ }
436
+ onTabRequested: function (row) { Tap.tappedTab(row, root.greatGrandparentPath, root.pane) }
437
+ }
438
+ }
439
+
440
+ // The grandparent, built only on a window wide enough for four columns, for the same reason.
441
+ Loader {
442
+ id: grandparentLoader
443
+ active: root.showGrandparent
444
+ width: root.showGrandparent ? root.columnWidth : 0
445
+ height: parent.height
446
+ sourceComponent: Flea.ColumnPane {
447
+ anchors.fill: parent
448
+ rows: root.grandparentShown ? root.rowsFor(root.grandparentPath) : []
449
+ enabled: !neighbourLanding.waiting(root.grandparentPath)
450
+ loadingRows: neighbourLanding.loading(root.grandparentPath)
451
+ onLoadingShown: function (shown) { neighbourLanding.markShown(root.grandparentPath, shown) }
452
+ peekSource: root.peekSource(root.grandparentPath)
453
+ lockedMode: root.grandparentShown ? root.deniedMode(root.grandparentPath) : -1
454
+ drawsEmpty: root.grandparentShown && root.answered(root.grandparentPath) && !neighbourLanding.waiting(root.grandparentPath)
455
+ liftedName: root.grandparentShown ? Nav.leafOf(root.parentPath) : ""
456
+ dim: true
457
+ showDivider: true
458
+ onActivated: function (name, isDir) { root.activateNeighbour(root.grandparentPath, name, isDir) }
459
+ onRowPressed: root.pane.pressSlowClick()
460
+ onNeighbourMenuRequested: function (name) { root.menuOnNeighbour(root.grandparentPath, name) }
461
+ onNeighbourBackgroundRequested: function (eventPoint) {
462
+ if (root.showGrandparent && root.grandparentShown)
463
+ root.menuOnNeighbourBackground(root.grandparentPath, eventPoint)
464
+ }
465
+ onTabRequested: function (row) { Tap.tappedTab(row, root.grandparentPath, root.pane) }
466
+ }
467
+ }
468
+
469
+ // The parent shows the current directory among its siblings; below 900 px it hides.
470
+ Flea.ColumnPane {
471
+ id: parentColumn
472
+ visible: root.showParent
473
+ width: root.showParent ? root.columnWidth : 0
474
+ height: parent.height
475
+ rows: (root.showParent && root.parentShown) ? root.rowsFor(root.parentPath) : []
476
+ enabled: !neighbourLanding.waiting(root.parentPath)
477
+ loadingRows: neighbourLanding.loading(root.parentPath)
478
+ onLoadingShown: function (shown) { neighbourLanding.markShown(root.parentPath, shown) }
479
+ peekSource: root.peekSource(root.parentPath)
480
+ lockedMode: (root.showParent && root.parentShown) ? root.deniedMode(root.parentPath) : -1
481
+ drawsEmpty: root.parentShown && root.answered(root.parentPath) && !neighbourLanding.waiting(root.parentPath)
482
+ liftedName: root.parentShown ? Nav.leafOf(root.pane.path) : ""
483
+ dim: true
484
+ showDivider: true
485
+ onActivated: function (name, isDir) { root.activateNeighbour(root.parentPath, name, isDir) }
486
+ onRowPressed: root.pane.pressSlowClick()
487
+ onNeighbourMenuRequested: function (name) { root.menuOnNeighbour(root.parentPath, name) }
488
+ onNeighbourBackgroundRequested: function (eventPoint) {
489
+ if (root.showParent && root.parentShown)
490
+ root.menuOnNeighbourBackground(root.parentPath, eventPoint)
491
+ }
492
+ onTabRequested: function (row) { Tap.tappedTab(row, root.parentPath, root.pane) }
493
+ }
494
+
495
+ // The pane's own listing, which is why this column and only this one takes the accent.
496
+ Flea.ColumnPane {
497
+ id: active
498
+ width: root.columnWidth
499
+ height: parent.height
500
+ rows: root.pane.rows
501
+ selectedIndex: root.pane.cursorIndex
502
+ // Only this column's rows are the pane's own, so only it can paint the pane's selection.
503
+ pane: root.pane
504
+ showDivider: root.thirdShown
505
+ // The list's and the grid's own two routes, reached from the one column whose rows are the pane's listing, so a click means the same thing in all three views.
506
+ onPicked: function (index, tapCount, modifiers, onName) {
507
+ var wasSole = root.pane.slowClickWasSole(index)
508
+ Tap.tappedMiddle(index, tapCount, modifiers, root.pane)
509
+ // The slow click renames on the pane's timer; a double click opens through tappedMiddle() above instead.
510
+ if (tapCount === 2) root.pane.cancelSlowClick()
511
+ else if (tapCount === 1 && onName) root.pane.armSlowClick(index, modifiers, active.fileDragActive, wasSole)
512
+ else root.pane.cancelSlowClick()
513
+ }
514
+ onMenuRequested: function (index, eventPoint) { Tap.tappedMenu(index, eventPoint, root.pane, root.menu) }
515
+ onRowPressed: root.pane.pressSlowClick()
516
+ onTabRequested: function (row) { Tap.tappedTab(row, root.pane.path, root.pane) }
517
+ onBackgroundMenuRequested: function (eventPoint) { root.menu.openBackground(eventPoint.scenePosition) }
518
+ onThumbsApplied: function (work) { root.thumbsApplied(work) }
519
+ onDirSizesApplied: function (ask) { root.dirSizesApplied(ask) }
520
+ }
521
+
522
+ // The cursor row: what is inside it when it is a directory, what it is when it is a file.
523
+ Flea.PreviewSwap {
524
+ id: thirdSwap
525
+ width: root.thirdWidth
526
+ height: parent.height
527
+ burstEnds: true
528
+ ready: root.thirdReady
529
+ folderHold: root.folderWaiting
530
+ // On glass the pane's ground is already under the picture, so a second would stack; see ui/Glass.qml.
531
+ ground: Glass.on ? "transparent" : Theme.color.background
532
+
533
+ Flea.ColumnPane {
534
+ id: childColumn
535
+ anchors.fill: parent
536
+ visible: root.shownIsDir
537
+ rows: root.rowsFor(root.shownChildPath)
538
+ peekSource: root.peekSource(root.shownChildPath)
539
+ lockedMode: root.deniedMode(root.shownChildPath)
540
+ drawsEmpty: root.answered(root.shownChildPath)
541
+ onActivated: function (name, isDir) { root.activateNeighbour(root.shownChildPath, name, isDir) }
542
+ onRowPressed: root.pane.pressSlowClick()
543
+ onNeighbourMenuRequested: function (name) { root.menuOnNeighbour(root.shownChildPath, name) }
544
+ onNeighbourBackgroundRequested: function (eventPoint) {
545
+ if (root.shownIsDir && root.shownChildPath.length > 0)
546
+ root.menuOnNeighbourBackground(root.shownChildPath, eventPoint)
547
+ }
548
+ onTabRequested: function (row) { Tap.tappedTab(row, root.shownChildPath, root.pane) }
549
+ }
550
+
551
+ Flea.SelectionPreview {
552
+ id: preview
553
+ anchors.fill: parent
554
+ visible: root.shownHasRow && !root.shownIsDir && ViewState.previewColumn
555
+ pane: root.pane
556
+ swap: thirdSwap
557
+ onThumbsApplied: function (work) { root.thumbsApplied(work) }
558
+ }
559
+ }
560
+ }
561
+
562
+ // A drag entering the pane asks the devices of the drawn neighbour columns' visible folder rows in one request, once per drag.
563
+ function askDropDevs(token) {
564
+ if (!root.visible) return
565
+ var paths = []
566
+ for (var column of [greatGrandparentLoader.item, grandparentLoader.item, parentColumn, childColumn])
567
+ if (column) paths = paths.concat(column.dropAsks())
568
+ root.pane.backend.askDropDevs(token, paths)
569
+ }
570
+
571
+ // The preview column's left edge drags the last column's width live and stores it once on release; a double click restores the default third.
572
+ PreviewEdge {
573
+ anchors.top: parent.top
574
+ anchors.bottom: parent.bottom
575
+ z: 3
576
+ visible: root.thirdShown
577
+ edge: root.shownBefore * root.columnWidth
578
+ onGrabbed: root.dragFrom = root.thirdWidth
579
+ onDragged: function (shift) { root.dragLast = root.clampLast(root.dragFrom - shift) }
580
+ onReleased: {
581
+ if (root.dragLast >= 0) ViewState.setPreviewWidth(Math.max(1, Math.min(100, Math.round(100 * root.dragLast / root.width))))
582
+ root.dragLast = -1
583
+ }
584
+ onRestored: { root.dragLast = -1; ViewState.setPreviewWidth(0) }
585
+ }
586
+
587
+ // For ui/Ipc.qml: the names a drawn neighbour column holds, "|" joined, and "" when that column is not drawn.
588
+ function drawnNames(slot) {
589
+ var drawn = slot === "child" ? root.shownIsDir : (slot === "parent" && root.showParent && root.parentShown)
590
+ return drawn ? (slot === "child" ? childColumn.rows : parentColumn.rows).map(function (row) { return row.n }).join("|") : ""
591
+ }
592
+ // For ui/Ipc.qml: the names the window last read for a folder, drawn or not.
593
+ function peekNames(path) { return root.rowsFor(path).map(function (row) { return row.n }).join("|") }
594
+ }