// SPDX-FileCopyrightText: 2020 George Florea Bănuș // SPDX-FileCopyrightText: 2026 Tri Vo Khac // SPDX-License-Identifier: GPL-3.0-or-later pragma ComponentBehavior: Bound import QtQuick import QtQuick.Controls import org.kde.ki18n // Checkable list of subtitle tracks, for the primary or the secondary subtitle. AppMenu { id: root icon.name: isPrimary ? "text-x-generic" : "text-x-script" required property MpvItem mpv property bool isPrimary: true readonly property int selectedId: isPrimary ? mpv.subtitleId : mpv.secondarySubtitleId readonly property int otherId: isPrimary ? mpv.secondarySubtitleId : mpv.subtitleId function trackLabel(track: var): string { const name = track.title || (track.external ? track.externalFilename.split("/").pop() : "") const lang = track.lang ? `[${track.lang}]` : "" const description = [name, lang].filter(part => part.length > 0).join(" ") return KI18n.i18nc("@item:inmenu subtitle track number and description", "%1: %2", track.id, description || KI18n.i18nc("@item:inmenu", "Untitled")) } function select(id: int) { if (root.isPrimary) { root.mpv.subtitleId = id } else { root.mpv.secondarySubtitleId = id } } enabled: mpv.subtitleTracks.length > 0 ButtonGroup { id: tracksGroup; exclusive: true } AppMenuItem { text: KI18n.i18nc("@item:inmenu no subtitle", "None") checkable: true ButtonGroup.group: tracksGroup checked: root.selectedId === 0 onTriggered: { root.select(0) // Keep mpv authoritative after MenuItem updates its checked state. checked = Qt.binding(() => root.selectedId === 0) } } Instantiator { model: root.mpv.subtitleTracks delegate: AppMenuItem { id: trackItem required property var modelData text: root.trackLabel(modelData) checkable: true ButtonGroup.group: tracksGroup checked: modelData.id === root.selectedId // mpv cannot show one track in both places. enabled: modelData.id !== root.otherId onTriggered: { root.select(modelData.id) checked = Qt.binding(() => trackItem.modelData.id === root.selectedId) } } onObjectAdded: (index, object) => root.insertItem(index + 1, object) onObjectRemoved: (index, object) => root.removeItem(object) } }