Warning, /multimedia/kasts/src/qml/FeedListDelegate.qml is written in an unsupported language. File is not indexed.
0001 /** 0002 * SPDX-FileCopyrightText: 2020 Tobias Fella <tobias.fella@kde.org> 0003 * SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 */ 0007 0008 import QtQuick 0009 import QtQuick.Controls as Controls 0010 import QtQuick.Layouts 0011 import QtQuick.Effects 0012 import QtQml.Models 0013 0014 import org.kde.kirigami as Kirigami 0015 0016 import org.kde.kasts 0017 0018 Controls.ItemDelegate { 0019 id: feedDelegate 0020 0021 property var countProperty: (kastsMainWindow.feedSorting === FeedsProxyModel.UnreadDescending || kastsMainWindow.feedSorting === FeedsProxyModel.UnreadAscending) ? feed.unreadEntryCount : ((kastsMainWindow.feedSorting === FeedsProxyModel.NewDescending || kastsMainWindow.feedSorting === FeedsProxyModel.NewAscending) ? feed.newEntryCount : ((kastsMainWindow.feedSorting === FeedsProxyModel.FavoriteDescending || kastsMainWindow.feedSorting === FeedsProxyModel.FavoriteAscending) ? feed.favoriteEntryCount : 0)) 0022 property int cardSize: 0 0023 property int cardMargin: 0 0024 property int borderWidth: 1 0025 implicitWidth: cardSize + 2 * cardMargin 0026 implicitHeight: cardSize + 2 * cardMargin 0027 0028 property QtObject listView: undefined 0029 property bool selected: false 0030 property bool isCurrentItem: false // to restore currentItem when model is resorted 0031 property string currentItemUrl: "" 0032 property int row: model ? model.row : -1 0033 property var activeBackgroundColor: Qt.lighter(Kirigami.Theme.highlightColor, 1.3) 0034 highlighted: selected 0035 0036 Accessible.role: Accessible.Button 0037 Accessible.name: feed.name 0038 Accessible.onPressAction: { 0039 clicked(); 0040 } 0041 Keys.onReturnPressed: clicked() 0042 0043 // We need to update the "selected" status: 0044 // - if the selected indexes changes 0045 // - if our delegate moves 0046 // - if the model moves and the delegate stays in the same place 0047 function updateIsSelected() { 0048 selected = listView.selectionModel.rowIntersectsSelection(row); 0049 } 0050 0051 onRowChanged: { 0052 updateIsSelected(); 0053 } 0054 0055 Component.onCompleted: { 0056 updateIsSelected(); 0057 } 0058 0059 background: Rectangle { 0060 // Background for highlighted / hovered / active items 0061 Rectangle { 0062 id: background 0063 anchors.fill: parent 0064 color: feedDelegate.checked || feedDelegate.highlighted || (feedDelegate.supportsMouseEvents && feedDelegate.pressed) 0065 ? feedDelegate.activeBackgroundColor 0066 : Kirigami.Theme.backgroundColor 0067 0068 Rectangle { 0069 id: internal 0070 property bool indicateActiveFocus: feedDelegate.pressed || Kirigami.Settings.tabletMode || feedDelegate.activeFocus || (feedDelegate.ListView.view ? feedDelegate.ListView.view.activeFocus : false) 0071 anchors.fill: parent 0072 visible: !Kirigami.Settings.tabletMode && feedDelegate.hoverEnabled 0073 color: feedDelegate.activeBackgroundColor 0074 opacity: (feedDelegate.hovered || feedDelegate.highlighted || feedDelegate.activeFocus) && !feedDelegate.pressed ? 0.5 : 0 0075 } 0076 } 0077 0078 Kirigami.ShadowedRectangle { 0079 anchors.fill: parent 0080 anchors.margins: cardMargin 0081 anchors.leftMargin: cardMargin 0082 color: Kirigami.Theme.backgroundColor 0083 0084 radius: Kirigami.Units.smallSpacing 0085 0086 shadow.size: Kirigami.Units.largeSpacing 0087 shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.15) 0088 shadow.yOffset: borderWidth * 2 0089 0090 border.width: borderWidth 0091 border.color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(color.r, color.g, color.b, 0.6)) 0092 } 0093 } 0094 0095 contentItem: MouseArea { 0096 id: mouseArea 0097 anchors.fill: parent 0098 anchors.margins: cardMargin + borderWidth 0099 implicitWidth: cardSize - 2 * borderWidth 0100 implicitHeight: cardSize - 2 * borderWidth 0101 0102 acceptedButtons: Qt.LeftButton | Qt.RightButton 0103 onClicked: (mouse) => { 0104 // Keep track of (currently) selected items 0105 var modelIndex = feedDelegate.listView.model.index(index, 0); 0106 0107 if (feedDelegate.listView.selectionModel.isSelected(modelIndex) && mouse.button == Qt.RightButton) { 0108 feedDelegate.listView.contextMenu.popup(null, mouse.x+1, mouse.y+1); 0109 } else if (mouse.modifiers & Qt.ShiftModifier) { 0110 // Have to take a detour through c++ since selecting large sets 0111 // in QML is extremely slow 0112 feedDelegate.listView.selectionModel.select(feedDelegate.listView.model.createSelection(modelIndex.row, feedDelegate.listView.selectionModel.currentIndex.row), ItemSelectionModel.ClearAndSelect | ItemSelectionModel.Rows); 0113 } else if (mouse.modifiers & Qt.ControlModifier) { 0114 feedDelegate.listView.selectionModel.select(modelIndex, ItemSelectionModel.Toggle | ItemSelectionModel.Rows); 0115 } else if (mouse.button == Qt.LeftButton) { 0116 feedDelegate.listView.currentIndex = index; 0117 feedDelegate.listView.selectionModel.setCurrentIndex(modelIndex, ItemSelectionModel.ClearAndSelect | ItemSelectionModel.Rows); 0118 feedDelegate.clicked(); 0119 } else if (mouse.button == Qt.RightButton) { 0120 // This item is right-clicked, but isn't selected 0121 feedDelegate.listView.selectionForContextMenu = [modelIndex]; 0122 feedDelegate.listView.contextMenu.popup(null, mouse.x+1, mouse.y+1); 0123 } 0124 } 0125 0126 onPressAndHold: { 0127 var modelIndex = feedDelegate.listView.model.index(index, 0); 0128 feedDelegate.listView.selectionModel.select(modelIndex, ItemSelectionModel.Toggle | ItemSelectionModel.Rows); 0129 } 0130 0131 Connections { 0132 target: listView.selectionModel 0133 function onSelectionChanged() { 0134 updateIsSelected(); 0135 } 0136 } 0137 0138 Connections { 0139 target: listView.model 0140 function onLayoutAboutToBeChanged() { 0141 if (feedList.currentItem === feedDelegate) { 0142 isCurrentItem = true; 0143 currentItemUrl = feed.url; 0144 } else { 0145 isCurrentItem = false; 0146 currentItemUrl = ""; 0147 } 0148 } 0149 function onLayoutChanged() { 0150 updateIsSelected(); 0151 if (isCurrentItem) { 0152 // yet another hack because "index" is still giving the old 0153 // value here; so we have to manually find the new index. 0154 for (var i = 0; i < feedList.model.rowCount(); i++) { 0155 if (feedList.model.data(feedList.model.index(i, 0), FeedsModel.UrlRole) == currentItemUrl) { 0156 feedList.currentIndex = i; 0157 } 0158 } 0159 } 0160 } 0161 } 0162 0163 ImageWithFallback { 0164 id: img 0165 anchors.fill: parent 0166 imageSource: feed.cachedImage 0167 imageTitle: feed.name 0168 isLoading: feed.refreshing 0169 absoluteRadius: Kirigami.Units.smallSpacing - borderWidth 0170 } 0171 0172 Rectangle { 0173 id: countRectangle 0174 visible: countProperty > 0 0175 anchors.top: img.top 0176 anchors.right: img.right 0177 width: actionsButton.width 0178 height: actionsButton.height 0179 color: feedDelegate.activeBackgroundColor 0180 radius: Kirigami.Units.smallSpacing - 2 * borderWidth 0181 } 0182 0183 Controls.Label { 0184 id: countLabel 0185 visible: countProperty > 0 0186 anchors.centerIn: countRectangle 0187 anchors.margins: Kirigami.Units.smallSpacing 0188 text: countProperty 0189 font.bold: true 0190 color: Kirigami.Theme.highlightedTextColor 0191 } 0192 0193 Rectangle { 0194 id: actionsRectangle 0195 anchors.fill: actionsButton 0196 color: "black" 0197 opacity: 0.5 0198 radius: Kirigami.Units.smallSpacing - 2 * borderWidth 0199 } 0200 0201 Controls.Button { 0202 id: actionsButton 0203 anchors.right: img.right 0204 anchors.bottom: img.bottom 0205 anchors.margins: 0 0206 padding: 0 0207 flat: true 0208 icon.name: "overflow-menu" 0209 icon.color: "white" 0210 onClicked: actionOverlay.open() 0211 } 0212 } 0213 0214 onClicked: { 0215 lastFeed = feed.url 0216 if (pageStack.depth > 1) 0217 pageStack.pop(); 0218 pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/FeedDetailsPage.qml", {"feed": feed}) 0219 } 0220 0221 Controls.ToolTip.visible: hovered 0222 Controls.ToolTip.text: feed.name 0223 Controls.ToolTip.delay: Kirigami.Units.toolTipDelay 0224 0225 Kirigami.MenuDialog { 0226 id: actionOverlay 0227 // parent: applicationWindow().overlay 0228 showCloseButton: true 0229 0230 title: feed.name 0231 0232 actions: [ 0233 Kirigami.Action { 0234 onTriggered: { 0235 while (pageStack.depth > 1) 0236 pageStack.pop() 0237 pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/FeedDetailsPage.qml", {"feed": feed}); 0238 } 0239 icon.name: "documentinfo" 0240 text: i18n("Podcast Details") 0241 }, 0242 Kirigami.Action { 0243 onTriggered: { 0244 if (feed.url === lastFeed) 0245 while(pageStack.depth > 1) 0246 pageStack.pop() 0247 DataManager.removeFeed(feed) 0248 } 0249 icon.name: "delete" 0250 text: i18n("Remove Podcast") 0251 } 0252 ] 0253 } 0254 }