Warning, /network/tokodon/src/content/ui/Main.qml is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
0002 // SPDX-FileCopyrightText: 2020 Han Young <hanyoung@protonmail.com>
0003 // SPDX-FileCopyrightText: 2020 Devin Lin <espidev@gmail.com>
0004 // SPDX-License-Identifier: GPL-3.0-only
0005 
0006 import QtQuick
0007 import org.kde.kirigami 2 as Kirigami
0008 import QtQuick.Controls 2 as QQC2
0009 import QtQuick.Layouts
0010 import QtQml.Models
0011 import org.kde.tokodon
0012 import org.kde.kirigamiaddons.delegates 1 as Delegates
0013 
0014 import "./StatusComposer"
0015 import "./StatusDelegate"
0016 
0017 Kirigami.ApplicationWindow {
0018     id: appwindow
0019 
0020     property bool isShowingFullScreenImage: false
0021 
0022     // A new post was created by us. Currently used by ThreadPages to update themselves when we reply.
0023     signal newPost()
0024 
0025     minimumWidth: Kirigami.Units.gridUnit * 21
0026     minimumHeight: Kirigami.Units.gridUnit * 20
0027 
0028     pageStack {
0029         defaultColumnWidth: appwindow.width
0030 
0031         globalToolBar {
0032             canContainHandles: true
0033             style: Kirigami.ApplicationHeaderStyle.ToolBar
0034             showNavigationButtons: if (applicationWindow().pageStack.currentIndex > 0
0035                 || applicationWindow().pageStack.currentIndex > 0) {
0036                 Kirigami.ApplicationHeaderStyle.ShowBackButton
0037             } else {
0038                 0
0039             }
0040         }
0041     }
0042 
0043     function decideDefaultPage() {
0044         globalDrawer.drawerOpen = true;
0045         pageStack.clear();
0046 
0047         if (InitialSetupFlow.isSetupNeeded()) {
0048             globalDrawer.drawerOpen = false;
0049             pageStack.push(Qt.createComponent("org.kde.tokodon", "SetupWelcome"));
0050             return;
0051         }
0052 
0053         if (AccountManager.selectedAccountHasIssue) {
0054             pageStack.push(Qt.createComponent("org.kde.tokodon", "LoginIssuePage"));
0055         } else {
0056             pageStack.push(mainTimeline, {
0057                 name: 'home',
0058             });
0059         }
0060     }
0061 
0062     function startupAccountCheck() {
0063         if (AccountManager.hasAccounts) {
0064             decideDefaultPage();
0065         } else {
0066             pageStack.push(Qt.createComponent("org.kde.tokodon", "WelcomePage"));
0067         }
0068     }
0069 
0070     function navigateLink(link, shouldOpenInternalLinks) {
0071         if (link.startsWith('hashtag:/') && shouldOpenInternalLinks) {
0072             pageStack.push(tagModelComponent, {
0073                 hashtag: link.substring(9),
0074             })
0075         } else if (link.startsWith('account:/') && shouldOpenInternalLinks) {
0076             Navigation.openAccount(link.substring(9))
0077         } else if (link.startsWith('web+ap:/') && shouldOpenInternalLinks) {
0078             Controller.openWebApLink(link.substring(8))
0079         } else {
0080             Qt.openUrlExternally(link)
0081         }
0082     }
0083 
0084     function requestCrossAction(action, url) {
0085         console.log("Requesting " + action + " of " + url);
0086         crossActionDialog.action = action;
0087         crossActionDialog.url = url;
0088         crossActionDialog.open();
0089     }
0090 
0091     ReportDialog {
0092         id: reportDialog
0093         visible: false
0094     }
0095 
0096     Kirigami.PromptDialog {
0097         id: crossActionDialog
0098 
0099         property string url
0100         property string action
0101 
0102         title: {
0103             if (action === 'open') {
0104                 return i18nc("@title", "Open As…")
0105             } else if (action === 'reply') {
0106                 return i18nc("@title", "Reply As…")
0107             } else if (action === 'favourite') {
0108                 return i18nc("@title", "Favorite As…")
0109             } else if (action === 'reblog') {
0110                 return i18nc("@title", "Boost As…")
0111             } else if (action === 'bookmark') {
0112                 return i18nc("@title", "Bookmark As…")
0113             } else {
0114                 return i18nc("@title", "Unknown Action")
0115             }
0116         }
0117 
0118         standardButtons: Kirigami.Dialog.NoButton
0119 
0120         mainItem: ColumnLayout {
0121             Repeater {
0122                 id: accounts
0123 
0124                 model: AccountManager
0125 
0126                 delegate: Delegates.RoundedItemDelegate {
0127                     required property int index
0128                     required property string displayName
0129                     required property string instance
0130                     required property var account
0131 
0132                     text: displayName
0133 
0134                     Layout.fillWidth: true
0135 
0136                     onClicked: crossActionDialog.takeAction(account)
0137                 }
0138             }
0139         }
0140 
0141         function takeAction(account): void {
0142             if (action === 'open' || action === 'reply') {
0143                 AccountManager.selectedAccount = account;
0144             }
0145 
0146             Qt.callLater(() => {
0147                 if (action === 'open') {
0148                     Controller.openWebApLink(url);
0149                 } else {
0150                     account.mutateRemotePost(url, action);
0151                 }
0152             });
0153 
0154             close();
0155         }
0156     }
0157 
0158     Component.onCompleted: {
0159         if (AccountManager.isReady) {
0160             startupAccountCheck();
0161         }
0162 
0163         saveWindowGeometryConnections.enabled = true;
0164         homeAction.checked = true;
0165     }
0166 
0167     Connections {
0168         target: AccountManager
0169 
0170         function onAccountSelected() {
0171             decideDefaultPage();
0172         }
0173 
0174         function onAccountRemoved() {
0175             if (!AccountManager.hasAccounts) {
0176                 pageStack.replace(Qt.createComponent("org.kde.tokodon", "WelcomePage"));
0177                 globalDrawer.drawerOpen = false;
0178             }
0179         }
0180 
0181         function onAccountsReloaded() {
0182             pageStack.replace(mainTimeline, {
0183                 name: "home"
0184             });
0185         }
0186 
0187         function onAccountsReady() {
0188             appwindow.startupAccountCheck();
0189         }
0190     }
0191 
0192     Connections {
0193         target: Controller
0194 
0195         function onOpenPost(id) {
0196             Navigation.openThread(id)
0197         }
0198 
0199         function onOpenAccount(id) {
0200             Navigation.openAccount(id)
0201         }
0202 
0203         function onOpenComposer(text) {
0204             pageStack.layers.push("./StatusComposer/StatusComposer.qml", {
0205                 purpose: StatusComposer.New,
0206                 initialText: text,
0207                 onPostFinished: applicationWindow().pageStack.layers.pop()
0208             });
0209         }
0210     }
0211 
0212     Connections {
0213         target: Navigation
0214 
0215         function onOpenStatusComposer() {
0216             pageStack.layers.push("./StatusComposer/StatusComposer.qml", {
0217                 purpose: StatusComposer.New
0218             });
0219         }
0220 
0221         function onReplyTo(inReplyTo, mentions, visibility, authorIdentity, post) {
0222             if (!mentions.includes(`@${authorIdentity.account}`)) {
0223                 mentions.push(`@${authorIdentity.account}`);
0224             }
0225             pageStack.layers.push("./StatusComposer/StatusComposer.qml", {
0226                 purpose: StatusComposer.Reply,
0227                 inReplyTo: inReplyTo,
0228                 mentions: mentions,
0229                 visibility: visibility,
0230                 previewPost: post
0231             });
0232         }
0233 
0234         function onOpenThread(postId) {
0235             if (!pageStack.currentItem.postId || pageStack.currentItem.postId !== postId) {
0236                 pageStack.push(Qt.createComponent("org.kde.tokodon", "ThreadPage"), {
0237                     postId: postId,
0238                 });
0239             }
0240         }
0241 
0242         function onOpenAccount(accountId) {
0243             if (!pageStack.currentItem.accountId || pageStack.currentItem.accountId !== accountId) {
0244                 pageStack.push(Qt.createComponent("org.kde.tokodon", "AccountInfo"), {
0245                     accountId: accountId,
0246                 });
0247             }
0248         }
0249 
0250         function onOpenTag(tag) {
0251             pageStack.push(tagModelComponent, {
0252                 hashtag: tag,
0253             })
0254         }
0255 
0256         function onReportPost(identity, postId) {
0257             applicationWindow().pageStack.pushDialogLayer(Qt.createComponent("org.kde.tokodon", "ReportDialog"),
0258                 {
0259                     type: ReportDialog.Post,
0260                     identity: identity,
0261                     postId: postId
0262                 });
0263         }
0264 
0265         function onReportUser(identity) {
0266             applicationWindow().pageStack.pushDialogLayer(Qt.createComponent("org.kde.tokodon", "ReportDialog"),
0267                 {
0268                     type: ReportDialog.User,
0269                     identity: identity
0270                 });
0271         }
0272 
0273         function onOpenList(listId, name) {
0274             pageStack.push(Qt.createComponent("org.kde.tokodon", "ListPage"), {
0275                 name,
0276                 listId
0277             });
0278         }
0279     }
0280 
0281     globalDrawer: Kirigami.OverlayDrawer {
0282         id: drawer
0283         enabled: AccountManager.hasAccounts && AccountManager.isReady
0284         edge: Qt.application.layoutDirection === Qt.RightToLeft ? Qt.RightEdge : Qt.LeftEdge
0285         modal: !enabled || Kirigami.Settings.isMobile || Kirigami.Settings.tabletMode || (applicationWindow().width < Kirigami.Units.gridUnit * 50 && !collapsed) // Only modal when not collapsed, otherwise collapsed won't show.
0286         z: modal ? Math.round(position * 10000000) : 100
0287         drawerOpen: !Kirigami.Settings.isMobile && enabled
0288         width: Kirigami.Units.gridUnit * 16
0289         Behavior on width {
0290             NumberAnimation {
0291                 duration: Kirigami.Units.longDuration
0292                 easing.type: Easing.InOutQuad
0293             }
0294         }
0295         Kirigami.Theme.colorSet: Kirigami.Theme.View
0296         Kirigami.Theme.inherit: false
0297 
0298         handleClosedIcon.source: modal ? null : "sidebar-expand-left"
0299         handleOpenIcon.source: modal ? null : "sidebar-collapse-left"
0300         handleVisible: modal && !isShowingFullScreenImage && enabled
0301         onModalChanged: drawerOpen = !modal;
0302 
0303         leftPadding: 0
0304         rightPadding: 0
0305         topPadding: 0
0306         bottomPadding: 0
0307 
0308         contentItem: ColumnLayout {
0309             spacing: 0
0310 
0311             QQC2.ToolBar {
0312                 Layout.fillWidth: true
0313                 Layout.preferredHeight: pageStack.globalToolBar.preferredHeight
0314                 Layout.bottomMargin: Kirigami.Units.smallSpacing / 2
0315 
0316                 leftPadding: 3
0317                 rightPadding: 3
0318                 topPadding: 3
0319                 bottomPadding: 3
0320 
0321                 visible: !Kirigami.Settings.isMobile
0322 
0323                 contentItem: SearchField {}
0324             }
0325 
0326             UserInfo {
0327                 Layout.fillWidth: true
0328             }
0329 
0330             Kirigami.Separator {
0331                 Layout.fillWidth: true
0332                 Layout.margins: Kirigami.Units.smallSpacing
0333             }
0334 
0335             QQC2.ButtonGroup {
0336                 id: pageButtonGroup
0337             }
0338 
0339             Repeater {
0340                 model: Kirigami.Settings.isMobile ?
0341                     [searchAction, announcementsAction, followRequestAction, exploreAction, conversationAction, favouritesAction, bookmarksAction, listsAction] :
0342                     [homeAction, notificationAction, searchAction, announcementsAction, followRequestAction, localTimelineAction, globalTimelineAction, exploreAction, conversationAction, favouritesAction, bookmarksAction, listsAction]
0343                 Delegates.RoundedItemDelegate {
0344                     required property var modelData
0345                     QQC2.ButtonGroup.group: pageButtonGroup
0346 
0347                     padding: Kirigami.Units.largeSpacing
0348                     action: modelData
0349                     Layout.fillWidth: true
0350                     visible: modelData.visible
0351                     enabled: !AccountManager.selectedAccountHasIssue
0352                 }
0353             }
0354 
0355             Item {
0356                 Layout.fillHeight: true
0357             }
0358 
0359             Delegates.RoundedItemDelegate {
0360                 icon.name: "debug-run"
0361                 onClicked: pageStack.pushDialogLayer(Qt.createComponent("org.kde.tokodon", "DebugPage"))
0362                 text: i18nc("@action:button Open debug page", "Debug")
0363                 visible: AccountManager.testMode
0364                 padding: Kirigami.Units.largeSpacing
0365 
0366                 Layout.fillWidth: true
0367             }
0368 
0369             Delegates.RoundedItemDelegate {
0370                 icon.name: "lock"
0371                 onClicked: pageStack.pushDialogLayer(Qt.createComponent("org.kde.tokodon", "ModerationToolPage"), {}, {title: i18n("Moderation Tools")})
0372                 text: i18nc("@action:button Open moderation tools", "Moderation Tools")
0373                 visible: AccountManager.selectedAccount && (AccountManager.selectedAccount.identity.permission & AdminAccountInfo.ManageUsers)
0374                 padding: Kirigami.Units.largeSpacing
0375 
0376                 Layout.fillWidth: true
0377             }
0378 
0379             Delegates.RoundedItemDelegate {
0380                 icon.name: "settings-configure"
0381                 onClicked: pageStack.pushDialogLayer(Qt.createComponent("org.kde.tokodon", "SettingsPage"), {}, {title: i18n("Configure")})
0382                 text: i18nc("@action:button Open settings dialog", "Settings")
0383                 padding: Kirigami.Units.largeSpacing
0384 
0385                 Layout.fillWidth: true
0386                 Layout.bottomMargin: Kirigami.Units.smallSpacing
0387             }
0388         }
0389     }
0390 
0391     property Kirigami.Action homeAction: Kirigami.Action {
0392         icon.name: "go-home-large"
0393         text: i18n("Home")
0394         checkable: true
0395         onTriggered: {
0396             pageStack.clear();
0397             pageStack.push(mainTimeline, {
0398                 name: "home"
0399             });
0400             checked = true;
0401             if (Kirigami.Settings.isMobile || drawer.modal) {
0402                 drawer.drawerOpen = false;
0403             }
0404         }
0405     }
0406     property Kirigami.Action notificationAction: Kirigami.Action {
0407         icon.name: "notifications"
0408         text: i18n("Notifications")
0409         checkable: true
0410         onTriggered: {
0411             pageStack.clear();
0412             pageStack.push(notificationTimeline);
0413             checked = true;
0414             if (Kirigami.Settings.isMobile || drawer.modal) {
0415                 drawer.drawerOpen = false;
0416             }
0417         }
0418     }
0419     property Kirigami.Action followRequestAction: Kirigami.Action {
0420         icon.name: "list-add-user"
0421         text: i18n("Follow Requests")
0422         checkable: true
0423         visible: AccountManager.hasAccounts && AccountManager.selectedAccount && AccountManager.selectedAccount.hasFollowRequests
0424         onTriggered: {
0425             pageStack.clear();
0426             pageStack.push(socialGraphComponent, {
0427                 name: "request"
0428             });
0429             checked = true;
0430             if (Kirigami.Settings.isMobile || drawer.modal) {
0431                 drawer.drawerOpen = false;
0432             }
0433         }
0434     }
0435     property Kirigami.Action localTimelineAction: Kirigami.Action {
0436         icon.name: "system-users"
0437         text: i18n("Local")
0438         checkable: true
0439         onTriggered: {
0440             pageStack.clear();
0441             pageStack.push(mainTimeline, {
0442                 name: "public",
0443             });
0444             checked = true;
0445             if (Kirigami.Settings.isMobile || drawer.modal) {
0446                 drawer.drawerOpen = false;
0447             }
0448         }
0449     }
0450     property Kirigami.Action globalTimelineAction: Kirigami.Action {
0451         icon.name: "kstars_xplanet"
0452         text: i18n("Global")
0453         checkable: true
0454         onTriggered: {
0455             pageStack.clear();
0456             pageStack.push(mainTimeline, {
0457                 name: "federated",
0458             });
0459             checked = true;
0460             if (Kirigami.Settings.isMobile || drawer.modal) {
0461                 drawer.drawerOpen = false;
0462             }
0463         }
0464     }
0465 
0466     property Kirigami.Action conversationAction: Kirigami.Action {
0467         icon.name: "tokodon-chat-reply"
0468         text: i18n("Conversation")
0469         checkable: true
0470         onTriggered: {
0471             pageStack.clear();
0472             pageStack.push(Qt.createComponent("org.kde.tokodon", "ConversationPage"));
0473             checked = true;
0474             if (Kirigami.Settings.isMobile || drawer.modal) {
0475                 drawer.drawerOpen = false;
0476             }
0477         }
0478     }
0479 
0480     property Kirigami.Action favouritesAction: Kirigami.Action {
0481         icon.name: "tokodon-post-favorite"
0482         text: i18n("Favourites")
0483         checkable: true
0484         onTriggered: {
0485             pageStack.clear();
0486             pageStack.push(mainTimeline, {
0487                 name: "favourites",
0488             });
0489             checked = true;
0490             if (Kirigami.Settings.isMobile || drawer.modal) {
0491                 drawer.drawerOpen = false;
0492             }
0493         }
0494     }
0495 
0496     property Kirigami.Action bookmarksAction: Kirigami.Action {
0497         icon.name: "bookmarks"
0498         text: i18n("Bookmarks")
0499         checkable: true
0500         onTriggered: {
0501             pageStack.clear();
0502             pageStack.push(mainTimeline, {
0503                 name: "bookmarks",
0504             });
0505             checked = true;
0506             if (Kirigami.Settings.isMobile || drawer.modal) {
0507                 drawer.drawerOpen = false;
0508             }
0509         }
0510     }
0511 
0512     property Kirigami.Action exploreAction: Kirigami.Action {
0513         icon.name: "kstars_planets"
0514         text: i18n("Explore")
0515         checkable: true
0516         onTriggered: {
0517             pageStack.clear();
0518             pageStack.push(exploreTimeline);
0519             checked = true;
0520             if (Kirigami.Settings.isMobile || drawer.modal) {
0521                 drawer.drawerOpen = false;
0522             }
0523         }
0524     }
0525 
0526     property Kirigami.Action searchAction: Kirigami.Action {
0527         icon.name: "search"
0528         text: i18n("Search")
0529         checkable: true
0530         visible: Kirigami.Settings.isMobile
0531         onTriggered: {
0532             pageStack.clear();
0533             pageStack.push(Qt.createComponent("org.kde.tokodon", "SearchPage"));
0534             checked = true;
0535             if (Kirigami.Settings.isMobile) {
0536                 drawer.drawerOpen = false;
0537             }
0538         }
0539     }
0540 
0541     property Kirigami.Action announcementsAction: Kirigami.Action {
0542         icon.name: "note"
0543         text: i18nc("@action:button Server Announcements", "Announcements")
0544         checkable: true
0545         visible: AccountManager.hasAccounts && AccountManager.selectedAccount
0546         onTriggered: {
0547             pageStack.clear();
0548             pageStack.push(Qt.createComponent("org.kde.tokodon", "AnnouncementsPage"));
0549             checked = true;
0550             if (Kirigami.Settings.isMobile || drawer.modal) {
0551                 drawer.drawerOpen = false;
0552             }
0553         }
0554     }
0555 
0556     property Kirigami.Action listsAction: Kirigami.Action {
0557         icon.name: "view-list-text"
0558         text: i18n("Lists")
0559         checkable: true
0560         onTriggered: {
0561             pageStack.clear();
0562             pageStack.push(Qt.createComponent("org.kde.tokodon", "ListsPage"));
0563             checked = true;
0564             if (Kirigami.Settings.isMobile || drawer.modal) {
0565                 drawer.drawerOpen = false;
0566             }
0567         }
0568     }
0569 
0570     property Kirigami.NavigationTabBar tabBar: Kirigami.NavigationTabBar {
0571         // Make sure we take in count drawer width
0572         visible: pageStack.layers.depth <= 1 && AccountManager.hasAccounts && !appwindow.wideScreen
0573         actions: [homeAction, notificationAction, localTimelineAction, globalTimelineAction]
0574         enabled: !AccountManager.selectedAccountHasIssue
0575     }
0576 
0577     footer: Kirigami.Settings.isMobile ? tabBar : null
0578 
0579     contextDrawer: Kirigami.ContextDrawer {
0580         id: contextDrawer
0581     }
0582 
0583     Component {
0584         id: mainTimeline
0585         TimelinePage {
0586             id: timelinePage
0587             property alias name: timelineModel.name
0588             model: MainTimelineModel {
0589                 id: timelineModel
0590                 showReplies: timelinePage.showReplies
0591                 showBoosts: timelinePage.showBoosts
0592             }
0593         }
0594     }
0595 
0596     Component {
0597         id: socialGraphComponent
0598         SocialGraphPage {
0599             id: socialGraphPage
0600             property alias name: socialGraphModel.name
0601             property alias accountId: socialGraphModel.accountId
0602             property alias statusId: socialGraphModel.statusId
0603             property alias count: socialGraphModel.count
0604             model: SocialGraphModel {
0605                 id: socialGraphModel
0606                 name: socialGraphPage.name
0607                 accountId: socialGraphPage.accountId
0608                 statusId: socialGraphPage.statusId
0609                 count: socialGraphPage.count
0610             }
0611         }
0612     }
0613 
0614     Component {
0615         id: notificationTimeline
0616         NotificationPage { }
0617     }
0618 
0619     Component {
0620         id: exploreTimeline
0621         ExplorePage { }
0622     }
0623 
0624     property Item hoverLinkIndicator: QQC2.Control {
0625         parent: overlay.parent
0626         property alias text: linkText.text
0627         opacity: text.length > 0 ? 1 : 0
0628         visible: !Kirigami.Settings.isMobile && !text.startsWith("hashtag:") && !text.startsWith("account:")
0629 
0630         z: 999990
0631         x: 0
0632         y: parent.height - implicitHeight
0633         contentItem: QQC2.Label {
0634             id: linkText
0635         }
0636         Kirigami.Theme.colorSet: Kirigami.Theme.View
0637         background: Rectangle {
0638              color: Kirigami.Theme.backgroundColor
0639         }
0640     }
0641 
0642     Component {
0643         id: tagModelComponent
0644         TimelinePage {
0645             id: tagPage
0646             property string hashtag
0647             model: TagsTimelineModel {
0648                 hashtag: tagPage.hashtag
0649                 showReplies: tagPage.showReplies
0650                 showBoosts: tagPage.showBoosts
0651             }
0652         }
0653     }
0654 
0655     Rectangle {
0656         anchors.fill: parent
0657         visible: !AccountManager.isReady
0658         color: Kirigami.Theme.backgroundColor
0659 
0660         Kirigami.LoadingPlaceholder {
0661             anchors.centerIn: parent
0662         }
0663     }
0664 
0665     // This timer allows to batch update the window size change to reduce
0666     // the io load and also work around the fact that x/y/width/height are
0667     // changed when loading the page and overwrite the saved geometry from
0668     // the previous session.
0669     Timer {
0670         id: saveWindowGeometryTimer
0671         interval: 1000
0672         onTriggered: WindowController.saveGeometry()
0673     }
0674 
0675     Connections {
0676         id: saveWindowGeometryConnections
0677         enabled: false // Disable on startup to avoid writing wrong values if the window is hidden
0678         target: appwindow
0679 
0680         function onClosing() { WindowController.saveGeometry(); }
0681         function onWidthChanged() { saveWindowGeometryTimer.restart(); }
0682         function onHeightChanged() { saveWindowGeometryTimer.restart(); }
0683         function onXChanged() { saveWindowGeometryTimer.restart(); }
0684         function onYChanged() { saveWindowGeometryTimer.restart(); }
0685     }
0686 
0687     Connections {
0688         target: AccountManager.selectedAccount
0689 
0690         function onFetchedOEmbed(html) {
0691             embedDialog.active = true;
0692             embedDialog.item.html = html;
0693             embedDialog.item.open()
0694         }
0695     }
0696 
0697     Loader {
0698         id: embedDialog
0699 
0700         active: false
0701         sourceComponent: Kirigami.PromptDialog {
0702             property alias html: textArea.text
0703 
0704             title: i18nc("@title", "Embed Information")
0705             mainItem: QQC2.TextArea {
0706                 id: textArea
0707 
0708                 readOnly: true
0709                 wrapMode: TextEdit.Wrap
0710 
0711                 Kirigami.SpellCheck.enabled: false
0712             }
0713             standardButtons: Kirigami.Dialog.Ok
0714             showCloseButton: false
0715         }
0716     }
0717 }