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,31 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+
4
+ // The READ, WRITE and EXEC (ENTER for a folder) headings over the bit columns, each in the thirds the dialog's grid lays out.
5
+ Row {
6
+ id: root
7
+ // The PermissionsDialog whose label width, row height and bit columns these headings sit on.
8
+ property var card: null
9
+ property bool enter: false
10
+ // The board's headings inherit the body's line-height of 1.6, where the note under the grid sets 1.5.
11
+ readonly property real headingLineRatio: 1.6
12
+ readonly property int lineBox: Math.round(root.headingLineRatio * Theme.font.caption)
13
+ readonly property int lead: Math.round((root.lineBox - metrics.height) / 2)
14
+ height: root.card.headingHeight
15
+ FontMetrics { id: metrics; font { family: Theme.font.family; pixelSize: Theme.font.caption } }
16
+ Item { width: root.card.labelWidth; height: parent.height }
17
+ Repeater {
18
+ model: ["READ", "WRITE", root.enter ? "ENTER" : "EXEC"]
19
+ // The board's row centres a one-line box in the heading and the glyphs in that box, so a floor, not Qt's half pixel, sets its top.
20
+ Text {
21
+ required property string modelData
22
+ required property int index
23
+ width: root.card.bitWidth(index); height: root.lineBox
24
+ y: Math.floor((parent.height - height) / 2)
25
+ lineHeight: height; lineHeightMode: Text.FixedHeight; topPadding: root.lead
26
+ horizontalAlignment: Text.AlignHCenter
27
+ text: modelData; textFormat: Text.PlainText; color: Theme.color.foreground
28
+ font { family: Theme.font.family; pixelSize: Theme.font.caption; letterSpacing: Theme.font.caption / 10 }
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,67 @@
1
+ import QtQuick
2
+ import Quickshell.Io
3
+ import "js/Phones.js" as Phones
4
+ import "js/Format.js" as Format
5
+ import "js/Mounts.js" as Mounts
6
+
7
+ // The DEVICES group's phone rows, the third Service beside ui/DeviceMounts.qml (block devices over
8
+ // lsblk) and ui/NetworkMounts.qml (shares over gio). An Android phone or a camera is a gvfs volume
9
+ // with no block device behind it, so lsblk can never list one; only the volume monitors can, and
10
+ // ui/MountListing.qml's five second listing already walks them, so this Service reads that text
11
+ // through ui/NetworkMounts.qml rather than earning a second 500 ms gio walk of its own.
12
+ // It only lists and unmounts: mounting and opening ride ui/NetworkMounts.qml's openShare leg,
13
+ // because an mtp:// uri mounts, resolves its FUSE folder and opens exactly the way a share does.
14
+ Item {
15
+ id: root
16
+
17
+ property string listingText: ""
18
+ property var entries: []
19
+ // The rail's phones gate: an empty first listing never changes this text, so the parent also feeds the listing's own answer.
20
+ property bool answered: false
21
+ property bool listingAnswered: false
22
+ readonly property bool firstDone: root.answered || root.listingAnswered
23
+
24
+ signal message(string text, bool isError)
25
+ // Raised when an unmount ends, so the owner re-polls the listing; the poll is what flips the row.
26
+ signal released()
27
+
28
+ property string _unmountLabel: ""
29
+
30
+ onListingTextChanged: root.rebuild()
31
+
32
+ function rebuild() {
33
+ root.answered = true
34
+ var out = Phones.parsePhones(root.listingText)
35
+ // Same rule as the other two Services: an unchanged poll assigns nothing, see Mounts.sameEntries.
36
+ if (!Mounts.sameEntries(root.entries, out))
37
+ root.entries = out
38
+ }
39
+
40
+ // The rail hands the key back rather than an index, the same stale-index rule every release has:
41
+ // the poll rebuilds these rows under it, so the row is resolved fresh here.
42
+ function release(key) {
43
+ var row = Mounts.rowByKey(root.entries, key)
44
+ if (row >= 0)
45
+ root.unmount(row)
46
+ }
47
+
48
+ // gio's -f is offered nowhere in this tree: forcing an unmount over an open transfer is how a
49
+ // file manager loses somebody's photos, and a phone is the surface people copy photos from.
50
+ function unmount(index) {
51
+ var e = root.entries[index]
52
+ if (!e || e.kind !== "phone" || !e.mounted || unmountProcess.running)
53
+ return
54
+ root._unmountLabel = e.label
55
+ unmountProcess.command = ["gio", "mount", "-u", e.uri]
56
+ unmountProcess.running = true
57
+ }
58
+
59
+ Process {
60
+ id: unmountProcess
61
+ onExited: function (exitCode) {
62
+ if (exitCode !== 0)
63
+ root.message(Format.fill(Mounts.WORDS.transferUsing, root._unmountLabel), true)
64
+ root.released()
65
+ }
66
+ }
67
+ }
@@ -0,0 +1,75 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+ import "." as Flea
4
+ import "js/Picker.js" as Picker
5
+
6
+ // The one row under the listing in every mode: the filter at the left, Cancel and the answer at the right.
7
+ Item {
8
+ id: root
9
+ objectName: "pickerAnswers"
10
+ required property var picker
11
+ readonly property alias filterItem: filter
12
+ readonly property alias cancelItem: cancelButton
13
+ anchors.left: parent.left
14
+ anchors.right: parent.right
15
+ // A save sits in the save column: no rule of its own and one gap under the field; an open keeps its own strip.
16
+ readonly property real lead: root.picker.saving ? Theme.spacing.gap : Theme.spacing.hairline + Theme.spacing.rowPaddingX
17
+ height: root.lead + Theme.spacing.rowPaddingX + cancelButton.height
18
+
19
+ // Every answer is the one body control every dialog draws; the picker owns Tab.
20
+ component Answer: Flea.DialogButton {
21
+ id: answer
22
+ property string name: answer.label
23
+ tabHandle: true
24
+ tabStop: true
25
+ onTabbed: function(from, back) { root.picker.stepFocus(answer, back) }
26
+ }
27
+
28
+ Rectangle {
29
+ anchors.fill: parent
30
+ color: Theme.color.surface
31
+ }
32
+
33
+ Rectangle {
34
+ visible: !root.picker.saving
35
+ anchors.top: parent.top
36
+ width: parent.width
37
+ height: Theme.spacing.hairline
38
+ color: root.picker.edge
39
+ }
40
+
41
+ Flea.PickerFilter {
42
+ id: filter
43
+ picker: root.picker
44
+ x: Theme.spacing.rowPaddingX
45
+ y: root.lead
46
+ height: cancelButton.height
47
+ }
48
+
49
+ Row {
50
+ anchors.right: parent.right
51
+ anchors.rightMargin: Theme.spacing.rowPaddingX
52
+ y: root.lead
53
+ spacing: Theme.spacing.gap
54
+
55
+ Answer {
56
+ id: cancelButton
57
+ label: "Cancel"
58
+ onActivated: root.picker.cancel()
59
+ }
60
+
61
+ Answer {
62
+ id: acceptButton
63
+ label: root.picker.collisionReview ? "Replace" : Picker.acceptLabel(root.picker.req, root.picker.marks.length)
64
+ primary: !root.picker.collisionReview
65
+ destructive: root.picker.collisionReview
66
+ available: root.picker.canAccept
67
+ onActivated: root.picker.collisionReview ? root.picker.replace() : root.picker.accept()
68
+ }
69
+ }
70
+
71
+ function focusItems() { return (filter.visible ? [filter] : []).concat([cancelButton, acceptButton]) }
72
+ function controls() {
73
+ return root.focusItems().map(function(item) { return root.picker.control(item.name, item, item.available) })
74
+ }
75
+ }
@@ -0,0 +1,26 @@
1
+ import QtQuick
2
+ import "." as Flea
3
+ import "js/MarkBox.js" as MarkBox
4
+
5
+ // The picker's mark box, one copy for the list and the grid; js/MarkBox.js holds its sizes.
6
+ Rectangle {
7
+ id: root
8
+
9
+ property bool marked: false
10
+ readonly property int innerSize: MarkBox.inner(Theme.font.bodySmall, Theme.spacing.hairline)
11
+ readonly property int borderWidth: MarkBox.border(Theme.spacing.hairline)
12
+
13
+ width: MarkBox.outer(Theme.font.bodySmall, Theme.spacing.hairline)
14
+ height: root.width
15
+ color: "transparent"
16
+ border.width: root.borderWidth
17
+ border.color: root.marked ? Theme.color.accent : Theme.color.mutedFrame
18
+
19
+ Flea.Glyph {
20
+ anchors.fill: parent
21
+ visible: root.marked
22
+ name: "check"
23
+ maxSize: root.innerSize - root.borderWidth * 2
24
+ color: Theme.color.accent
25
+ }
26
+ }
@@ -0,0 +1,295 @@
1
+ import QtQuick
2
+ import QtQuick.Layouts
3
+ import qs.Commons
4
+ import "." as Flea
5
+ import "js/Format.js" as Format
6
+ import "js/Picker.js" as Picker
7
+
8
+ // The picker's two chrome strips: what was asked for on top, where the list is standing underneath; the answers are ui/PickerAnswers.qml.
9
+ Item {
10
+ id: root
11
+ // Its Jump dropdown hangs below the strip, so the chrome rises over the places and the listing while it shows.
12
+ z: entry.jumpShown ? 1 : 0
13
+
14
+ property var picker: null
15
+ property var submissionFocus: null
16
+ property var listing: null
17
+ property var backend: null
18
+
19
+ readonly property bool editing: entry.editing
20
+ readonly property var jump: entry.jump
21
+ function startEdit() { entry.startEdit() }
22
+
23
+ function submissionChanged() {
24
+ var window = root.Window.window
25
+ if (root.picker.submitting) {
26
+ var before = window ? window.activeFocusItem : null
27
+ root.submissionFocus = null
28
+ root.picker.stepFocus(null, false)
29
+ root.submissionFocus = {before: before, stepped: window ? window.activeFocusItem : null}
30
+ return
31
+ }
32
+ var pending = root.submissionFocus
33
+ // Replies clear submitting before they answer and before disabled controls re-enable.
34
+ Qt.callLater(function() {
35
+ if (!pending || root.submissionFocus !== pending) return
36
+ root.submissionFocus = null
37
+ if (root.picker.answered || root.picker.submitting || root.picker.backendUnavailable) return
38
+ var before = pending.before
39
+ if (before && before.visible && before.enabled && pending.stepped && pending.stepped.activeFocus)
40
+ before.forceActiveFocus()
41
+ })
42
+ }
43
+
44
+ Connections {
45
+ target: root.Window.window
46
+ function onActiveFocusItemChanged() {
47
+ if (root.submissionFocus && root.Window.window.activeFocusItem !== root.submissionFocus.stepped)
48
+ root.submissionFocus = null
49
+ }
50
+ }
51
+
52
+ signal backRequested()
53
+ signal upRequested()
54
+ signal viewChosen(string mode)
55
+
56
+ readonly property var req: root.picker.req
57
+
58
+ readonly property color edge: root.picker.edge
59
+
60
+ implicitHeight: ask.height + where.height
61
+
62
+ // Back and Up rest in the foreground like the main chrome; only an unlit view mark rests muted.
63
+ component Mark: Flea.ChromeButton {
64
+ id: mark
65
+ ruleRows: Theme.spacing.hairline
66
+ property bool lit: false
67
+ readonly property bool available: mark.enabled
68
+ property string name: mark.accessName
69
+ gesturePolicy: TapHandler.ReleaseWithinBounds
70
+ restingColor: Theme.color.foreground
71
+ activeFocusOnTab: mark.enabled
72
+ keyboardFocused: mark.activeFocus
73
+ Keys.onTabPressed: function(event) { root.picker.stepFocus(mark, (event.modifiers & Qt.ShiftModifier) !== 0) }
74
+ Keys.onBacktabPressed: root.picker.stepFocus(mark, true)
75
+ }
76
+
77
+ // One 33 px line at body: the caller's title as it came, then the requester after a middot when the portal names one.
78
+ Item {
79
+ id: ask
80
+ objectName: "pickerAsk"
81
+ anchors.left: parent.left
82
+ anchors.right: parent.right
83
+ anchors.top: parent.top
84
+ height: Math.max(Theme.chromeHeight, caller.implicitHeight + 2 * Theme.spacing.rowPaddingY)
85
+
86
+ Rectangle {
87
+ anchors.fill: parent
88
+ color: Theme.color.surface
89
+ }
90
+
91
+ RowLayout {
92
+ id: titles
93
+ objectName: "pickerTitleLine"
94
+ anchors.left: parent.left
95
+ anchors.leftMargin: Theme.spacing.rowPaddingX
96
+ anchors.right: parent.right
97
+ anchors.rightMargin: Theme.spacing.rowPaddingX
98
+ anchors.verticalCenter: parent.verticalCenter
99
+ spacing: 0
100
+
101
+ // The caller's own words, and a filename is arbitrary text, so PlainText here too.
102
+ Text {
103
+ id: caller
104
+ Layout.alignment: Qt.AlignBaseline
105
+ Layout.fillWidth: true
106
+ Layout.maximumWidth: implicitWidth
107
+ text: Picker.title(root.req)
108
+ color: Theme.color.foreground
109
+ font.family: Theme.font.family
110
+ font.pixelSize: Theme.font.body
111
+ elide: Text.ElideRight
112
+ textFormat: Text.PlainText
113
+ }
114
+
115
+ // Only a portal identity is drawn, in a Text of its own that the caller's title never reaches.
116
+ Text {
117
+ Layout.alignment: Qt.AlignBaseline
118
+ visible: requester.visible
119
+ text: "\u00a0\u00b7\u00a0"
120
+ color: Theme.color.muted
121
+ font.family: Theme.font.family
122
+ font.pixelSize: Theme.font.caption
123
+ textFormat: Text.PlainText
124
+ }
125
+
126
+ Text {
127
+ id: requester
128
+ objectName: "pickerRequester"
129
+ Layout.alignment: Qt.AlignBaseline
130
+ Layout.fillWidth: true
131
+ visible: text.length > 0
132
+ text: Picker.subtitle(root.req)
133
+ color: Theme.color.foreground
134
+ font.family: Theme.font.family
135
+ font.pixelSize: Theme.font.caption
136
+ elide: Text.ElideRight
137
+ textFormat: Text.PlainText
138
+ }
139
+ }
140
+
141
+ Rectangle {
142
+ anchors.bottom: parent.bottom
143
+ width: parent.width
144
+ height: Theme.spacing.hairline
145
+ color: root.edge
146
+ }
147
+ }
148
+
149
+ Item {
150
+ id: where
151
+ objectName: "pickerWhere"
152
+ anchors.left: parent.left
153
+ anchors.right: parent.right
154
+ anchors.top: ask.bottom
155
+ // The board's 27 px strip at base-size 14: the chrome's own height, so the field and its dropdown sit as in the main window.
156
+ height: Theme.chromeHeight
157
+
158
+ Rectangle {
159
+ anchors.bottom: parent.bottom
160
+ width: parent.width
161
+ height: Theme.spacing.hairline
162
+ color: root.edge
163
+ }
164
+
165
+ Row {
166
+ id: moves
167
+ anchors.left: parent.left
168
+ anchors.leftMargin: Theme.spacing.rowPaddingX
169
+ anchors.verticalCenter: parent.verticalCenter
170
+ spacing: Theme.spacing.gap
171
+
172
+ Mark {
173
+ id: backButton
174
+ objectName: "pickerBack"
175
+ glyph: "arrow-left"
176
+ enabled: !root.picker.backendUnavailable && root.picker.history.length > 0 && !root.picker.submitting
177
+ onActivated: root.backRequested()
178
+ }
179
+
180
+ Mark {
181
+ id: upButton
182
+ objectName: "pickerUp"
183
+ glyph: "arrow-up"
184
+ accessName: root.picker.recent ? "Parent folder unavailable in Recent" : "Parent folder"
185
+ // The board's own rule, drawn as its disabled Up: a history has no directory above it.
186
+ enabled: !root.picker.backendUnavailable && !root.picker.submitting && !root.picker.recent && Picker.parentOf(root.picker.path) !== root.picker.path
187
+ onActivated: root.upRequested()
188
+ }
189
+ }
190
+
191
+ // Parents muted, the leaf lit inline after them; a long path elides its parents from the left and keeps the leaf whole.
192
+ Row {
193
+ id: strip
194
+ objectName: "pickerStrip"
195
+ anchors.left: moves.right
196
+ anchors.leftMargin: Theme.spacing.gap
197
+ anchors.right: parent.right
198
+ anchors.rightMargin: views.width + Theme.spacing.rowPaddingX + Theme.spacing.gap
199
+ anchors.verticalCenter: parent.verticalCenter
200
+ // The marks centre in the band above the rule, so the path does too.
201
+ anchors.verticalCenterOffset: -Theme.spacing.hairline / 2
202
+ visible: !entry.editing
203
+ // Recent is a location and not a path, so the strip says its name, never a tilde form of the token.
204
+ readonly property string display: root.picker.recent ? Picker.RECENT_LABEL : Format.tilde(root.picker.path, root.picker.home)
205
+ readonly property string leaf: root.picker.recent ? strip.display : Format.leafPart(strip.display)
206
+ readonly property string parents: root.picker.recent ? "" : strip.display.substring(0, strip.display.length - strip.leaf.length)
207
+ Text {
208
+ id: stripParents
209
+ width: Math.min(implicitWidth, Math.max(0, strip.width - stripLeaf.width))
210
+ visible: strip.parents.length > 0
211
+ text: strip.parents
212
+ color: Theme.color.muted
213
+ font.family: Theme.font.family
214
+ font.pixelSize: Theme.font.caption
215
+ elide: Text.ElideLeft
216
+ textFormat: Text.PlainText
217
+ }
218
+ Text {
219
+ id: stripLeaf
220
+ width: Math.min(implicitWidth, strip.width)
221
+ text: strip.leaf
222
+ color: Theme.color.foreground
223
+ font.family: Theme.font.family
224
+ font.pixelSize: Theme.font.caption
225
+ elide: Text.ElideMiddle
226
+ textFormat: Text.PlainText
227
+ }
228
+ }
229
+
230
+ // Picker040 path entry: the shared field, whose line pathLogic below answers.
231
+ Flea.PathEntry {
232
+ id: entry
233
+ anchors.left: moves.right
234
+ anchors.leftMargin: Theme.spacing.gap
235
+ anchors.right: parent.right
236
+ anchors.rightMargin: views.width + Theme.spacing.rowPaddingX + Theme.spacing.gap
237
+ anchors.top: parent.top
238
+ anchors.bottom: parent.bottom
239
+ anchors.bottomMargin: Theme.spacing.hairline
240
+ path: pathLogic.basePath
241
+ home: root.picker.home
242
+ showHidden: root.picker.showHidden
243
+ onCommitLine: function (text) { pathLogic.commitTyped(text) }
244
+ onJumpChosen: function (path) { pathLogic.ask(path) }
245
+ onEditClosed: pathLogic.editClosed()
246
+ onCompleteRequested: function (dir, hidden) { root.listing.peek(dir, root.picker.windowSize, hidden) }
247
+ onSaid: function (text) { root.picker.say(text, false) }
248
+ onJumpRequested: function (id, ranking, favourites, recent) { root.listing.jump(id, ranking, favourites, recent) }
249
+ }
250
+
251
+ Flea.PickerPathBar {
252
+ id: pathLogic
253
+ picker: root.picker
254
+ listing: root.listing
255
+ backend: root.backend
256
+ entry: entry
257
+ }
258
+ }
259
+
260
+ // Pointer and ctrl-1/ctrl-3 targets only; callout 12 keeps them out of the Tab walk.
261
+ Row {
262
+ id: views
263
+ anchors.right: parent.right
264
+ anchors.rightMargin: Theme.spacing.rowPaddingX
265
+ anchors.verticalCenter: where.verticalCenter
266
+ spacing: Theme.spacing.gap
267
+
268
+ Mark {
269
+ id: listButton
270
+ objectName: "pickerListView"
271
+ glyph: "list"
272
+ lit: root.picker.viewMode === "list"
273
+ restingColor: listButton.lit ? Theme.color.foreground : Theme.color.mutedFrame
274
+ activeFocusOnTab: false
275
+ onActivated: root.viewChosen("list")
276
+ }
277
+
278
+ Mark {
279
+ id: gridButton
280
+ objectName: "pickerGridView"
281
+ glyph: "grid"
282
+ lit: root.picker.viewMode === "grid"
283
+ restingColor: gridButton.lit ? Theme.color.foreground : Theme.color.mutedFrame
284
+ activeFocusOnTab: false
285
+ onActivated: root.viewChosen("grid")
286
+ }
287
+ }
288
+
289
+ function focusItems() {
290
+ return [backButton, upButton]
291
+ }
292
+ function controls() {
293
+ return root.focusItems().concat([listButton, gridButton]).map(function(item) { return root.picker.control(item.name, item, item.available) })
294
+ }
295
+ }
@@ -0,0 +1,97 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+ import "." as Flea
4
+ import "js/Picker.js" as Picker
5
+
6
+ // Picker040's filter dropdown: one trigger at the menu's width, its menu opening flush above it.
7
+ Item {
8
+ id: root
9
+ required property var picker
10
+ readonly property var chips: Picker.chips(root.picker.req)
11
+ readonly property int current: root.chips.findIndex(function(chip) { return chip.index === root.picker.filterIndex })
12
+ // The focus walk and the probe read these two the way they read a button's.
13
+ readonly property string name: "Filter"
14
+ readonly property bool available: root.enabled
15
+ // The board draws the chevron in the foreground at four fifths.
16
+ readonly property real chevronAlpha: 0.8
17
+ // The chevron's box is the body text plus two pixels, the board's 16 px at base size 14.
18
+ readonly property real chevronSize: Theme.font.body + 2
19
+ // Built at the first open, so a picker that never opens it holds no menu.
20
+ property Item menu: null
21
+
22
+ width: Theme.menuWidth
23
+ visible: root.chips.length > 0
24
+ enabled: !root.picker.backendUnavailable && !root.picker.submitting
25
+ opacity: root.enabled ? 1 : Theme.disabledOpacity
26
+ activeFocusOnTab: root.enabled
27
+
28
+ Accessible.role: Accessible.ComboBox
29
+ Accessible.name: root.name
30
+ Accessible.description: root.current >= 0 ? root.chips[root.current].label : ""
31
+ Accessible.onPressAction: root.open()
32
+
33
+ Keys.onTabPressed: function(event) { root.picker.stepFocus(root, (event.modifiers & Qt.ShiftModifier) !== 0) }
34
+ Keys.onBacktabPressed: root.picker.stepFocus(root, true)
35
+ Keys.onReturnPressed: root.open()
36
+ Keys.onEnterPressed: root.open()
37
+ Keys.onSpacePressed: root.open()
38
+ Keys.onDownPressed: root.open()
39
+
40
+ // One entry per filter then All files, the mark slot empty; the action carries the filter index.
41
+ function open() {
42
+ if (!root.enabled) return
43
+ if (!root.menu) {
44
+ root.menu = Qt.createComponent("ContextMenu.qml").createObject(root.picker.contentItem)
45
+ root.menu.railChosen.connect(function(action) { if (root.enabled) root.picker.filterIndex = parseInt(action) })
46
+ }
47
+ var entries = root.chips.map(function(chip) { return {label: chip.label, action: String(chip.index), mark: "", hint: ""} })
48
+ // The menu is as tall as its rows and padding, so its bottom edge is the trigger's top.
49
+ var shut = root.mapToItem(root.picker.contentItem, 0, 0)
50
+ root.menu.openForRail("filter", entries, Qt.point(shut.x, shut.y - entries.length * Theme.rowHeight - 2 * Theme.spacing.rowPaddingY))
51
+ root.menu.cursor = root.current
52
+ }
53
+
54
+ Rectangle {
55
+ anchors.fill: parent
56
+ color: Qt.alpha(Theme.color.foreground, hover.hovered || press.pressed ? Theme.washHover : 0)
57
+ border.width: Theme.spacing.hairline
58
+ border.color: root.activeFocus ? Theme.color.accent : Theme.color.muted
59
+ }
60
+
61
+ Text {
62
+ anchors.left: parent.left
63
+ anchors.leftMargin: Theme.spacing.gap
64
+ anchors.right: chevron.left
65
+ anchors.rightMargin: Theme.spacing.gap
66
+ anchors.verticalCenter: parent.verticalCenter
67
+ text: root.current >= 0 ? root.chips[root.current].label : ""
68
+ color: Theme.color.foreground
69
+ font.family: Theme.font.family
70
+ font.pixelSize: Theme.font.body
71
+ textFormat: Text.PlainText
72
+ elide: Text.ElideRight
73
+ }
74
+
75
+ Flea.Glyph {
76
+ id: chevron
77
+ anchors.right: parent.right
78
+ anchors.rightMargin: Theme.spacing.gap
79
+ anchors.verticalCenter: parent.verticalCenter
80
+ width: root.chevronSize
81
+ height: width
82
+ maxSize: width
83
+ name: "chevron-down"
84
+ color: Qt.alpha(Theme.color.foreground, root.chevronAlpha)
85
+ }
86
+
87
+ HoverHandler {
88
+ id: hover
89
+ cursorShape: Qt.PointingHandCursor
90
+ }
91
+
92
+ TapHandler {
93
+ id: press
94
+ acceptedButtons: Qt.LeftButton
95
+ onTapped: { root.forceActiveFocus(Qt.MouseFocusReason); root.open() }
96
+ }
97
+ }