mirror of
https://invent.kde.org/marcoa/a-la-karte.git
synced 2026-02-09 21:13:08 +00:00
qml: confirm destructive actions
This commit is contained in:
parent
b961a8cc8f
commit
e754d88eb0
2 changed files with 253 additions and 24 deletions
|
|
@ -19,6 +19,7 @@ Kirigami.ApplicationWindow {
|
|||
height: Kirigami.Units.gridUnit * 40
|
||||
|
||||
property var selectedGame: null
|
||||
property var pendingRemoveGame: null
|
||||
property string currentSource: "all"
|
||||
property bool searchActive: false
|
||||
property bool settingsLayerOpen: false
|
||||
|
|
@ -498,19 +499,9 @@ Kirigami.ApplicationWindow {
|
|||
}
|
||||
|
||||
onRemoveRequested: {
|
||||
if (root.selectedGame) {
|
||||
let gameId = root.selectedGame.id
|
||||
let gameName = root.selectedGame.name
|
||||
App.removeGame(root.selectedGame)
|
||||
detailsSheet.close()
|
||||
root.selectedGame = null
|
||||
showPassiveNotification(
|
||||
i18n("%1 removed", gameName),
|
||||
"long",
|
||||
i18n("Undo"),
|
||||
function() { App.restoreGame(gameId) }
|
||||
)
|
||||
}
|
||||
if (!root.selectedGame) return
|
||||
root.pendingRemoveGame = root.selectedGame
|
||||
removeGameConfirmDialog.open()
|
||||
}
|
||||
|
||||
onClosed: {
|
||||
|
|
@ -518,6 +509,33 @@ Kirigami.ApplicationWindow {
|
|||
}
|
||||
}
|
||||
|
||||
Kirigami.PromptDialog {
|
||||
id: removeGameConfirmDialog
|
||||
title: i18n("Remove Game")
|
||||
subtitle: root.pendingRemoveGame
|
||||
? i18n("Are you sure you want to remove '%1'?", root.pendingRemoveGame.name)
|
||||
: i18n("Are you sure you want to remove this game?")
|
||||
standardButtons: Kirigami.Dialog.Yes | Kirigami.Dialog.No
|
||||
onAccepted: {
|
||||
if (!root.pendingRemoveGame) return
|
||||
let gameId = root.pendingRemoveGame.id
|
||||
let gameName = root.pendingRemoveGame.name
|
||||
App.removeGame(root.pendingRemoveGame)
|
||||
root.pendingRemoveGame = null
|
||||
detailsSheet.close()
|
||||
root.selectedGame = null
|
||||
showPassiveNotification(
|
||||
i18n("%1 removed", gameName),
|
||||
"long",
|
||||
i18n("Undo"),
|
||||
function() { App.restoreGame(gameId) }
|
||||
)
|
||||
}
|
||||
onRejected: {
|
||||
root.pendingRemoveGame = null
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: importSheet
|
||||
title: i18n("Import Games")
|
||||
|
|
|
|||
|
|
@ -17,6 +17,17 @@ ColumnLayout {
|
|||
showPlatformBadgesDelegate.forceActiveFocus()
|
||||
}
|
||||
|
||||
property var pendingDisableImportApply: null
|
||||
property var pendingDisableImportDelegate: null
|
||||
property string pendingDisableImportName: ""
|
||||
|
||||
function requestDisableImport(delegate, sourceName, applyFn) {
|
||||
pendingDisableImportDelegate = delegate
|
||||
pendingDisableImportName = sourceName
|
||||
pendingDisableImportApply = applyFn
|
||||
disableImportConfirmDialog.open()
|
||||
}
|
||||
|
||||
FormCard.FormHeader {
|
||||
Layout.fillWidth: true
|
||||
title: i18n("Appearance")
|
||||
|
|
@ -88,8 +99,26 @@ FormCard.FormHeader {
|
|||
secondary: "steam"
|
||||
resourceFallback: Qt.resolvedUrl("icons/brand/steam-symbolic.svg")
|
||||
}
|
||||
property bool restoring: false
|
||||
checked: App.config.importSteam
|
||||
onToggled: App.config.importSteam = checked
|
||||
onToggled: {
|
||||
if (restoring) return
|
||||
|
||||
if (checked === App.config.importSteam) return
|
||||
|
||||
if (!checked && App.gameModel.hasPlatformPrefix("Steam")) {
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importSteam })
|
||||
restoring = false
|
||||
settingsPage.requestDisableImport(this, i18n("Steam"), function() { App.config.importSteam = false })
|
||||
return
|
||||
}
|
||||
|
||||
App.config.importSteam = checked
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importSteam })
|
||||
restoring = false
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
|
@ -101,8 +130,26 @@ FormCard.FormHeader {
|
|||
primary: "lutris"
|
||||
secondary: "applications-games"
|
||||
}
|
||||
property bool restoring: false
|
||||
checked: App.config.importLutris
|
||||
onToggled: App.config.importLutris = checked
|
||||
onToggled: {
|
||||
if (restoring) return
|
||||
|
||||
if (checked === App.config.importLutris) return
|
||||
|
||||
if (!checked && App.gameModel.hasPlatformPrefix("Lutris")) {
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importLutris })
|
||||
restoring = false
|
||||
settingsPage.requestDisableImport(this, i18n("Lutris"), function() { App.config.importLutris = false })
|
||||
return
|
||||
}
|
||||
|
||||
App.config.importLutris = checked
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importLutris })
|
||||
restoring = false
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
|
@ -115,8 +162,26 @@ FormCard.FormHeader {
|
|||
primary: "com.heroicgameslauncher.hgl"
|
||||
secondary: "applications-games"
|
||||
}
|
||||
property bool restoring: false
|
||||
checked: App.config.importHeroic
|
||||
onToggled: App.config.importHeroic = checked
|
||||
onToggled: {
|
||||
if (restoring) return
|
||||
|
||||
if (checked === App.config.importHeroic) return
|
||||
|
||||
if (!checked && App.gameModel.hasPlatformPrefix("Heroic")) {
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importHeroic })
|
||||
restoring = false
|
||||
settingsPage.requestDisableImport(this, i18n("Heroic Games Launcher"), function() { App.config.importHeroic = false })
|
||||
return
|
||||
}
|
||||
|
||||
App.config.importHeroic = checked
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importHeroic })
|
||||
restoring = false
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
|
@ -129,8 +194,26 @@ FormCard.FormHeader {
|
|||
primary: "user-desktop"
|
||||
secondary: "computer"
|
||||
}
|
||||
property bool restoring: false
|
||||
checked: App.config.importDesktop
|
||||
onToggled: App.config.importDesktop = checked
|
||||
onToggled: {
|
||||
if (restoring) return
|
||||
|
||||
if (checked === App.config.importDesktop) return
|
||||
|
||||
if (!checked && App.gameModel.hasPlatformPrefix("Desktop")) {
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importDesktop })
|
||||
restoring = false
|
||||
settingsPage.requestDisableImport(this, i18n("Desktop Entries"), function() { App.config.importDesktop = false })
|
||||
return
|
||||
}
|
||||
|
||||
App.config.importDesktop = checked
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importDesktop })
|
||||
restoring = false
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
|
@ -143,8 +226,26 @@ FormCard.FormHeader {
|
|||
primary: "com.usebottles.bottles"
|
||||
secondary: "application-x-executable"
|
||||
}
|
||||
property bool restoring: false
|
||||
checked: App.config.importBottles
|
||||
onToggled: App.config.importBottles = checked
|
||||
onToggled: {
|
||||
if (restoring) return
|
||||
|
||||
if (checked === App.config.importBottles) return
|
||||
|
||||
if (!checked && App.gameModel.hasPlatformPrefix("Bottles")) {
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importBottles })
|
||||
restoring = false
|
||||
settingsPage.requestDisableImport(this, i18n("Bottles"), function() { App.config.importBottles = false })
|
||||
return
|
||||
}
|
||||
|
||||
App.config.importBottles = checked
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importBottles })
|
||||
restoring = false
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
|
@ -157,8 +258,26 @@ FormCard.FormHeader {
|
|||
primary: "flatpak-discover"
|
||||
secondary: "applications-games"
|
||||
}
|
||||
property bool restoring: false
|
||||
checked: App.config.importFlatpak
|
||||
onToggled: App.config.importFlatpak = checked
|
||||
onToggled: {
|
||||
if (restoring) return
|
||||
|
||||
if (checked === App.config.importFlatpak) return
|
||||
|
||||
if (!checked && App.gameModel.hasPlatformPrefix("Flatpak")) {
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importFlatpak })
|
||||
restoring = false
|
||||
settingsPage.requestDisableImport(this, i18n("Flatpak"), function() { App.config.importFlatpak = false })
|
||||
return
|
||||
}
|
||||
|
||||
App.config.importFlatpak = checked
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importFlatpak })
|
||||
restoring = false
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
|
@ -172,8 +291,26 @@ FormCard.FormHeader {
|
|||
secondary: "itch"
|
||||
resourceFallback: Qt.resolvedUrl("icons/brand/itchdotio-symbolic.svg")
|
||||
}
|
||||
property bool restoring: false
|
||||
checked: App.config.importItch
|
||||
onToggled: App.config.importItch = checked
|
||||
onToggled: {
|
||||
if (restoring) return
|
||||
|
||||
if (checked === App.config.importItch) return
|
||||
|
||||
if (!checked && App.gameModel.hasPlatformPrefix("itch.io")) {
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importItch })
|
||||
restoring = false
|
||||
settingsPage.requestDisableImport(this, i18n("itch.io"), function() { App.config.importItch = false })
|
||||
return
|
||||
}
|
||||
|
||||
App.config.importItch = checked
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importItch })
|
||||
restoring = false
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
|
@ -186,8 +323,26 @@ FormCard.FormHeader {
|
|||
primary: "legendary"
|
||||
secondary: "applications-games"
|
||||
}
|
||||
property bool restoring: false
|
||||
checked: App.config.importLegendary
|
||||
onToggled: App.config.importLegendary = checked
|
||||
onToggled: {
|
||||
if (restoring) return
|
||||
|
||||
if (checked === App.config.importLegendary) return
|
||||
|
||||
if (!checked && App.gameModel.hasPlatformPrefix("Legendary")) {
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importLegendary })
|
||||
restoring = false
|
||||
settingsPage.requestDisableImport(this, i18n("Legendary"), function() { App.config.importLegendary = false })
|
||||
return
|
||||
}
|
||||
|
||||
App.config.importLegendary = checked
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importLegendary })
|
||||
restoring = false
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
|
@ -201,8 +356,26 @@ FormCard.FormHeader {
|
|||
secondary: "retroarch"
|
||||
resourceFallback: Qt.resolvedUrl("icons/brand/retroarch-symbolic.svg")
|
||||
}
|
||||
property bool restoring: false
|
||||
checked: App.config.importRetroArch
|
||||
onToggled: App.config.importRetroArch = checked
|
||||
onToggled: {
|
||||
if (restoring) return
|
||||
|
||||
if (checked === App.config.importRetroArch) return
|
||||
|
||||
if (!checked && App.gameModel.hasPlatformPrefix("RetroArch")) {
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importRetroArch })
|
||||
restoring = false
|
||||
settingsPage.requestDisableImport(this, i18n("RetroArch"), function() { App.config.importRetroArch = false })
|
||||
return
|
||||
}
|
||||
|
||||
App.config.importRetroArch = checked
|
||||
restoring = true
|
||||
checked = Qt.binding(function() { return App.config.importRetroArch })
|
||||
restoring = false
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
|
@ -309,7 +482,7 @@ FormCard.FormHeader {
|
|||
description: App.steamGridDB.busy ? i18n("Fetching...") : i18n("Download covers for all games")
|
||||
icon.name: "download"
|
||||
enabled: App.steamGridDB.enabled && App.steamGridDB.apiKey.length > 0 && !App.steamGridDB.busy
|
||||
onClicked: App.steamGridDB.fetchAllCovers()
|
||||
onClicked: fetchAllCoversConfirmDialog.open()
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
|
@ -355,7 +528,7 @@ FormCard.FormHeader {
|
|||
text: i18n("Remove Missing Games")
|
||||
description: i18n("Remove games whose executables no longer exist")
|
||||
icon.name: "edit-delete"
|
||||
onClicked: App.removeMissingGames()
|
||||
onClicked: removeMissingConfirmDialog.open()
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
|
@ -377,6 +550,44 @@ FormCard.FormHeader {
|
|||
}
|
||||
}
|
||||
|
||||
Kirigami.PromptDialog {
|
||||
id: disableImportConfirmDialog
|
||||
title: i18n("Disable Import Source")
|
||||
subtitle: i18n("Disabling %1 will remove all games imported from that source. Are you sure?", settingsPage.pendingDisableImportName)
|
||||
standardButtons: Kirigami.Dialog.Yes | Kirigami.Dialog.No
|
||||
onAccepted: {
|
||||
if (settingsPage.pendingDisableImportApply) {
|
||||
settingsPage.pendingDisableImportApply()
|
||||
}
|
||||
settingsPage.pendingDisableImportApply = null
|
||||
settingsPage.pendingDisableImportDelegate = null
|
||||
settingsPage.pendingDisableImportName = ""
|
||||
}
|
||||
onRejected: {
|
||||
settingsPage.pendingDisableImportApply = null
|
||||
settingsPage.pendingDisableImportDelegate = null
|
||||
settingsPage.pendingDisableImportName = ""
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.PromptDialog {
|
||||
id: fetchAllCoversConfirmDialog
|
||||
title: i18n("Fetch All Covers")
|
||||
subtitle: App.steamGridDB.preferSteamGridDB
|
||||
? i18n("This will download cover art for all games and may replace existing covers. Continue?")
|
||||
: i18n("This will download cover art for games that are missing covers. Continue?")
|
||||
standardButtons: Kirigami.Dialog.Yes | Kirigami.Dialog.No
|
||||
onAccepted: App.steamGridDB.fetchAllCovers()
|
||||
}
|
||||
|
||||
Kirigami.PromptDialog {
|
||||
id: removeMissingConfirmDialog
|
||||
title: i18n("Remove Missing Games")
|
||||
subtitle: i18n("This will remove games whose executables cannot be found. This cannot be undone. Continue?")
|
||||
standardButtons: Kirigami.Dialog.Yes | Kirigami.Dialog.No
|
||||
onAccepted: App.removeMissingGames()
|
||||
}
|
||||
|
||||
Kirigami.PromptDialog {
|
||||
id: clearConfirmDialog
|
||||
title: i18n("Clear Library")
|
||||
|
|
|
|||
Loading…
Reference in a new issue