The reader had been there the whole time — `theme_qt.rs` builds
`AutoSource::Image` from `auto_theme_image_path` — with no way for a user
to write it, which made "Custom Image" a source you could select and never
supply. Adds the native picker (rfd, through the `settingsString` action
seam the folder chooser already uses), the "Detected: <desktop>" hint from
the shared detector, and the experimental caveat. Persisting the path also
sets source=image before regenerating, because the theme re-reads the prefs.
No new msgids: all four are already in the eight catalogs.
Also deletes eight header comments that were false, each verified against
the code before removing it:
- LocalLibrarySettings: "no native folder picker" (library-pick-folder
uses rfd) and "LibFolderEditModal not ported" (it is, and mounted at
SettingsView.qml:330)
- OfflineSettings + settings_qt/offline.rs: "Check now not shipped" (the
button is right there)
- DeveloperSettings: "in-app log viewer not ported" (LogViewerModal.qml)
and "export always without auth" (the credentials switch is inline)
- PlexSettings: "the PIN flow is not ported" (Generate/Link/Copy code and
Open sign-in all present)
- settings_qt.rs: "no JACK in the POC build" (the banner is in
AudioSettings.qml), plus the wizard and settings export, both shipped
- tray_qt.rs and auth_qt.rs: "the Qt port has no session_persist module"
— false since the queue restore landed; this port flushes once after
the event loop instead of from each quit handler
A "not ported" note that outlives the port is worse than no note: the last
round of recon believed two of these and planned around them.
cc
119 lines
4.9 KiB
QML
119 lines
4.9 KiB
QML
// Settings > Developer — the QML port of crates/qbz-ui/ui/settings/
|
|
// DeveloperSettings.slint.
|
|
//
|
|
// Shipped, in the Slint's order: QOBUZ CONNECT · LOGS · SETTINGS PORTABILITY.
|
|
//
|
|
// Deltas vs the Slint (no dead rows):
|
|
// - LOGS offers TWO buttons where the Slint has one: "View logs" opens the
|
|
// in-app viewer (copy / redact / upload) and "Open log file" hands the
|
|
// on-disk sink to the desktop.
|
|
// - "Export settings…" carries its include-auth gate INLINE (the
|
|
// "Include sign-in credentials" switch, default OFF and reset on hide)
|
|
// instead of inside a SettingsExportModal. The modal is a wrapper; the
|
|
// security decision it guards is the same one, in the same place.
|
|
// - The inline DiagnosticsPanel is ported and mounted last, as in the
|
|
// reference — with the GTK/WebKit/GSK/GDK rows CUT, because in a Qt process
|
|
// they can only read "—" and their saved column would come from a file this
|
|
// binary never writes. The panel's own header explains the cut.
|
|
|
|
import QtQuick
|
|
import com.blitzfc.qbz
|
|
import "../controls"
|
|
import "../theme"
|
|
|
|
Column {
|
|
id: root
|
|
|
|
property var doc: ({})
|
|
readonly property var dev: doc.dev || ({})
|
|
|
|
QbzTheme { id: theme }
|
|
|
|
spacing: 4
|
|
|
|
// ========================== QOBUZ CONNECT ============================
|
|
GroupHeader { text: QbzSession.tr("QOBUZ CONNECT", QbzSession.trRev) }
|
|
SettingRow {
|
|
label: QbzSession.tr("Connect diagnostics", QbzSession.trRev)
|
|
description: QbzSession.tr("Live session topology and a rolling event log for debugging Qobuz Connect at runtime.", QbzSession.trRev)
|
|
SettingsButton {
|
|
text: QbzSession.tr("Open diagnostics", QbzSession.trRev)
|
|
onClicked: QbzQConnect.diagSetOpen(true)
|
|
}
|
|
}
|
|
|
|
SettingsSpacer { }
|
|
|
|
// ============================== LOGS =================================
|
|
GroupHeader { text: QbzSession.tr("LOGS", QbzSession.trRev) }
|
|
SettingRow {
|
|
label: QbzSession.tr("Application logs", QbzSession.trRev)
|
|
description: (root.dev.logPath || "") !== ""
|
|
? root.dev.logPath
|
|
: QbzSession.tr("View the in-app log, copy it (secrets redacted), or upload it to share in a GitHub issue.", QbzSession.trRev)
|
|
Row {
|
|
spacing: 8
|
|
// The description above has always promised "view the in-app log,
|
|
// copy it (secrets redacted), or upload it" — until the viewer
|
|
// landed, the only button here did none of those three.
|
|
SettingsButton {
|
|
text: QbzSession.tr("View logs", QbzSession.trRev)
|
|
onClicked: QbzShell.logOpen()
|
|
}
|
|
SettingsButton {
|
|
text: QbzSession.tr("Open log file", QbzSession.trRev)
|
|
enabled: (root.dev.logPath || "") !== ""
|
|
onClicked: QbzBridge.settingsString("open-log-file", "")
|
|
}
|
|
}
|
|
}
|
|
|
|
SettingsSpacer { }
|
|
|
|
// ====================== SETTINGS PORTABILITY =========================
|
|
GroupHeader { text: QbzSession.tr("SETTINGS PORTABILITY", QbzSession.trRev) }
|
|
// The `--include-auth` gate. The reference puts it in a modal
|
|
// (SettingsExportModal.slint) with ONE checkbox, default OFF; this port
|
|
// exports directly from the row, so the checkbox is a row too.
|
|
//
|
|
// DELIBERATELY NOT PERSISTED. The reference's default-OFF is re-asserted
|
|
// every time its modal opens, so the user re-decides per export. A
|
|
// persisted toggle would not: switch it on once and every later export
|
|
// silently carries credentials. `includeAuth` therefore lives here as
|
|
// session state and resets whenever the panel is left.
|
|
property bool includeAuth: false
|
|
onVisibleChanged: if (!visible) root.includeAuth = false
|
|
|
|
SettingRow {
|
|
label: QbzSession.tr("Include sign-in credentials", QbzSession.trRev)
|
|
description: QbzSession.tr("The bundle will contain your tokens. Anyone who opens the file can sign in as you.", QbzSession.trRev)
|
|
QbzToggle {
|
|
checked: root.includeAuth
|
|
onToggled: function (v) { root.includeAuth = v }
|
|
}
|
|
}
|
|
SettingRow {
|
|
label: QbzSession.tr("Export settings…", QbzSession.trRev)
|
|
description: QbzSession.tr("Save a portable bundle of your settings to move to another machine or the qbzd daemon.", QbzSession.trRev)
|
|
SettingsButton {
|
|
text: QbzSession.tr("Export…", QbzSession.trRev)
|
|
onClicked: QbzBridge.settingsString(
|
|
"export-settings", root.includeAuth ? "with-auth" : "")
|
|
}
|
|
}
|
|
Text {
|
|
visible: (root.dev.status || "") !== ""
|
|
width: parent.width
|
|
text: root.dev.status || ""
|
|
color: theme.textMuted
|
|
font.pixelSize: theme.fontLegal
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
|
|
SettingsSpacer { }
|
|
|
|
// ========================== DIAGNOSTICS ==============================
|
|
// Last child, 1:1 with DeveloperSettings.slint:92.
|
|
DiagnosticsPanel { }
|
|
}
|