Phase 1 shipped a fixed 6-button toolbar. Phase 2 moves visibility to
the config so users pick which buttons appear.
Config (config.rs):
- new ToolbarItems struct (CosmicConfigEntry) with one bool per button
- Config.toolbar: ToolbarItems, default = 'minimal 6' set from phase 1
(new_folder, rename, delete, cut, copy, paste) + 5 extras off
(new_file, reload, toggle_show_hidden, open_terminal, location_up)
Rendering (view()):
- iterate through self.config.toolbar fields in fixed logical order
(location → create/edit → clipboard → view toggles)
- dividers inserted only between non-empty groups
- whole toolbar hidden if every button is off (no empty container)
Settings page (settings()):
- new 'Toolbar' section with one toggler per button, wired through
Message::SetToolbar(ToolbarItems) which persists via config_set!
i18n (en + fr):
- added 'toolbar' + 'parent-directory' strings
- reused existing new-folder / new-file / rename / delete / cut / copy /
paste / reload-folder / show-hidden-files / open-in-terminal
All actions dispatch through Action::message so keybindings and toolbar
share one code path.
The 'Open with...' dialog let you pick an app but never remembered your
choice — you'd see the same dialog again next time. The infrastructure
was already there (MimeAppCache::set_default writes to mimeapps.list),
just never wired to the UI.
Adds a toggler below the app list labelled 'Always use this app for this
file type' (EN) / 'Toujours utiliser cette application pour ce type de
fichier' (FR). When enabled, after spawning the selected app, the
default handler for the file's mime type is persisted via
self.mime_app_cache.set_default(mime, app.id).
Implementation:
- DialogPage::OpenWith gains a set_default: bool field (defaulted false)
- Message::OpenWithToggleDefault(bool) + handler mutates the dialog state
- DialogComplete handler for OpenWith calls set_default after a clean
spawn when the flag is set
- Dialog rendering adds a .control(widget::row) with label + toggler,
between the scrollable list and the action buttons
- i18n strings added: en/fr open-with-set-default
Closes: #1157
The fix splits the "canceled" and "failed" states for OperationError. It
also preserves that state because some functions overwrote the state by
rewrapping the error.