feat(ui): style app menus and extract glossary dialog

- Add AppMenu and AppMenuItem so menu labels, mnemonics and shortcuts render consistently under org.kde.union
- Move the translation glossary into GlossaryDialog with add, remove and clear-all actions
- Regroup the translation preset and instructions settings layout
This commit was merged in pull request #3.
This commit is contained in:
tri committed 2026-11-07 15:03:37 +07:00
1 parent 9e55dba687
commit de9e6484ee
24 files changed
+533 -166

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
// SPDX-FileCopyrightText: 2026 Tri Vo Khac
// SPDX-License-Identifier: GPL-3.0-or-later
import QtQuick.Controls
Menu {
delegate: AppMenuItem {}
}
+93
View File
@@ -0,0 +1,93 @@
// SPDX-FileCopyrightText: 2026 Tri Vo Khac
// SPDX-License-Identifier: GPL-3.0-or-later
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import org.kde.kirigami as Kirigami
MenuItem {
id: root
// org.kde.desktop sets these on its MenuItem, but other Plasma styles such
// as org.kde.union do not, which would leave the label below empty.
Kirigami.MnemonicData.enabled: enabled && visible
Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.MenuItem
Kirigami.MnemonicData.label: text
// The content includes the submenu arrow slot, so do not add it again as
// the desktop style does. Keep the style's background and indicator sizing.
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
contentItem: Item {
implicitWidth: row.implicitWidth
implicitHeight: row.implicitHeight
baselineOffset: row.y + label.y + label.baselineOffset
RowLayout {
id: row
width: parent.width
anchors.verticalCenter: parent.verticalCenter
spacing: Kirigami.Units.smallSpacing
layoutDirection: root.mirrored ? Qt.RightToLeft : Qt.LeftToRight
Item {
Layout.preferredWidth: (root.ListView.view && root.ListView.view.hasCheckables) || root.checkable
? root.indicator.width : Kirigami.Units.smallSpacing
}
// Reserve the icon column even for rows without an icon.
Item {
Layout.preferredWidth: Kirigami.Units.iconSizes.small
Layout.preferredHeight: Layout.preferredWidth
Layout.alignment: Qt.AlignVCenter
Kirigami.Icon {
anchors.fill: parent
visible: root.icon.name !== "" || root.icon.source.toString() !== ""
source: root.icon.name !== "" ? root.icon.name : root.icon.source
color: root.icon.color
selected: root.pressed
}
}
Label {
id: label
Layout.fillWidth: true
Layout.alignment: Qt.AlignBaseline
text: root.Kirigami.MnemonicData.richTextLabel
// StyledText keeps mnemonic underlines without RichText's
// different line metrics relative to the shortcut label.
textFormat: Text.StyledText
font: root.font
color: root.pressed ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor
elide: Text.ElideRight
horizontalAlignment: root.mirrored ? Text.AlignRight : Text.AlignLeft
}
Label {
id: shortcut
Layout.alignment: Qt.AlignBaseline
visible: !root.subMenu && root.action && root.action.shortcut !== undefined
text: visible ? itemShortcut.nativeText : ""
textFormat: Text.PlainText
font: root.font
color: label.color
horizontalAlignment: Text.AlignRight
Shortcut {
id: itemShortcut
sequence: shortcut.visible && root.action ? root.action.shortcut : ""
}
}
// The inherited arrow sits over this slot. Without a submenu,
// shortcut text reaches the very same trailing edge.
Item {
visible: root.subMenu !== null
Layout.preferredWidth: root.arrow ? root.arrow.width : 0
}
}
}
}
+6 -6
View File
@@ -6,7 +6,7 @@ import QtQuick
import QtQuick.Controls
import org.kde.ki18n
Menu {
AppMenu {
id: root
required property Actions actions
@@ -19,9 +19,9 @@ Menu {
title: KI18n.i18nc("@title:menu", "&Track")
}
MenuSeparator {}
MenuItem { action: root.actions.mute }
MenuItem { action: root.actions.volumeUp }
MenuItem { action: root.actions.volumeDown }
MenuItem { action: root.actions.audioCycleUp }
MenuItem { action: root.actions.audioCycleDown }
AppMenuItem { action: root.actions.mute }
AppMenuItem { action: root.actions.volumeUp }
AppMenuItem { action: root.actions.volumeDown }
AppMenuItem { action: root.actions.audioCycleUp }
AppMenuItem { action: root.actions.audioCycleDown }
}
+2 -2
View File
@@ -9,7 +9,7 @@ import QtQuick.Controls
import org.kde.ki18n
// Checkable list of audio tracks.
Menu {
AppMenu {
id: root
required property MpvItem mpv
@@ -25,7 +25,7 @@ Menu {
Instantiator {
model: root.mpv.audioTracks
delegate: MenuItem {
delegate: AppMenuItem {
required property var modelData
text: root.trackLabel(modelData)
checkable: true
+4 -4
View File
@@ -6,16 +6,16 @@ import QtQuick
import QtQuick.Controls
import org.kde.ki18n
Menu {
AppMenu {
id: root
required property Actions actions
title: KI18n.i18nc("@title:menu", "&File")
MenuItem { action: root.actions.openFile }
MenuItem { action: root.actions.openUrl }
AppMenuItem { action: root.actions.openFile }
AppMenuItem { action: root.actions.openUrl }
RecentFilesMenu { actions: root.actions }
MenuSeparator {}
MenuItem { action: root.actions.quit }
AppMenuItem { action: root.actions.quit }
}
+287
View File
@@ -0,0 +1,287 @@
// SPDX-FileCopyrightText: 2026 Tri Vo Khac
// SPDX-License-Identifier: GPL-3.0-or-later
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import org.kde.ki18n
import org.kde.kirigami as Kirigami
import org.kde.kirigami.dialogs as KDialogs
Kirigami.Dialog {
id: root
required property var translator
readonly property real removeButtonWidth: Kirigami.Units.iconSizes.smallMedium + Kirigami.Units.smallSpacing * 2
// One inset for the header, content and footer so every edge lines up.
readonly property real inset: Kirigami.Units.largeSpacing
title: KI18n.i18nc("@title:window", "Translation Glossary")
standardButtons: Kirigami.Dialog.NoButton
width: Math.min(parent.width * 0.9, Kirigami.Units.gridUnit * 38)
height: Math.min(parent.height - Kirigami.Units.largeSpacing * 2, Kirigami.Units.gridUnit * 30)
leftPadding: inset
rightPadding: inset
topPadding: 0
bottomPadding: 0
header: KDialogs.DialogHeader {
dialog: root
leftPadding: root.inset
rightPadding: root.inset
topPadding: root.inset
contentItem: KDialogs.DialogHeaderTopContent {
dialog: root
}
}
function addTerm() {
glossaryModel.append({
source: "",
target: ""
})
glossaryList.currentIndex = glossaryModel.count - 1
Qt.callLater(() => {
glossaryList.forceLayout()
glossaryList.positionViewAtIndex(glossaryList.currentIndex, ListView.Contain)
glossaryList.forceLayout()
const row = glossaryList.itemAtIndex(glossaryList.currentIndex)
if (row) {
row.focusOriginal()
}
})
}
onOpened: {
glossaryModel.clear()
for (const entry of translator.glossaryEntries) {
glossaryModel.append(entry)
}
glossaryList.positionViewAtBeginning()
}
onAccepted: {
const entries = []
for (let i = 0; i < glossaryModel.count; ++i) {
const entry = glossaryModel.get(i)
entries.push({
source: entry.source,
target: entry.target
})
}
translator.saveGlossary(entries)
}
ListModel {
id: glossaryModel
}
// Union's DialogButtonBox adds its own padding on top of the dialog's, so
// lay the footer out ourselves with the same inset as the header and content.
footer: Control {
leftPadding: root.inset
rightPadding: root.inset
topPadding: Kirigami.Units.largeSpacing
bottomPadding: root.inset
contentItem: RowLayout {
spacing: Kirigami.Units.smallSpacing
Item {
Layout.fillWidth: true
}
Button {
text: KI18n.i18nc("@action:button", "Save")
icon.name: "document-save"
onClicked: root.accept()
}
Button {
text: KI18n.i18nc("@action:button", "Cancel")
icon.name: "dialog-cancel"
onClicked: root.reject()
}
}
}
Action {
id: addTermAction
text: KI18n.i18nc("@action:button", "Add Term")
icon.name: "list-add"
onTriggered: root.addTerm()
}
contentItem: ColumnLayout {
spacing: Kirigami.Units.largeSpacing
RowLayout {
Layout.fillWidth: true
spacing: Kirigami.Units.smallSpacing
Label {
Layout.fillWidth: true
text: KI18n.i18ncp("@label glossary term count", "%1 term", "%1 terms", glossaryModel.count)
color: Kirigami.Theme.disabledTextColor
}
Button {
action: addTermAction
}
Button {
text: KI18n.i18nc("@action:button", "Clear All")
icon.name: "edit-clear-all"
enabled: glossaryModel.count > 0
onClicked: glossaryModel.clear()
}
}
RowLayout {
visible: glossaryModel.count > 0
Layout.fillWidth: true
Layout.rightMargin: listScroll.rightPadding
spacing: Kirigami.Units.smallSpacing
Label {
Layout.fillWidth: true
Layout.preferredWidth: 1
Layout.minimumWidth: 0
text: KI18n.i18nc("@title:column glossary source term", "Original")
font: Kirigami.Theme.smallFont
color: Kirigami.Theme.disabledTextColor
}
Label {
Layout.fillWidth: true
Layout.preferredWidth: 1
Layout.minimumWidth: 0
text: KI18n.i18nc("@title:column glossary translated term", "Translation")
font: Kirigami.Theme.smallFont
color: Kirigami.Theme.disabledTextColor
}
Item {
Layout.preferredWidth: root.removeButtonWidth
}
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
ScrollView {
id: listScroll
anchors.fill: parent
clip: true
contentWidth: availableWidth
leftPadding: 0
topPadding: 0
bottomPadding: 0
// Room for the scrollbar plus a gap, so its right edge lines up
// with the buttons above and below.
rightPadding: ScrollBar.vertical.visible ? ScrollBar.vertical.width + Kirigami.Units.smallSpacing : 0
// The style's frame and focus ring would stretch into the margin.
background: null
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
// The style's scrollbar is wide and draws a separator line; a slim
// one keeps the right side tidy.
ScrollBar.vertical: ScrollBar {
parent: listScroll
policy: ScrollBar.AsNeeded
active: true
// Union sets each side explicitly, so `padding: 0` alone is not enough.
leftPadding: 0
rightPadding: 0
topPadding: 0
bottomPadding: 0
leftInset: 0
rightInset: 0
topInset: 0
bottomInset: 0
background: null
contentItem: Rectangle {
implicitWidth: Kirigami.Units.smallSpacing * 1.5
radius: width / 2
color: Kirigami.Theme.textColor
opacity: parent.pressed ? 0.6 : parent.hovered ? 0.45 : 0.25
}
width: implicitWidth
x: listScroll.width - width
y: 0
height: listScroll.height
}
contentItem: ListView {
id: glossaryList
clip: true
spacing: Kirigami.Units.smallSpacing
boundsBehavior: Flickable.StopAtBounds
model: glossaryModel
delegate: RowLayout {
id: termRow
required property int index
required property string source
required property string target
width: glossaryList.width
height: implicitHeight
spacing: Kirigami.Units.smallSpacing
function focusOriginal() {
originalField.forceActiveFocus(Qt.TabFocusReason)
}
TextField {
id: originalField
Layout.fillWidth: true
Layout.preferredWidth: 1
Layout.minimumWidth: 0
text: termRow.source
placeholderText: KI18n.i18nc("@info:placeholder glossary source term", "Original term")
Accessible.name: KI18n.i18nc("@label:textbox glossary source term", "Original term")
onTextEdited: glossaryModel.setProperty(termRow.index, "source", text)
}
TextField {
Layout.fillWidth: true
Layout.preferredWidth: 1
Layout.minimumWidth: 0
text: termRow.target
placeholderText: KI18n.i18nc("@info:placeholder glossary translated term", "Translation")
Accessible.name: KI18n.i18nc("@label:textbox glossary translated term", "Translation")
onTextEdited: glossaryModel.setProperty(termRow.index, "target", text)
}
ToolButton {
Layout.preferredWidth: root.removeButtonWidth
Layout.minimumWidth: root.removeButtonWidth
Layout.maximumWidth: root.removeButtonWidth
Layout.alignment: Qt.AlignVCenter
flat: true
icon.name: "edit-delete"
icon.color: Kirigami.Theme.textColor
display: AbstractButton.IconOnly
text: KI18n.i18nc("@action:button remove glossary term", "Remove")
ToolTip.text: text
ToolTip.visible: hovered
ToolTip.delay: Kirigami.Units.toolTipDelay
onClicked: glossaryModel.remove(termRow.index)
}
}
}
}
Kirigami.PlaceholderMessage {
anchors.centerIn: parent
width: parent.width - Kirigami.Units.largeSpacing * 2
visible: glossaryModel.count === 0
text: KI18n.i18nc("@info:placeholder", "No glossary terms yet")
explanation: KI18n.i18nc("@info:placeholder", "Terms are extracted automatically before translation, or you can add them manually.")
helpfulAction: addTermAction
}
}
}
}
+11 -11
View File
@@ -29,19 +29,19 @@ ToolButton {
ToolTip.visible: hovered && !menu.visible
ToolTip.delay: Kirigami.Units.toolTipDelay
Menu {
AppMenu {
id: menu
y: root.inFooter ? -height - Kirigami.Units.largeSpacing : root.height + Kirigami.Units.largeSpacing
modal: true
dim: false
MenuItem {
AppMenuItem {
action: root.actions.openFile
visible: root.inFooter
height: visible ? implicitHeight : 0
}
MenuItem {
AppMenuItem {
action: root.actions.openUrl
visible: root.inFooter
height: visible ? implicitHeight : 0
@@ -62,20 +62,20 @@ ToolButton {
title: KI18n.i18nc("@title:menu", "Audio Track")
}
MenuSeparator {}
MenuItem { action: root.actions.translateSubtitle }
MenuItem { action: root.actions.toggleFullscreen }
MenuItem { action: root.actions.togglePlaylist }
MenuItem { action: root.actions.screenshot }
AppMenuItem { action: root.actions.translateSubtitle }
AppMenuItem { action: root.actions.toggleFullscreen }
AppMenuItem { action: root.actions.togglePlaylist }
AppMenuItem { action: root.actions.screenshot }
MenuSeparator {}
MenuItem {
AppMenuItem {
action: root.actions.configure
visible: root.inFooter
height: visible ? implicitHeight : 0
}
MenuItem { action: root.actions.toggleMenuBar }
MenuItem { action: root.actions.about }
AppMenuItem { action: root.actions.toggleMenuBar }
AppMenuItem { action: root.actions.about }
MenuSeparator {}
Menu {
AppMenu {
title: KI18n.i18nc("@title:menu", "&More")
FileMenu { actions: root.actions }
ViewMenu { actions: root.actions }
+2 -2
View File
@@ -79,8 +79,8 @@ ToolBar {
enabled: true
MenuSeparator {}
MenuItem { action: root.actions.translateSubtitle }
MenuItem { action: root.actions.addSubtitle }
AppMenuItem { action: root.actions.translateSubtitle }
AppMenuItem { action: root.actions.addSubtitle }
}
}
+3 -3
View File
@@ -6,13 +6,13 @@ import QtQuick
import QtQuick.Controls
import org.kde.ki18n
Menu {
AppMenu {
id: root
required property Actions actions
title: KI18n.i18nc("@title:menu", "&Help")
MenuItem { action: root.actions.about }
MenuItem { action: root.actions.reportBug }
AppMenuItem { action: root.actions.about }
AppMenuItem { action: root.actions.reportBug }
}
+2 -33
View File
@@ -318,39 +318,8 @@ ApplicationWindow {
onAccepted: video.addSubtitleFile(selectedFile)
}
Kirigami.Dialog {
GlossaryDialog {
id: glossaryDialog
title: KI18n.i18nc("@title:window", "Translation Glossary")
standardButtons: Kirigami.Dialog.Save | Kirigami.Dialog.Cancel
width: Math.min(appWindow.width * 0.9, 650)
contentItem: ColumnLayout {
ListView {
id: glossaryList
Layout.fillWidth: true
Layout.fillHeight: true
Layout.preferredHeight: Kirigami.Units.gridUnit * 15
clip: true
model: ListModel { id: glossaryModel }
delegate: RowLayout {
width: glossaryList.width
TextField { text: source; Layout.fillWidth: true; onTextChanged: model.source = text }
TextField { text: target; Layout.fillWidth: true; onTextChanged: model.target = text }
ToolButton { icon.name: "edit-delete-remove"; onClicked: glossaryModel.remove(index) }
}
}
RowLayout {
Button { text: KI18n.i18nc("@action:button", "Add"); onClicked: glossaryModel.append({source: "", target: ""}) }
Button { text: KI18n.i18nc("@action:button", "Clear"); onClicked: glossaryModel.clear() }
}
}
onOpened: {
glossaryModel.clear()
for (const entry of translationService.glossaryEntries) glossaryModel.append(entry)
}
onAccepted: {
const entries = []
for (let i = 0; i < glossaryModel.count; ++i) entries.push(glossaryModel.get(i))
translationService.saveGlossary(entries)
}
translator: translationService
}
}
+16 -16
View File
@@ -7,24 +7,24 @@ import QtQuick.Controls
import org.kde.ki18n
// Right click menu of the video.
Menu {
AppMenu {
id: root
required property Actions actions
required property MpvItem mpv
MenuItem { action: root.actions.playPause }
MenuItem { action: root.actions.playNextFile }
MenuItem { action: root.actions.playPreviousFile }
Menu {
AppMenuItem { action: root.actions.playPause }
AppMenuItem { action: root.actions.playNextFile }
AppMenuItem { action: root.actions.playPreviousFile }
AppMenu {
title: KI18n.i18nc("@title:menu", "Playback Speed")
MenuItem { action: root.actions.speedUp }
MenuItem { action: root.actions.speedDown }
MenuItem { action: root.actions.speedReset }
AppMenuItem { action: root.actions.speedUp }
AppMenuItem { action: root.actions.speedDown }
AppMenuItem { action: root.actions.speedReset }
}
MenuSeparator {}
MenuItem { action: root.actions.openFile }
MenuItem { action: root.actions.openUrl }
AppMenuItem { action: root.actions.openFile }
AppMenuItem { action: root.actions.openUrl }
MenuSeparator {}
SubtitleTracksMenu {
mpv: root.mpv
@@ -40,7 +40,7 @@ Menu {
mpv: root.mpv
title: KI18n.i18nc("@title:menu", "Audio Track")
}
MenuItem { action: root.actions.translateSubtitle }
AppMenuItem { action: root.actions.translateSubtitle }
MenuSeparator {}
VideoMenu { actions: root.actions }
SubtitlesMenu {
@@ -52,10 +52,10 @@ Menu {
mpv: root.mpv
}
MenuSeparator {}
MenuItem { action: root.actions.toggleFullscreen }
MenuItem { action: root.actions.togglePlaylist }
MenuItem { action: root.actions.toggleMenuBar }
MenuItem { action: root.actions.toggleHeader }
AppMenuItem { action: root.actions.toggleFullscreen }
AppMenuItem { action: root.actions.togglePlaylist }
AppMenuItem { action: root.actions.toggleMenuBar }
AppMenuItem { action: root.actions.toggleHeader }
MenuSeparator {}
MenuItem { action: root.actions.configure }
AppMenuItem { action: root.actions.configure }
}
+22 -22
View File
@@ -6,41 +6,41 @@ import QtQuick
import QtQuick.Controls
import org.kde.ki18n
Menu {
AppMenu {
id: root
required property Actions actions
title: KI18n.i18nc("@title:menu", "&Playback")
MenuItem { action: root.actions.playPause }
MenuItem { action: root.actions.stop }
MenuItem { action: root.actions.playNextFile }
MenuItem { action: root.actions.playPreviousFile }
MenuItem { action: root.actions.restart }
AppMenuItem { action: root.actions.playPause }
AppMenuItem { action: root.actions.stop }
AppMenuItem { action: root.actions.playNextFile }
AppMenuItem { action: root.actions.playPreviousFile }
AppMenuItem { action: root.actions.restart }
MenuSeparator {}
MenuItem { action: root.actions.speedUp }
MenuItem { action: root.actions.speedDown }
MenuItem { action: root.actions.speedReset }
AppMenuItem { action: root.actions.speedUp }
AppMenuItem { action: root.actions.speedDown }
AppMenuItem { action: root.actions.speedReset }
MenuSeparator {}
Menu {
AppMenu {
title: KI18n.i18nc("@title:menu", "Seek")
MenuItem { action: root.actions.seekForwardSmall }
MenuItem { action: root.actions.seekBackwardSmall }
AppMenuItem { action: root.actions.seekForwardSmall }
AppMenuItem { action: root.actions.seekBackwardSmall }
MenuSeparator {}
MenuItem { action: root.actions.seekForwardMedium }
MenuItem { action: root.actions.seekBackwardMedium }
AppMenuItem { action: root.actions.seekForwardMedium }
AppMenuItem { action: root.actions.seekBackwardMedium }
MenuSeparator {}
MenuItem { action: root.actions.seekForwardBig }
MenuItem { action: root.actions.seekBackwardBig }
AppMenuItem { action: root.actions.seekForwardBig }
AppMenuItem { action: root.actions.seekBackwardBig }
MenuSeparator {}
MenuItem { action: root.actions.seekNextSubtitle }
MenuItem { action: root.actions.seekPreviousSubtitle }
AppMenuItem { action: root.actions.seekNextSubtitle }
AppMenuItem { action: root.actions.seekPreviousSubtitle }
MenuSeparator {}
MenuItem { action: root.actions.seekNextChapter }
MenuItem { action: root.actions.seekPreviousChapter }
AppMenuItem { action: root.actions.seekNextChapter }
AppMenuItem { action: root.actions.seekPreviousChapter }
MenuSeparator {}
MenuItem { action: root.actions.frameStepForward }
MenuItem { action: root.actions.frameStepBackward }
AppMenuItem { action: root.actions.frameStepForward }
AppMenuItem { action: root.actions.frameStepBackward }
}
}
+6 -6
View File
@@ -113,15 +113,15 @@ Item {
}
}
Menu {
AppMenu {
id: contextMenu
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@action:inmenu", "Play")
icon.name: "media-playback-start"
onTriggered: root.playlist.play(root.index)
}
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@action:inmenu", "Open Containing Folder")
icon.name: "folder-open"
enabled: root.url.toString().startsWith("file://")
@@ -131,19 +131,19 @@ Item {
}
}
MenuSeparator {}
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@action:inmenu", "Move Up")
icon.name: "go-up"
enabled: root.index > 0
onTriggered: root.playlist.move(root.index, root.index - 1)
}
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@action:inmenu", "Move Down")
icon.name: "go-down"
enabled: root.index < root.playlist.count - 1
onTriggered: root.playlist.move(root.index, root.index + 1)
}
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@action:inmenu", "Remove from Playlist")
icon.name: "list-remove"
onTriggered: root.playlist.remove(root.index)
+3 -3
View File
@@ -8,7 +8,7 @@ import QtQuick
import QtQuick.Controls
import org.kde.ki18n
Menu {
AppMenu {
id: root
required property Actions actions
@@ -18,7 +18,7 @@ Menu {
Instantiator {
model: RecentFilesModel
delegate: MenuItem {
delegate: AppMenuItem {
required property url url
required property string name
required property string path
@@ -35,7 +35,7 @@ Menu {
MenuSeparator {}
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@action:inmenu", "Clear List")
icon.name: "edit-clear-history"
onTriggered: RecentFilesModel.clear()
+7 -7
View File
@@ -6,34 +6,34 @@ import QtQuick
import QtQuick.Controls
import org.kde.ki18n
Menu {
AppMenu {
id: root
required property Actions actions
title: KI18n.i18nc("@title:menu", "&Settings")
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@action:inmenu", "General")
onTriggered: root.actions.settingsRequested("general")
}
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@action:inmenu", "Playback")
onTriggered: root.actions.settingsRequested("playback")
}
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@action:inmenu", "Subtitles")
onTriggered: root.actions.settingsRequested("subtitles")
}
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@action:inmenu", "Translation")
onTriggered: root.actions.settingsRequested("translation")
}
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@action:inmenu", "Playlist")
onTriggered: root.actions.settingsRequested("playlist")
}
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@action:inmenu", "About")
onTriggered: root.actions.settingsRequested("about")
}
+3 -3
View File
@@ -9,7 +9,7 @@ import QtQuick.Controls
import org.kde.ki18n
// Checkable list of subtitle tracks, for the primary or the secondary subtitle.
Menu {
AppMenu {
id: root
required property MpvItem mpv
@@ -36,7 +36,7 @@ Menu {
enabled: mpv.subtitleTracks.length > 0
MenuItem {
AppMenuItem {
text: KI18n.i18nc("@item:inmenu no subtitle", "None")
checkable: true
checked: root.selectedId === 0
@@ -49,7 +49,7 @@ Menu {
Instantiator {
model: root.mpv.subtitleTracks
delegate: MenuItem {
delegate: AppMenuItem {
required property var modelData
text: root.trackLabel(modelData)
checkable: true
+13 -13
View File
@@ -6,7 +6,7 @@ import QtQuick
import QtQuick.Controls
import org.kde.ki18n
Menu {
AppMenu {
id: root
required property Actions actions
@@ -25,21 +25,21 @@ Menu {
title: KI18n.i18nc("@title:menu", "Secondary Subtitle")
}
MenuSeparator {}
MenuItem { action: root.actions.translateSubtitle }
MenuItem { action: root.actions.editGlossary }
MenuItem {
AppMenuItem { action: root.actions.translateSubtitle }
AppMenuItem { action: root.actions.editGlossary }
AppMenuItem {
action: root.actions.cancelTranslation
visible: root.actions.cancelTranslation.enabled
height: visible ? implicitHeight : 0
}
MenuSeparator {}
MenuItem { action: root.actions.addSubtitle }
MenuItem { action: root.actions.subtitleBigger }
MenuItem { action: root.actions.subtitleSmaller }
MenuItem { action: root.actions.subtitleEarlier }
MenuItem { action: root.actions.subtitleLater }
MenuItem { action: root.actions.subtitleDelayReset }
MenuItem { action: root.actions.subtitleToggle }
MenuItem { action: root.actions.subtitleCycleUp }
MenuItem { action: root.actions.subtitleCycleDown }
AppMenuItem { action: root.actions.addSubtitle }
AppMenuItem { action: root.actions.subtitleBigger }
AppMenuItem { action: root.actions.subtitleSmaller }
AppMenuItem { action: root.actions.subtitleEarlier }
AppMenuItem { action: root.actions.subtitleLater }
AppMenuItem { action: root.actions.subtitleDelayReset }
AppMenuItem { action: root.actions.subtitleToggle }
AppMenuItem { action: root.actions.subtitleCycleUp }
AppMenuItem { action: root.actions.subtitleCycleDown }
}
+21 -21
View File
@@ -147,36 +147,35 @@ SettingsBasePage {
Label {
text: KI18n.i18nc("@label:listbox", "Preset")
Layout.alignment: Qt.AlignRight | Qt.AlignTop
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ColumnLayout {
ComboBox {
id: presetCombo
Layout.fillWidth: true
ComboBox {
id: presetCombo
Layout.fillWidth: true
model: root.translator.translationPresets
textRole: "name"
valueRole: "id"
Component.onCompleted: currentIndex = Math.max(0, indexOfValue(QtPotatoSettings.translationPreset))
onActivated: {
QtPotatoSettings.translationPreset = currentValue
QtPotatoSettings.save()
}
model: root.translator.translationPresets
textRole: "name"
valueRole: "id"
Component.onCompleted: currentIndex = Math.max(0, indexOfValue(QtPotatoSettings.translationPreset))
onActivated: {
QtPotatoSettings.translationPreset = currentValue
QtPotatoSettings.save()
}
}
Label {
text: presetCombo.currentIndex >= 0 ? presetCombo.model[presetCombo.currentIndex].guidance : ""
wrapMode: Text.WordWrap
opacity: 0.7
Layout.fillWidth: true
}
Item { Layout.preferredWidth: 1 }
Label {
text: presetCombo.currentIndex >= 0 ? presetCombo.model[presetCombo.currentIndex].description : ""
wrapMode: Text.WordWrap
opacity: 0.7
font: Kirigami.Theme.smallFont
Layout.fillWidth: true
}
Label {
text: KI18n.i18nc("@label:textbox", "Additional instructions")
Layout.alignment: Qt.AlignRight | Qt.AlignTop
Layout.alignment: Qt.AlignRight | Qt.AlignBaseline
}
TextArea {
@@ -184,6 +183,7 @@ SettingsBasePage {
placeholderText: KI18n.i18nc("@info:placeholder", "e.g. Translate 'Young Master' as 'Thiếu gia'. Use 'ta/ngươi' between enemies.")
wrapMode: TextArea.Wrap
Layout.fillWidth: true
Layout.alignment: Qt.AlignBaseline
Layout.preferredHeight: Kirigami.Units.gridUnit * 4
// TextArea has no textEdited before Qt 6.9.
onTextChanged: QtPotatoSettings.customInstructions = text
+8 -8
View File
@@ -6,18 +6,18 @@ import QtQuick
import QtQuick.Controls
import org.kde.ki18n
Menu {
AppMenu {
id: root
required property Actions actions
title: KI18n.i18nc("@title:menu", "&Video")
MenuItem { action: root.actions.toggleDeinterlacing }
MenuItem { action: root.actions.zoomIn }
MenuItem { action: root.actions.zoomOut }
MenuItem { action: root.actions.zoomReset }
MenuItem { action: root.actions.screenshot }
MenuItem { action: root.actions.rotateClockwise }
MenuItem { action: root.actions.rotateCounterClockwise }
AppMenuItem { action: root.actions.toggleDeinterlacing }
AppMenuItem { action: root.actions.zoomIn }
AppMenuItem { action: root.actions.zoomOut }
AppMenuItem { action: root.actions.zoomReset }
AppMenuItem { action: root.actions.screenshot }
AppMenuItem { action: root.actions.rotateClockwise }
AppMenuItem { action: root.actions.rotateCounterClockwise }
}
+5 -5
View File
@@ -6,16 +6,16 @@ import QtQuick
import QtQuick.Controls
import org.kde.ki18n
Menu {
AppMenu {
id: root
required property Actions actions
title: KI18n.i18nc("@title:menu", "&View")
MenuItem { action: root.actions.toggleFullscreen }
MenuItem { action: root.actions.togglePlaylist }
AppMenuItem { action: root.actions.toggleFullscreen }
AppMenuItem { action: root.actions.togglePlaylist }
MenuSeparator {}
MenuItem { action: root.actions.toggleMenuBar }
MenuItem { action: root.actions.toggleHeader }
AppMenuItem { action: root.actions.toggleMenuBar }
AppMenuItem { action: root.actions.toggleHeader }
}