Fix: ComboSetting support for QStringList models and multiple model types
- Add type detection for three different model types:
- QStringList (video devices): plain strings
- Audio devices: objects with {id, display_name}
- Simple entries (language, color): objects with {text, value}
- Set textRole: "" for video devices ComboBox (QStringList)
- Fix ComboBox popup background color for dark mode
- Add window background color to CallsWindow for dark mode
- Update documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
ae94b325b1
commit
1c7e9271bf
5 changed files with 106 additions and 9 deletions
|
|
@ -202,11 +202,72 @@ AbstractWindow {
|
|||
}
|
||||
```
|
||||
|
||||
## 4. ComboSetting unterstützt verschiedene Model-Typen
|
||||
|
||||
### Problem
|
||||
Die ComboSetting-Komponente konnte nur mit einem Model-Typ umgehen. Es gibt aber drei verschiedene Typen:
|
||||
1. **Audio-Geräte**: `QVariantList` mit Objekten `{id: "...", display_name: "..."}`
|
||||
2. **Einfache Einträge**: `QVariantList` mit Objekten `{text: "...", value: "..."}`
|
||||
3. **Video-Geräte**: `QStringList` mit einfachen Strings
|
||||
|
||||
### Symptome
|
||||
- Audio-Geräte (Lautsprecher, Mikrofon, Klingel) wurden nach Neustart nicht korrekt angezeigt
|
||||
- Kamera-Dropdown zeigte keine Gerätenamen an (nur leere Einträge)
|
||||
|
||||
### Lösung
|
||||
**Datei:** `Linphone/view/Control/Button/Settings/ComboSetting.qml`
|
||||
|
||||
Die `currentIndex`-Berechnung, `onCurrentIndexChanged` und `Binding.value` wurden erweitert, um alle drei Typen zu erkennen und korrekt zu verarbeiten:
|
||||
|
||||
```qml
|
||||
currentIndex: Utils.findIndex(model, function (entry) {
|
||||
var currentVal = propertyOwnerGui
|
||||
? propertyOwnerGui.core[mainItem.propertyName]
|
||||
: propertyOwner[mainItem.propertyName]
|
||||
// Handle different entry types
|
||||
if (typeof entry === 'string') {
|
||||
// QStringList (video devices): compare strings directly
|
||||
return entry === currentVal
|
||||
} else if (entry.id !== undefined) {
|
||||
// Audio devices: compare by id
|
||||
return currentVal && entry.id === currentVal.id
|
||||
} else if (entry.value !== undefined) {
|
||||
// Simple entries (language, color): compare by value
|
||||
return entry.value === currentVal
|
||||
}
|
||||
return false
|
||||
})
|
||||
```
|
||||
|
||||
**Datei:** `Linphone/view/Control/Form/Settings/MultimediaSettings.qml`
|
||||
|
||||
Für die Kamera-ComboBox wurde `textRole: ""` gesetzt, da QStringList-Models keine Properties haben:
|
||||
|
||||
```qml
|
||||
ComboSetting {
|
||||
id: videoDevicesCbox
|
||||
entries: SettingsCpp.videoDevices
|
||||
propertyName: "videoDevice"
|
||||
propertyOwner: SettingsCpp
|
||||
textRole: "" // Empty for QStringList models
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Technischer Hintergrund
|
||||
|
||||
| Model-Typ | Beispiel | Vergleich | Rückgabewert |
|
||||
|-----------|----------|-----------|--------------|
|
||||
| QStringList | `"V4L2: /dev/video0"` | `entry === currentVal` | `entry` (String) |
|
||||
| Audio-Geräte | `{id: "pulse:0", display_name: "Speaker"}` | `entry.id === currentVal.id` | `entry` (Objekt) |
|
||||
| Einfache Einträge | `{text: "English", value: "en"}` | `entry.value === currentVal` | `entry.value` (String) |
|
||||
|
||||
## Zusammenfassung der geänderten Dateien
|
||||
|
||||
| Datei | Änderung |
|
||||
|-------|----------|
|
||||
| `ComboSetting.qml` | valueRole/textRole und korrekter Wertvergleich |
|
||||
| `ComboSetting.qml` | Unterstützung für drei Model-Typen (QStringList, Audio-Geräte, einfache Einträge) |
|
||||
| `MultimediaSettings.qml` | `textRole: ""` für Kamera-ComboBox |
|
||||
| `TextField.qml` | Binding nach Windows-Workaround wiederherstellen |
|
||||
| `ComboBox.qml` | Popup-Hintergrundfarbe für Dark Mode |
|
||||
| `DisplaySettingsLayout.qml` | Tippfehler bei Farbname korrigiert |
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ Control.ComboBox {
|
|||
Layout.leftMargin: delegateImg.visible ? 0 : Utils.getSizeWithScreenRatio(5)
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
visible: mainItem.flagRole
|
||||
color: DefaultStyle.main2_600
|
||||
font {
|
||||
family: DefaultStyle.flagFont
|
||||
pixelSize: mainItem.pixelSize
|
||||
|
|
@ -216,6 +217,7 @@ Control.ComboBox {
|
|||
Layout.leftMargin: delegateImg.visible ? 0 : Utils.getSizeWithScreenRatio(flagItem.visble ? 5 : 25)
|
||||
Layout.rightMargin: Utils.getSizeWithScreenRatio(20)
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
color: DefaultStyle.main2_600
|
||||
text: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text ? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] : $modelData : ""
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
|
|
|
|||
|
|
@ -49,27 +49,57 @@ RowLayout {
|
|||
Layout.preferredWidth: titleText.length > 0 ? Utils.getSizeWithScreenRatio(200) : undefined
|
||||
Layout.fillWidth: titleText.length === 0
|
||||
oneLine: true
|
||||
valueRole: "value"
|
||||
textRole: "text"
|
||||
currentIndex: Utils.findIndex(model, function (entry) {
|
||||
var currentVal = propertyOwnerGui
|
||||
? propertyOwnerGui.core[mainItem.propertyName]
|
||||
: propertyOwner[mainItem.propertyName]
|
||||
// Compare entry.value with the stored value (both are simple strings like "en", "orange")
|
||||
// Handle different entry types
|
||||
if (typeof entry === 'string') {
|
||||
// QStringList (video devices): compare strings directly
|
||||
return entry === currentVal
|
||||
} else if (entry.id !== undefined) {
|
||||
// Audio devices: compare by id
|
||||
return currentVal && entry.id === currentVal.id
|
||||
} else if (entry.value !== undefined) {
|
||||
// Simple entries (language, color): compare by value
|
||||
return entry.value === currentVal
|
||||
}
|
||||
return false
|
||||
})
|
||||
onCurrentValueChanged: {
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex < 0 || !model) return
|
||||
var entry = model[currentIndex]
|
||||
if (!entry) return
|
||||
var storedVal = propertyOwnerGui
|
||||
? propertyOwnerGui.core[mainItem.propertyName]
|
||||
: propertyOwner[mainItem.propertyName]
|
||||
// currentValue is now just the value string (e.g., "en", "orange")
|
||||
binding.when = currentValue !== storedVal
|
||||
// Determine if values differ based on entry type
|
||||
if (typeof entry === 'string') {
|
||||
// QStringList: compare strings directly
|
||||
binding.when = entry !== storedVal
|
||||
} else if (entry.id !== undefined) {
|
||||
// Audio devices: compare by id
|
||||
binding.when = !storedVal || entry.id !== storedVal.id
|
||||
} else if (entry.value !== undefined) {
|
||||
// Simple entries: compare by value
|
||||
binding.when = entry.value !== storedVal
|
||||
}
|
||||
}
|
||||
Binding {
|
||||
id: binding
|
||||
target: propertyOwnerGui ? propertyOwnerGui.core : propertyOwner
|
||||
property: mainItem.propertyName
|
||||
value: comboBox.currentValue
|
||||
value: {
|
||||
if (comboBox.currentIndex < 0 || !comboBox.model) return undefined
|
||||
var entry = comboBox.model[comboBox.currentIndex]
|
||||
if (!entry) return undefined
|
||||
// Return based on entry type
|
||||
if (typeof entry === 'string') return entry // QStringList
|
||||
if (entry.id !== undefined) return entry // Audio devices
|
||||
if (entry.value !== undefined) return entry.value // Simple entries
|
||||
return entry
|
||||
}
|
||||
when: false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ ColumnLayout {
|
|||
//: "Haut-parleurs"
|
||||
text: qsTr("multimedia_settings_speaker_title")
|
||||
font: Typography.p2l
|
||||
color: DefaultStyle.main2_600
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
|
@ -130,6 +131,7 @@ ColumnLayout {
|
|||
//: "Microphone"
|
||||
text: qsTr("multimedia_settings_microphone_title")
|
||||
font: Typography.p2l
|
||||
color: DefaultStyle.main2_600
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
|
@ -220,6 +222,7 @@ ColumnLayout {
|
|||
//: "Caméra"
|
||||
text: qsTr("multimedia_settings_camera_title")
|
||||
font: Typography.p2l
|
||||
color: DefaultStyle.main2_600
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
|
@ -231,6 +234,7 @@ ColumnLayout {
|
|||
entries: SettingsCpp.videoDevices
|
||||
propertyName: "videoDevice"
|
||||
propertyOwner: SettingsCpp
|
||||
textRole: ""
|
||||
Connections {
|
||||
enabled: mainItem.call
|
||||
target: videoDevicesCbox
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ AbstractWindow {
|
|||
/************************* CONTENT ********************************/
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: DefaultStyle.grey_900
|
||||
color: "#1a1a1a" // Always dark for call window (video display)
|
||||
focus: true
|
||||
|
||||
ColumnLayout {
|
||||
|
|
|
|||
Loading…
Reference in a new issue