Warning, /plasma/xdg-desktop-portal-kde/src/AppChooserDialog.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  * SPDX-FileCopyrightText: 2019 Red Hat Inc
0003  * SPDX-License-Identifier: LGPL-2.0-or-later
0004  *
0005  * SPDX-FileCopyrightText: 2019 Jan Grulich <jgrulich@redhat.com>
0006  * SPDX-FileCopyrightText: 2022 Nate Graham <nate@kde.org>
0007  */
0008 
0009 pragma ComponentBehavior: Bound
0010 
0011 import QtQuick
0012 import QtQuick.Controls as QQC2
0013 import QtQuick.Layouts
0014 import Qt.labs.platform
0015 import org.kde.kirigami as Kirigami
0016 import org.kde.plasma.workspace.dialogs as PWD
0017 
0018 import org.kde.xdgdesktopportal
0019 
0020 PWD.SystemDialog {
0021     id: root
0022 
0023     iconName: "applications-all"
0024 
0025     property bool remember: false
0026 
0027     ColumnLayout {
0028         spacing: Kirigami.Units.smallSpacing
0029 
0030         QQC2.CheckBox {
0031             Layout.fillWidth: true
0032             text: i18nc("@option:check %1 is description of a file type, like 'PNG image'", "Always open %1 files with the chosen app", AppChooserData.mimeDesc)
0033             checked: root.remember
0034             onToggled: {
0035                 root.remember = checked;
0036             }
0037         }
0038 
0039         RowLayout {
0040             spacing: Kirigami.Units.smallSpacing
0041 
0042             Kirigami.SearchField {
0043                 id: searchField
0044                 implicitWidth: Kirigami.Units.gridUnit * 20
0045                 Layout.fillWidth: true
0046                 focus: true
0047                 // We don't want auto-accept here because it would cause the
0048                 // selected app in the grid view to be immediately launched
0049                 // without user input
0050                 autoAccept: false
0051 
0052                 Keys.onDownPressed: {
0053                     grid.forceActiveFocus();
0054                     grid.currentIndex = 0;
0055                 }
0056                 onTextChanged: {
0057                     AppModel.filter = text;
0058                     if (text.length > 0 && grid.count === 1) {
0059                         grid.currentIndex = 0;
0060                     }
0061                 }
0062                 onAccepted: grid.currentItem.activate();
0063             }
0064 
0065             QQC2.Button {
0066                 icon.name: "view-more-symbolic"
0067                 text: i18n("Show All Installed Applications")
0068 
0069                 checkable: true
0070                 checked: !AppModel.showOnlyPreferredApps
0071                 visible: AppModel.sourceModel.hasPreferredApps
0072                 onVisibleChanged: AppModel.showOnlyPreferredApps = visible
0073 
0074                 onToggled: AppModel.showOnlyPreferredApps = !AppModel.showOnlyPreferredApps
0075             }
0076         }
0077 
0078 
0079         QQC2.ScrollView {
0080             id: scrollView
0081 
0082             Layout.fillWidth: true
0083             Layout.fillHeight: true
0084             Layout.preferredHeight: grid.cellHeight * 3
0085 
0086             Component.onCompleted: {
0087                 if (background) {
0088                     background.visible = true;
0089                 }
0090             }
0091 
0092             GridView {
0093                 id: grid
0094 
0095                 readonly property int gridDelegateSize: Kirigami.Units.iconSizes.huge + (Kirigami.Units.gridUnit * 4)
0096 
0097                 clip: true
0098 
0099                 Keys.onReturnPressed: currentItem.activate();
0100                 Keys.onEnterPressed: currentItem.activate();
0101 
0102                 currentIndex: -1 // Don't pre-select anything as that doesn't make sense here
0103 
0104                 cellWidth: {
0105                     const columns = Math.max(Math.floor(scrollView.availableWidth / gridDelegateSize), 2);
0106                     return Math.floor(scrollView.availableWidth / columns) - 1;
0107                 }
0108                 cellHeight: gridDelegateSize
0109 
0110                 model: AppModel
0111                 delegate: Item {
0112                     id: delegate
0113 
0114                     required property int index
0115                     required property var model
0116 
0117                     height: grid.cellHeight
0118                     width: grid.cellWidth
0119 
0120                     function activate() {
0121                         AppChooserData.applicationSelected(model.applicationDesktopFile, root.remember)
0122                     }
0123 
0124                     HoverHandler {
0125                         id: hoverhandler
0126                     }
0127 
0128                     TapHandler {
0129                         id: taphandler
0130                         onTapped: delegate.activate()
0131                     }
0132 
0133                     Rectangle {
0134                         anchors.fill: parent
0135                         visible: hoverhandler.hovered || delegate.GridView.isCurrentItem
0136                         border.color: Kirigami.Theme.highlightColor
0137                         border.width: 1
0138                         color: taphandler.pressed ? Kirigami.Theme.highlightColor : Qt.alpha(Kirigami.Theme.highlightColor, 0.3)
0139                         radius: Kirigami.Units.smallSpacing
0140                     }
0141 
0142                     ColumnLayout {
0143                         anchors {
0144                             top: parent.top
0145                             left: parent.left
0146                             right: parent.right
0147                             margins: Kirigami.Units.largeSpacing
0148                         }
0149                         spacing: 0 // Items add their own as needed here
0150 
0151                         Kirigami.Icon {
0152                             Layout.preferredWidth: Kirigami.Units.iconSizes.huge
0153                             Layout.preferredHeight: Kirigami.Units.iconSizes.huge
0154                             Layout.bottomMargin: Kirigami.Units.largeSpacing
0155                             Layout.alignment: Qt.AlignHCenter
0156                             source: delegate.model.applicationIcon
0157                             smooth: true
0158                         }
0159 
0160                         QQC2.Label {
0161                             Layout.fillWidth: true
0162                             Layout.alignment: Qt.AlignTop
0163                             horizontalAlignment: Text.AlignHCenter
0164                             text: delegate.model.applicationName
0165                             font.bold: delegate.model.applicationDesktopFile === AppChooserData.defaultApp
0166                             elide: Text.ElideRight
0167                             maximumLineCount: 2
0168                             wrapMode: Text.WordWrap
0169                         }
0170 
0171                         QQC2.Label {
0172                             Layout.fillWidth: true
0173                             Layout.alignment: Qt.AlignTop
0174                             horizontalAlignment: Text.AlignHCenter
0175                             visible: delegate.model.applicationDesktopFile === AppChooserData.defaultApp || delegate.model.applicationDesktopFile === AppChooserData.lastUsedApp
0176                             font.bold: true
0177                             opacity: 0.7
0178                             text: delegate.model.applicationDesktopFile === AppChooserData.defaultApp
0179                                 ? i18n("Default app for this file type")
0180                                 : i18nc("@info:whatsthis", "Last used app for this file type")
0181                             elide: Text.ElideRight
0182                             maximumLineCount: 2
0183                             wrapMode: Text.WordWrap
0184                         }
0185                     }
0186                 }
0187 
0188                 Loader {
0189                     id: placeholderLoader
0190 
0191                     anchors.centerIn: parent
0192                     width: parent.width - Kirigami.Units.gridUnit * 4
0193 
0194                     active: grid.count === 0
0195                     sourceComponent: Kirigami.PlaceholderMessage {
0196                         anchors.centerIn: parent
0197 
0198                         icon.name: "edit-none"
0199                         text: searchField.text.length > 0 ? i18n("No matches") : xi18nc("@info", "No installed applications can open <filename>%1</filename>", AppChooserData.fileName)
0200 
0201                         helpfulAction: QQC2.Action {
0202                             icon.name: "plasmadiscover"
0203                             text: i18nc("Find some more apps that can open this content using the Discover app", "Find More in Discover")
0204                             onTriggered: AppChooserData.openDiscover()
0205                         }
0206                     }
0207                 }
0208             }
0209         }
0210 
0211         // Using a TextEdit here instead of a Label because it can know when any
0212         // links are hovered, which is needed for us to be able to use the correct
0213         // cursor shape for it.
0214 
0215         TextEdit {
0216             visible: !placeholderLoader.active && StandardPaths.findExecutable("plasma-discover").toString() !== ""
0217             Layout.fillWidth: true
0218             text: xi18nc("@info", "Don't see the right app? Find more in <link>Discover</link>.")
0219             textFormat: Text.RichText
0220             wrapMode: Text.WordWrap
0221             readOnly: true
0222             color: Kirigami.Theme.textColor
0223             selectedTextColor: Kirigami.Theme.highlightedTextColor
0224             selectionColor: Kirigami.Theme.highlightColor
0225 
0226             onLinkActivated: {
0227                 AppChooserData.openDiscover()
0228             }
0229 
0230             HoverHandler {
0231                 acceptedButtons: Qt.NoButton
0232                 cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
0233             }
0234         }
0235     }
0236 }
0237