Warning, /plasma/plasma-systemmonitor/src/table/TableViewHeader.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005  */
0006 
0007 import QtQuick 2.12
0008 import QtQuick.Controls 2.2
0009 import QtQml.Models 2.12
0010 
0011 import org.kde.kirigami 2.2 as Kirigami
0012 import org.kde.ksysguard.formatter 1.0 as Formatter
0013 
0014 import org.kde.kitemmodels 1.0 as KItemModels
0015 import org.kde.qqc2desktopstyle.private 1.0 as StylePrivate
0016 
0017 FocusScope {
0018     id: heading
0019 
0020     x: LayoutMirroring.enabled ? view.contentWidth - view.width - view.contentX : -view.contentX
0021     width: view.contentWidth
0022     height: heightHelper.height
0023 
0024     property TableView view
0025     property int sortColumn: -1
0026     property int sortOrder: Qt.AscendingOrder
0027 
0028     property string idRole: "Attribute"
0029     property string sortName
0030 
0031     property alias sourceModel: headerModel.sourceModel
0032 
0033     signal sort(int column, int order)
0034     signal resize(int column, real width)
0035     signal contextMenuRequested(int column, point position)
0036 
0037     function columnWidth(index) {
0038         return repeater.itemAt(index).width
0039     }
0040 
0041     Kirigami.Theme.inherit: false
0042     Kirigami.Theme.colorSet: Kirigami.Theme.Button
0043 
0044     StylePrivate.StyleItem {
0045         anchors.fill: parent
0046         elementType: "header"
0047         raised: false
0048         sunken: false
0049         properties: {
0050             "headerpos": LayoutMirroring.enabled ? "beginning" : "end"
0051         }
0052     }
0053 
0054     Kirigami.BasicListItem {
0055         id: heightHelper
0056         text: "Placeholder"
0057         visible: false
0058     }
0059 
0060     activeFocusOnTab: true
0061 
0062     function focusNext(delta) {
0063         var newIndex = headerRow.currentIndex
0064         var item = undefined
0065         while (item === undefined || item instanceof Repeater) {
0066             newIndex = newIndex + delta
0067 
0068             if (newIndex < 0) {
0069                 newIndex = headerRow.children.length - 1
0070             }
0071             if (newIndex >= headerRow.children.length) {
0072                 newIndex = 0
0073             }
0074 
0075             item = headerRow.children[newIndex]
0076         }
0077 
0078         item.focus = true
0079         headerRow.currentIndex = newIndex
0080     }
0081 
0082     Row {
0083         id: headerRow
0084         anchors.left: parent.left
0085         anchors.leftMargin: LayoutMirroring.enabled ? view.contentWidth - width : 0
0086         property int currentIndex: 0
0087 
0088         Repeater {
0089             id: repeater
0090 
0091             model: KItemModels.KColumnHeadersModel {
0092                 id: headerModel
0093                 sourceModel: heading.view.model
0094             }
0095 
0096             delegate: StylePrivate.StyleItem {
0097                 id: headerItem
0098                 // FIXME Need to reverse the index order until TableView correctly supports it itself, see QTBUG-90547
0099                 width: heading.view.columnWidthProvider(LayoutMirroring.enabled ? repeater.count - model.row - 1 : model.row)
0100                 height: heightHelper.height
0101                 enabled: width > 0
0102 
0103                 property string headerPosition: {
0104                     if (repeater.count === 1) {
0105                         return "only";
0106                     }
0107                     if (index == 0) {
0108                         return LayoutMirroring.enabled ? "end" : "beginning"
0109                     }
0110                     return "middle"
0111                 }
0112 
0113                 property string columnId: model[heading.idRole] !== undefined ? model[heading.idRole] : ""
0114 
0115                 elementType: "header"
0116                 activeControl: heading.sortName == columnId ? (heading.sortOrder == Qt.AscendingOrder ? "down" : "up") : ""
0117                 raised: false
0118                 sunken: mouse.pressed || activeFocus
0119                 text: model.display != undefined ? model.display : ""
0120                 hover: mouse.containsMouse
0121 
0122                 focus: true
0123 
0124                 properties: {
0125                     "headerpos": headerPosition,
0126                     "textalignment": Text.AlignHCenter
0127                 }
0128 
0129                 Keys.onPressed: {
0130                     switch (event.key) {
0131                         case Qt.Key_Space:
0132                         case Qt.Key_Enter:
0133                         case Qt.Key_Return:
0134                             toggleSort()
0135                             break;
0136                         case Qt.Key_Menu:
0137                             heading.contextMenuRequested(model.row, mapToGlobal(headerItem.x, headerItem.y + headerItem.height))
0138                             break
0139                         case Qt.Key_Left:
0140                             heading.focusNext(-1)
0141                             break
0142                         case Qt.Key_Right:
0143                             heading.focusNext(1)
0144                             break
0145                         default:
0146                             break;
0147                     }
0148                 }
0149 
0150                 function toggleSort() {
0151                     if (heading.sortName == headerItem.columnId) {
0152                         sort(heading.sortOrder == Qt.AscendingOrder ? Qt.DescendingOrder : Qt.AscendingOrder);
0153                     } else {
0154                         sort(model.Unit == Formatter.Units.UnitNone || model.Unit == Formatter.Units.UnitInvalid ? Qt.AscendingOrder : Qt.DescendingOrder);
0155                     }
0156                 }
0157 
0158                 function sort(sortOrder) {
0159                     heading.sortColumn = model.row;
0160                     heading.sortName = headerItem.columnId
0161                     heading.sortOrder = sortOrder
0162                     heading.sort(heading.sortColumn, heading.sortOrder)
0163                 }
0164 
0165                 MouseArea {
0166                     id: mouse
0167                     anchors.fill: parent
0168                     hoverEnabled: true
0169                     acceptedButtons: Qt.LeftButton | Qt.RightButton
0170 
0171                     onClicked: {
0172                         if (mouse.button == Qt.RightButton) {
0173                             heading.contextMenuRequested(model.row, mapToGlobal(mouse.x, mouse.y))
0174                             return
0175                         }
0176 
0177                         headerItem.toggleSort()
0178                     }
0179                 }
0180                 MouseArea {
0181                     id: dragHandle
0182                     property real mouseDownX
0183                     property bool dragging: false
0184                     anchors {
0185                         top: parent.top
0186                         bottom: parent.bottom
0187                         left: LayoutMirroring.enabled && !dragging ? parent.left : undefined
0188                         right: !LayoutMirroring.enabled && !dragging ? parent.right : undefined
0189                     }
0190                     drag.target: dragHandle
0191                     drag.axis: Drag.XAxis
0192                     cursorShape: enabled ? Qt.SplitHCursor : undefined
0193                     width: Kirigami.Units.smallSpacing * 2
0194                     onPressed: {
0195                         dragging = true
0196                         mouseDownX = x
0197                     }
0198                     onXChanged: {
0199                         if (!dragging) {
0200                             return
0201                         }
0202                         heading.resize(model.row, headerItem.width + (x - mouseDownX))
0203                         mouseDownX = x
0204 
0205                     }
0206                     onReleased: {
0207                         dragging = false
0208                     }
0209                 }
0210                 Component.onCompleted: {
0211                     if (heading.sortColumn == -1 && headerItem.columnId == heading.sortName) {
0212                         Qt.callLater(() => headerItem.sort(heading.sortOrder));
0213                     }
0214                 }
0215             }
0216         }
0217     }
0218 }