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,378 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+ import "." as Flea
4
+ import "js/Archive.js" as Archive
5
+ import "js/ArchiveCard.js" as ArchiveCard
6
+
7
+ // The With-password compress card: format, name, the password pair and the header switch, on the shipped dialog controls.
8
+ Item {
9
+ id: root
10
+
11
+ property bool opened: false
12
+ property var owner: null
13
+ property var source: null
14
+ property int count: 0
15
+ property string parentLeaf: ""
16
+ property var formats: ["7z", "zip"]
17
+ property string format: "7z"
18
+ property string stem: ""
19
+ property bool encryptNames: true
20
+ property string errorText: ""
21
+ property int focusPart: 0
22
+
23
+ signal accepted(var source, string format, string name, string password, bool encryptNames)
24
+
25
+ readonly property string password: passwordField.text
26
+ readonly property string confirm: confirmField.text
27
+ readonly property bool matched: root.password === root.confirm
28
+ // A password card compresses only with a password typed twice, so an empty pair never reaches the wire.
29
+ readonly property bool canCompress: root.opened && root.matched && root.password.length > 0 && root.name.length > 0
30
+ readonly property string name: nameField.text
31
+ readonly property var cancelItem: cancelButton
32
+ readonly property var submitItem: compressButton
33
+ readonly property var bodyItem: body
34
+ readonly property int dialogWidth: 448
35
+ readonly property int clampMargin: 8
36
+ readonly property var cardItem: card
37
+
38
+ // What a capture reads instead of the fields: the eye, which field wears the error frame, never a typed character.
39
+ function captureState() {
40
+ return { encrypt: root.encryptNames, encryptShown: encryptRow.visible, revealed: passwordField.revealed, eye: passwordField.eyeCentre(),
41
+ passwordError: passwordField.error, confirmError: confirmField.error }
42
+ }
43
+
44
+ anchors.fill: parent
45
+ visible: root.opened || root.opacity > 0
46
+ // Closed means no input, even while the fade-out is still drawn.
47
+ enabled: root.opened
48
+ opacity: 0
49
+ z: 2
50
+
51
+ Flea.Reveal { target: root; shown: root.opened; lift: card }
52
+ // The name clears once the fade ended, so the card stays still while it fades out; open() sets it again.
53
+ onOpacityChanged: if (root.opacity === 0 && !root.opened) nameField.text = ""
54
+
55
+ // The tab order; a disabled stop is skipped, so Tab never lands on a button that does nothing.
56
+ function tabStops() {
57
+ var stops = [formatRow, nameField.input, passwordField.input, confirmField.input]
58
+ if (root.format === "7z") stops.push(encryptRow)
59
+ return stops.concat([cancelButton, compressButton]).filter(function (s) { return s.enabled })
60
+ }
61
+
62
+ function stepTab(back) {
63
+ var stops = root.tabStops()
64
+ var at = -1
65
+ for (var i = 0; i < stops.length; i++) {
66
+ if (stops[i].activeFocus) { at = i; break }
67
+ }
68
+ var next = at < 0 ? (back ? stops.length - 1 : 0)
69
+ : (at + (back ? stops.length - 1 : 1)) % stops.length
70
+ // The rings read focusPart, so a ring follows the tab stop.
71
+ if (stops[next] === cancelButton) root.focusPart = 5
72
+ else if (stops[next] === compressButton) root.focusPart = 6
73
+ else if (stops[next] === encryptRow) root.focusPart = 4
74
+ else if (stops[next] === formatRow) root.focusPart = 1
75
+ else root.focusPart = 0
76
+ stops[next].forceActiveFocus()
77
+ }
78
+
79
+ Keys.onEscapePressed: function (event) { root.close(); event.accepted = true }
80
+ Keys.onTabPressed: function (event) { root.stepTab((event.modifiers & Qt.ShiftModifier) !== 0); event.accepted = true }
81
+ Keys.onBacktabPressed: function (event) { root.stepTab(true); event.accepted = true }
82
+ Keys.onPressed: function (event) {
83
+ if (formatRow.activeFocus
84
+ && (event.key === Qt.Key_Left || event.key === Qt.Key_Right)) {
85
+ var at = root.formats.indexOf(root.format)
86
+ root.chooseFormat(at + (event.key === Qt.Key_Right ? 1 : -1))
87
+ event.accepted = true
88
+ return
89
+ }
90
+ if (encryptRow.activeFocus && event.key === Qt.Key_Space) {
91
+ root.encryptNames = !root.encryptNames
92
+ event.accepted = true
93
+ return
94
+ }
95
+ if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
96
+ && (formatRow.activeFocus || encryptRow.activeFocus)) {
97
+ root.commit()
98
+ event.accepted = true
99
+ }
100
+ }
101
+
102
+ // Test seam for the threat walk: types into the pair the way keys would, the confirm apart when asked.
103
+ function takeSecretForTest(secret, confirm) {
104
+ passwordField.text = secret
105
+ confirmField.text = confirm === undefined ? secret : confirm
106
+ }
107
+
108
+ // The source is { paths, menuId }, kept whole so the menu id reaches the wire with the submit.
109
+ function open(source, leaf, holder) {
110
+ if (root.opened || !holder || !source || !source.paths || source.paths.length === 0) return
111
+ var paths = source.paths
112
+ root.owner = holder
113
+ var leaves = ArchiveCard.pathLeaves(paths)
114
+ root.source = source
115
+ root.count = paths.length
116
+ root.parentLeaf = leaf || ""
117
+ // The board's order, 7z first, whatever order the backend reports its formats in.
118
+ var have = holder.backend.archiveFormats || []
119
+ var offered = ["7z", "zip"].filter(function (f) { return have.indexOf(f) >= 0 })
120
+ root.formats = offered.length > 0 ? offered : ["7z"]
121
+ root.format = root.formats.indexOf("7z") >= 0 ? "7z" : root.formats[0]
122
+ root.stem = Archive.archiveStem(leaves, root.parentLeaf)
123
+ root.encryptNames = true
124
+ root.errorText = ""
125
+ root.focusPart = 2
126
+ root.opened = true
127
+ body.contentY = 0
128
+ nameField.text = root.stem + "." + root.format
129
+ passwordField.text = ""
130
+ confirmField.text = ""
131
+ passwordField.takeFocus()
132
+ }
133
+
134
+ // The fields clear on close, so a secret never outlives the card that took it.
135
+ function close() {
136
+ if (!root.opened)
137
+ return
138
+ passwordField.text = ""
139
+ confirmField.text = ""
140
+ root.stem = ""
141
+ root.source = null
142
+ root.opened = false
143
+ if (root.owner && root.owner.listArea)
144
+ root.owner.listArea.forceActiveFocus()
145
+ }
146
+
147
+ function chooseFormat(index) {
148
+ var next = root.formats[Math.max(0, Math.min(root.formats.length - 1, index))]
149
+ if (next === root.format) return
150
+ root.format = next
151
+ nameField.text = root.stem + "." + next
152
+ }
153
+
154
+ function commit() {
155
+ if (!root.opened) return
156
+ if (!root.canCompress) {
157
+ if (!root.matched) root.errorText = "Passwords do not match."
158
+ else if (root.password.length === 0) root.errorText = "Type a password first."
159
+ // Only an empty name is left: the old sentence goes and the focus moves to that field.
160
+ else { root.errorText = ""; root.focusPart = 0; nameField.takeFocus() }
161
+ return
162
+ }
163
+ root.errorText = ""
164
+ // Accepted before close, so the owner's submit still sees the source; close clears the fields.
165
+ root.accepted(root.source, root.format, root.name, root.password,
166
+ root.encryptNames && root.format === "7z")
167
+ root.close()
168
+ }
169
+
170
+ Flea.DialogScrim {
171
+ onDismissed: root.close()
172
+ }
173
+
174
+ Rectangle {
175
+ id: card
176
+ x: Theme.cardOrigin(root.width, width)
177
+ y: Theme.cardOrigin(root.height, height)
178
+ width: Theme.cardSpan(Theme.space(root.dialogWidth) * Theme.dialogWidthRatio, root.width - 2 * root.clampMargin)
179
+ // Clamped to the window; the body scrolls whatever the clamp cut, see ui/CardScroll.qml.
180
+ height: Theme.cardSpan(body.wanted + 2 * Theme.spacing.rowPaddingX, root.height - 2 * root.clampMargin)
181
+ color: Theme.color.surface
182
+ border.width: Theme.spacing.hairline
183
+ border.color: Theme.color.mutedFrame
184
+ radius: Style.cornerRadius
185
+
186
+ MouseArea {
187
+ anchors.fill: parent
188
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
189
+ hoverEnabled: true
190
+ onClicked: {}
191
+ onWheel: function (wheel) { wheel.accepted = true }
192
+ }
193
+
194
+ Flea.CardFrame {
195
+ id: body
196
+ bleedY: Theme.focusClearance
197
+ anchors.fill: parent
198
+ anchors.topMargin: Theme.spacing.rowPaddingX - Theme.focusClearance
199
+ anchors.bottomMargin: Theme.spacing.rowPaddingX - Theme.focusClearance
200
+ spacing: Theme.spacing.rowPaddingX
201
+
202
+ title: Item {
203
+ width: parent.width
204
+ height: header.implicitHeight + Theme.spacing.gap
205
+
206
+ Flea.DialogTitle {
207
+ id: header
208
+ anchors.left: parent.left
209
+ anchors.right: parent.right
210
+ anchors.margins: Theme.spacing.rowPaddingX
211
+ text: ArchiveCard.compressTitle(root.count)
212
+ elide: Text.ElideMiddle
213
+ }
214
+
215
+ Rectangle {
216
+ anchors.bottom: parent.bottom
217
+ x: Theme.spacing.rowPaddingX
218
+ width: parent.width - 2 * Theme.spacing.rowPaddingX
219
+ height: Theme.spacing.hairline
220
+ color: Theme.color.mutedFrame
221
+ opacity: 0.4
222
+ }
223
+ }
224
+
225
+ buttons: Item {
226
+ width: parent.width
227
+ height: Math.max(cancelButton.implicitHeight, compressButton.implicitHeight)
228
+ Row {
229
+ anchors.bottom: parent.bottom
230
+ anchors.right: parent.right
231
+ anchors.rightMargin: Theme.spacing.rowPaddingX
232
+ spacing: Theme.spacing.gap
233
+
234
+ Flea.DialogButton {
235
+ id: cancelButton
236
+ label: "Cancel"
237
+ focused: root.focusPart === 5
238
+ onActivated: root.close()
239
+ onTabbed: function (from, back) { root.stepTab(back) }
240
+ }
241
+
242
+ Flea.DialogButton {
243
+ id: compressButton
244
+ label: "Compress"
245
+ primary: true
246
+ focused: root.focusPart === 6
247
+ onActivated: root.commit()
248
+ onTabbed: function (from, back) { root.stepTab(back) }
249
+ }
250
+ }
251
+ }
252
+
253
+ Column {
254
+ width: parent.width
255
+ spacing: Theme.spacing.rowPaddingX
256
+
257
+ // The segment's own caption, in the same capitals and at the same distance DialogField draws above its box.
258
+ Column {
259
+ x: Theme.spacing.rowPaddingX
260
+ width: parent.width - 2 * Theme.spacing.rowPaddingX
261
+ spacing: Theme.spacing.hairline * 4
262
+
263
+ Text {
264
+ width: parent.width
265
+ text: "FORMAT"
266
+ color: Theme.color.muted
267
+ font.family: Theme.font.family
268
+ font.pixelSize: Theme.font.caption
269
+ font.letterSpacing: Theme.font.caption * nameField.labelSpacing
270
+ textFormat: Text.PlainText
271
+ }
272
+
273
+ Flea.SettingsSegment {
274
+ id: formatRow
275
+ tabStop: true
276
+ options: root.formats
277
+ value: root.format
278
+ onPicked: function (index) { root.chooseFormat(index) }
279
+ }
280
+ }
281
+
282
+ Flea.DialogField {
283
+ id: nameField
284
+ x: Theme.spacing.rowPaddingX
285
+ width: parent.width - 2 * Theme.spacing.rowPaddingX
286
+ label: "Name"
287
+ placeholder: "Archive.7z"
288
+ onAccepted: root.commit()
289
+ onTabbed: function (from, back) { root.stepTab(back) }
290
+ }
291
+
292
+ Flea.DialogField {
293
+ id: passwordField
294
+ x: Theme.spacing.rowPaddingX
295
+ width: parent.width - 2 * Theme.spacing.rowPaddingX
296
+ label: "Password"
297
+ secret: true
298
+ error: root.errorText.length > 0 && root.password.length === 0
299
+ onEdited: root.errorText = ""
300
+ onAccepted: root.commit()
301
+ onTabbed: function (from, back) { root.stepTab(back) }
302
+ }
303
+
304
+ // The extract card's recipe: the refused field in the error frame, its bare sentence directly under the pair.
305
+ Column {
306
+ x: Theme.spacing.rowPaddingX
307
+ width: parent.width - 2 * Theme.spacing.rowPaddingX
308
+ spacing: Theme.spacing.gap
309
+
310
+ Flea.DialogField {
311
+ id: confirmField
312
+ width: parent.width
313
+ label: "Confirm"
314
+ secret: true
315
+ error: root.errorText.length > 0 && !root.matched
316
+ onEdited: root.errorText = ""
317
+ onAccepted: root.commit()
318
+ onTabbed: function (from, back) { root.stepTab(back) }
319
+ }
320
+
321
+ Text {
322
+ width: parent.width
323
+ visible: root.errorText.length > 0
324
+ text: root.errorText
325
+ color: Theme.color.errorOnSurface
326
+ font { family: Theme.font.family; pixelSize: Theme.font.caption }
327
+ textFormat: Text.PlainText
328
+ wrapMode: Text.Wrap
329
+ }
330
+ }
331
+
332
+ Item {
333
+ id: encryptRow
334
+ width: parent.width
335
+ height: Theme.rowHeight
336
+ visible: root.format === "7z"
337
+ Accessible.role: Accessible.CheckBox
338
+ Accessible.name: "Encrypt file names"
339
+ Accessible.checkable: true
340
+ Accessible.checked: root.encryptNames
341
+
342
+ // An Item, not a Rectangle: a Rectangle with no color paints white behind the unchecked box.
343
+ Item {
344
+ id: box
345
+ anchors.left: parent.left
346
+ anchors.leftMargin: Theme.spacing.rowPaddingX
347
+ anchors.verticalCenter: parent.verticalCenter
348
+ width: ruleBox.implicitWidth
349
+ height: ruleBox.implicitHeight
350
+
351
+ Flea.CheckBox {
352
+ id: ruleBox
353
+ value: root.encryptNames ? "on" : "off"
354
+ focused: root.focusPart === 4
355
+ }
356
+ }
357
+
358
+ Text {
359
+ anchors.left: box.right
360
+ anchors.leftMargin: Theme.spacing.gap
361
+ anchors.verticalCenter: parent.verticalCenter
362
+ text: "Encrypt file names"
363
+ color: Theme.color.foreground
364
+ font.family: Theme.font.family
365
+ font.pixelSize: Theme.font.body
366
+ textFormat: Text.PlainText
367
+ }
368
+
369
+ TapHandler {
370
+ acceptedButtons: Qt.LeftButton
371
+ gesturePolicy: TapHandler.ReleaseWithinBounds
372
+ onTapped: root.encryptNames = !root.encryptNames
373
+ }
374
+ }
375
+ }
376
+ }
377
+ }
378
+ }
@@ -0,0 +1,127 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+ import "." as Flea
4
+
5
+ // Bulk extraction is deliberate: Enter defaults to Cancel, as in permanent deletion.
6
+ FocusScope {
7
+ id: root
8
+ anchors.fill: parent
9
+ visible: opened || opacity > 0
10
+ // Closed means no input, even while the fade-out is still drawn.
11
+ enabled: opened
12
+ opacity: 0
13
+ property bool opened: false
14
+ property var snapshot: ({})
15
+ property bool destructiveFocus: false
16
+ readonly property real referenceScale: Theme.font.bodySmall / 13
17
+ readonly property real cardPadding: Math.round(16 * referenceScale)
18
+ readonly property real cardBottomPadding: Theme.spacing.rowPaddingX
19
+ signal confirmed(var source)
20
+ signal cancelled()
21
+ readonly property var cardItem: card
22
+ readonly property var cancelItem: cancelButton
23
+ readonly property var dangerItem: dangerButton
24
+ readonly property string titleText: title.text
25
+ readonly property string bodyText: bodyLabel.text
26
+ function open(value) { snapshot = value; destructiveFocus = false; body.contentY = 0; opened = true; forceActiveFocus() }
27
+ function close() { opened = false }
28
+ function cancel() { close(); cancelled() }
29
+ function activate() {
30
+ if (!destructiveFocus) { cancel(); return }
31
+ var source = snapshot
32
+ close()
33
+ confirmed(source)
34
+ }
35
+ Flea.Reveal { target: root; shown: root.opened; lift: card }
36
+ Keys.onPressed: function(event) {
37
+ if (event.key === Qt.Key_Escape) root.cancel()
38
+ else if (event.modifiers & (Qt.ControlModifier | Qt.AltModifier | Qt.MetaModifier)) { event.accepted = true; return }
39
+ else if (event.key === Qt.Key_Tab || event.key === Qt.Key_Backtab) root.destructiveFocus = !root.destructiveFocus
40
+ else if (event.key === Qt.Key_L || event.key === Qt.Key_Right) root.destructiveFocus = true
41
+ else if (event.key === Qt.Key_H || event.key === Qt.Key_Left) root.destructiveFocus = false
42
+ else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter || event.key === Qt.Key_Space) root.activate()
43
+ if (root.opened) body.reveal(root.destructiveFocus ? dangerButton : cancelButton)
44
+ event.accepted = true
45
+ }
46
+ Rectangle {
47
+ anchors.fill: parent
48
+ color: Theme.color.background
49
+ opacity: 0.5
50
+ MouseArea {
51
+ anchors.fill: parent
52
+ hoverEnabled: true
53
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
54
+ onClicked: root.cancel()
55
+ onWheel: function(wheel) { wheel.accepted = true }
56
+ }
57
+ }
58
+ Rectangle {
59
+ id: card
60
+ x: Theme.cardOrigin(root.width, width)
61
+ y: Theme.cardOrigin(root.height, height)
62
+ // TrashSidebar's 340px content width excludes its two 16px paddings and hairlines.
63
+ width: Theme.cardSpan(Math.round(340 * root.referenceScale * Theme.dialogWidthRatio) + 2 * root.cardPadding + 2 * Theme.spacing.hairline, root.width - 2 * Theme.spacing.gap)
64
+ height: Theme.cardSpan(body.wanted + root.cardPadding + root.cardBottomPadding + 2 * Theme.spacing.hairline, root.height - 2 * Theme.spacing.gap)
65
+ color: Theme.color.surface
66
+ border.color: Theme.color.mutedFrame
67
+ border.width: Theme.spacing.hairline
68
+ radius: Style.cornerRadius
69
+ MouseArea {
70
+ anchors.fill: parent
71
+ hoverEnabled: true
72
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
73
+ onWheel: function(wheel) { wheel.accepted = true }
74
+ }
75
+ Flea.CardFrame {
76
+ id: body
77
+ bleed: Theme.focusClearance
78
+ anchors.fill: parent
79
+ anchors.leftMargin: root.cardPadding + Theme.spacing.hairline - Theme.focusClearance
80
+ anchors.rightMargin: root.cardPadding + Theme.spacing.hairline - Theme.focusClearance
81
+ anchors.topMargin: root.cardPadding + Theme.spacing.hairline - Theme.focusClearance
82
+ anchors.bottomMargin: root.cardBottomPadding + Theme.spacing.hairline - Theme.focusClearance
83
+ title: Row {
84
+ width: parent.width
85
+ spacing: Theme.spacing.gap
86
+ Flea.Glyph { id: alertMark; width: Theme.font.bodySmall * 1.3; height: title.height; name: "alert"; color: Theme.color.error }
87
+ Text {
88
+ id: title
89
+ width: parent.width - alertMark.width - parent.spacing
90
+ text: "Extract here?"
91
+ textFormat: Text.PlainText
92
+ wrapMode: Text.Wrap
93
+ color: Theme.color.foreground
94
+ font { family: Theme.font.family; pixelSize: Theme.font.body; bold: true }
95
+ }
96
+ }
97
+ buttons: Flow {
98
+ width: Math.min(parent.width, cancelButton.implicitWidth + dangerButton.implicitWidth + spacing)
99
+ anchors.right: parent.right
100
+ spacing: Theme.spacing.gap
101
+ Flea.DialogButton {
102
+ id: cancelButton
103
+ label: "Cancel"
104
+ primary: true
105
+ focused: !root.destructiveFocus
106
+ onActivated: root.cancel()
107
+ }
108
+ Flea.DialogButton {
109
+ id: dangerButton
110
+ label: "Extract here"
111
+ destructive: true
112
+ focused: root.destructiveFocus
113
+ onActivated: { root.destructiveFocus = true; root.activate() }
114
+ }
115
+ }
116
+ Text {
117
+ id: bodyLabel
118
+ width: parent.width
119
+ text: (root.snapshot.entries >= 0 ? root.snapshot.entries + " top-level items" : "This archive") + " will be extracted into:\n" + root.snapshot.dest + "\n\nExisting names will get a copy suffix. Continue?"
120
+ textFormat: Text.PlainText
121
+ wrapMode: Text.Wrap
122
+ color: Theme.color.foreground
123
+ font { family: Theme.font.family; pixelSize: Theme.font.body }
124
+ }
125
+ }
126
+ }
127
+ }