Warning, /plasma/discover/discover/qml/SourcesPage.qml is written in an unsupported language. File is not indexed.

0001 pragma ComponentBehavior: Bound
0002 
0003 import QtQuick
0004 import QtQuick.Controls as QQC2
0005 import QtQuick.Layouts
0006 import org.kde.discover as Discover
0007 import org.kde.kcmutils as KCMUtils
0008 import org.kde.kirigami as Kirigami
0009 import org.kde.kirigami.delegates as KD
0010 
0011 DiscoverPage {
0012     id: page
0013 
0014     property string search
0015     readonly property string name: title
0016 
0017     clip: true
0018     title: i18n("Settings")
0019 
0020     Kirigami.Action {
0021         id: configureUpdatesAction
0022         text: i18n("Configure Updates…")
0023         displayHint: Kirigami.DisplayHint.AlwaysHide
0024         onTriggered: {
0025             KCMUtils.KCMLauncher.openSystemSettings("kcm_updates");
0026         }
0027     }
0028 
0029     actions: feedbackLoader.item?.actions ?? [configureUpdatesAction]
0030 
0031     header: ColumnLayout {
0032         spacing: Kirigami.Units.smallSpacing
0033 
0034         Repeater {
0035             model: Discover.SourcesModel.sources
0036 
0037             delegate: Kirigami.InlineMessage {
0038                 id: delegate
0039 
0040                 required property Discover.AbstractSourcesBackend modelData
0041 
0042                 Layout.fillWidth: true
0043                 Layout.margins: Kirigami.Units.smallSpacing
0044                 text: modelData.inlineAction?.toolTip ?? ""
0045                 visible: modelData.inlineAction?.visible ?? false
0046                 actions: Kirigami.Action {
0047                     icon.name: delegate.modelData.inlineAction?.iconName ?? ""
0048                     text: delegate.modelData.inlineAction?.text ?? ""
0049                     onTriggered: delegate.modelData.inlineAction?.trigger()
0050                 }
0051             }
0052         }
0053     }
0054 
0055     ListView {
0056         id: sourcesView
0057         model: Discover.SourcesModel
0058         Component.onCompleted: Qt.callLater(Discover.SourcesModel.showingNow)
0059         currentIndex: -1
0060         pixelAligned: true
0061         section.property: "sourceName"
0062         section.delegate: Kirigami.ListSectionHeader {
0063             id: backendItem
0064 
0065             required property string section
0066 
0067             height: Math.ceil(Math.max(Kirigami.Units.gridUnit * 2.5, contentItem.implicitHeight))
0068 
0069             readonly property Discover.AbstractSourcesBackend backend: Discover.SourcesModel.sourcesBackendByName(section)
0070             readonly property Discover.AbstractResourcesBackend resourcesBackend: backend.resourcesBackend
0071             readonly property bool isDefault: Discover.ResourcesModel.currentApplicationBackend === resourcesBackend
0072 
0073             width: sourcesView.width
0074 
0075             Connections {
0076                 target: backendItem.backend
0077                 function onPassiveMessage(message) {
0078                     window.showPassiveNotification(message)
0079                 }
0080                 function onProceedRequest(title, description) {
0081                     const dialog = sourceProceedDialog.createObject(window, {
0082                         sourcesBackend: backendItem.backend,
0083                         title,
0084                         description,
0085                     })
0086                     dialog.open()
0087                 }
0088             }
0089 
0090             contentItem: RowLayout {
0091                 spacing: Kirigami.Units.smallSpacing
0092 
0093                 Kirigami.Heading {
0094                     text: resourcesBackend.displayName
0095                     level: 3
0096                     font.weight: backendItem.isDefault ? Font.Bold : Font.Normal
0097                 }
0098 
0099                 Kirigami.ActionToolBar {
0100                     id: actionBar
0101 
0102                     alignment: Qt.AlignRight
0103 
0104                     Kirigami.Action {
0105                         id: isDefaultbackendLabelAction
0106 
0107                         visible: backendItem.isDefault
0108                         displayHint: Kirigami.DisplayHint.KeepVisible
0109                         displayComponent: Kirigami.Heading {
0110                             text: i18n("Default source")
0111                             level: 3
0112                             font.weight: Font.Bold
0113                         }
0114                     }
0115 
0116                     Kirigami.Action {
0117                         id: addSourceAction
0118                         text: i18n("Add Source…")
0119                         icon.name: "list-add"
0120                         visible: backendItem.backend && backendItem.backend.supportsAdding
0121 
0122                         onTriggered: {
0123                             const addSourceDialog = dialogComponent.createObject(window, {
0124                                 displayName: backendItem.backend.resourcesBackend.displayName,
0125                             })
0126                             addSourceDialog.open()
0127                         }
0128                     }
0129 
0130                     Component {
0131                         id: dialogComponent
0132                         AddSourceDialog {
0133                             source: backendItem.backend
0134 
0135                             onClosed: {
0136                                 destroy();
0137                             }
0138                         }
0139                     }
0140 
0141                     Kirigami.Action {
0142                         id: makeDefaultAction
0143                         visible: resourcesBackend && resourcesBackend.hasApplications && !backendItem.isDefault
0144 
0145                         text: i18n("Make default")
0146                         icon.name: "favorite"
0147                         onTriggered: Discover.ResourcesModel.currentApplicationBackend = backendItem.backend.resourcesBackend
0148                     }
0149 
0150                     Component {
0151                         id: kirigamiAction
0152                         ConvertDiscoverAction {}
0153                     }
0154 
0155                     function mergeActions(moreActions) {
0156                         const actions = [
0157                             isDefaultbackendLabelAction,
0158                             makeDefaultAction,
0159                             addSourceAction
0160                         ]
0161                         for (const action of moreActions) {
0162                             actions.push(kirigamiAction.createObject(this, { action }))
0163                         }
0164                         return actions;
0165                     }
0166                     actions: mergeActions(backendItem.backend.actions)
0167                 }
0168             }
0169         }
0170 
0171         Component {
0172             id: sourceProceedDialog
0173             Kirigami.OverlaySheet {
0174                 id: sheet
0175 
0176                 property Discover.AbstractSourcesBackend sourcesBackend
0177                 property alias description: descriptionLabel.text
0178                 property bool acted: false
0179 
0180                 parent: page.QQC2.Overlay.overlay
0181                 showCloseButton: false
0182 
0183                 implicitWidth: Kirigami.Units.gridUnit * 30
0184 
0185                 Kirigami.SelectableLabel {
0186                     id: descriptionLabel
0187                     width: parent.width
0188                     textFormat: TextEdit.RichText
0189                     wrapMode: TextEdit.Wrap
0190                 }
0191 
0192                 footer: QQC2.DialogButtonBox {
0193                     QQC2.Button {
0194                         QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole
0195                         text: i18n("Proceed")
0196                         icon.name: "dialog-ok"
0197                     }
0198 
0199                     QQC2.Button {
0200                         QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.RejectRole
0201                         text: i18n("Cancel")
0202                         icon.name: "dialog-cancel"
0203                     }
0204 
0205                     onAccepted: {
0206                         sheet.sourcesBackend.proceed()
0207                         sheet.acted = true
0208                         sheet.close()
0209                     }
0210 
0211                     onRejected: {
0212                         sheet.sourcesBackend.cancel()
0213                         sheet.acted = true
0214                         sheet.close()
0215                     }
0216                 }
0217 
0218                 onOpened: {
0219                     descriptionLabel.forceActiveFocus(Qt.PopupFocusReason);
0220                 }
0221 
0222                 onClosed: {
0223                     if (!acted) {
0224                         sourcesBackend.cancel()
0225                     }
0226                     destroy();
0227                 }
0228             }
0229         }
0230 
0231         delegate: Kirigami.SwipeListItem {
0232             id: delegate
0233 
0234             required property int index
0235             required property var model
0236 
0237             enabled: model.display.length > 0 && model.enabled
0238             highlighted: ListView.isCurrentItem
0239             supportsMouseEvents: false
0240             visible: model.display.indexOf(page.search) >= 0
0241             height: visible ? implicitHeight : 0
0242 
0243             Keys.onReturnPressed: enabledBox.clicked()
0244             Keys.onSpacePressed: enabledBox.clicked()
0245             actions: [
0246                 Kirigami.Action {
0247                     icon.name: "go-up"
0248                     tooltip: i18n("Increase priority")
0249                     enabled: delegate.model.sourcesBackend.firstSourceId !== delegate.model.sourceId
0250                     visible: delegate.model.sourcesBackend.canMoveSources
0251                     onTriggered: {
0252                         const ret = delegate.model.sourcesBackend.moveSource(delegate.model.sourceId, -1)
0253                         if (!ret) {
0254                             window.showPassiveNotification(i18n("Failed to increase '%1' preference", delegate.model.display))
0255                         }
0256                     }
0257                 },
0258                 Kirigami.Action {
0259                     icon.name: "go-down"
0260                     tooltip: i18n("Decrease priority")
0261                     enabled: delegate.model.sourcesBackend.lastSourceId !== delegate.model.sourceId
0262                     visible: delegate.model.sourcesBackend.canMoveSources
0263                     onTriggered: {
0264                         const ret = delegate.model.sourcesBackend.moveSource(delegate.model.sourceId, +1)
0265                         if (!ret) {
0266                             window.showPassiveNotification(i18n("Failed to decrease '%1' preference", delegate.model.display))
0267                         }
0268                     }
0269                 },
0270                 Kirigami.Action {
0271                     icon.name: "edit-delete"
0272                     tooltip: i18n("Remove repository")
0273                     visible: delegate.model.sourcesBackend.supportsAdding
0274                     onTriggered: {
0275                         const backend = delegate.model.sourcesBackend
0276                         if (!backend.removeSource(delegate.model.sourceId)) {
0277                             console.warn("Failed to remove the source", delegate.model.display)
0278                         }
0279                     }
0280                 },
0281                 Kirigami.Action {
0282                     icon.name: delegate.mirrored ? "go-next-symbolic-rtl" : "go-next-symbolic"
0283                     tooltip: i18n("Show contents")
0284                     visible: delegate.model.sourcesBackend.canFilterSources
0285                     onTriggered: {
0286                         Navigation.openApplicationListSource(delegate.model.sourceId)
0287                     }
0288                 }
0289             ]
0290 
0291             contentItem: RowLayout {
0292                 spacing: Kirigami.Units.smallSpacing
0293 
0294                 QQC2.CheckBox {
0295                     id: enabledBox
0296 
0297                     readonly property var idx: sourcesView.model.index(index, 0)
0298                     readonly property /*Qt::CheckState*/int modelChecked: delegate.model.checkState
0299                     checked: modelChecked !== Qt.Unchecked
0300                     enabled: sourcesView.model.flags(idx) & Qt.ItemIsUserCheckable
0301                     onClicked: {
0302                         sourcesView.model.setData(idx, checkState, Qt.CheckStateRole)
0303                         checked = Qt.binding(() => (modelChecked !== Qt.Unchecked))
0304                     }
0305                 }
0306                 QQC2.Label {
0307                     text: delegate.model.display + (delegate.model.toolTip ? " - <i>" + delegate.model.toolTip + "</i>" : "")
0308                     elide: Text.ElideRight
0309                     textFormat: Text.StyledText
0310                     Layout.fillWidth: true
0311                 }
0312             }
0313         }
0314 
0315         footer: ColumnLayout {
0316             anchors {
0317                 right: parent.right
0318                 left: parent.left
0319                 margins: Kirigami.Units.smallSpacing
0320             }
0321             Kirigami.ListSectionHeader {
0322                 contentItem: Kirigami.Heading {
0323                     Layout.fillWidth: true
0324                     text: i18n("Missing Backends")
0325                     visible: back.count > 0
0326                     level: 3
0327                 }
0328             }
0329             spacing: 0
0330             Repeater {
0331                 id: back
0332                 model: Discover.ResourcesProxyModel {
0333                     extending: "org.kde.discover.desktop"
0334                     filterMinimumState: false
0335                     stateFilter: Discover.AbstractResource.None
0336                 }
0337                 delegate: QQC2.ItemDelegate {
0338                     id: delegate
0339 
0340                     required property int index
0341                     required property var model
0342 
0343                     Layout.fillWidth: true
0344                     hoverEnabled: false
0345                     down: false
0346 
0347                     contentItem: RowLayout {
0348                         spacing: Kirigami.Units.smallSpacing
0349                         KD.IconTitleSubtitle {
0350                             title: name
0351                             icon.source: delegate.model.icon
0352                             subtitle: delegate.model.comment
0353                             Layout.fillWidth: true
0354                         }
0355                         InstallApplicationButton {
0356                             application: delegate.model.application
0357                         }
0358                     }
0359                 }
0360             }
0361         }
0362     }
0363 }