Warning, /plasma/plasma-systemmonitor/src/table/BaseTableView.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 0008 import QtQuick.Controls 0009 import QtQuick.Layouts 0010 import QtQml.Models 0011 0012 import org.kde.kitemmodels as ItemModels 0013 0014 import org.kde.kirigami as Kirigami 0015 import org.kde.ksysguard.table as Table 0016 0017 FocusScope { 0018 id: root 0019 0020 property var model 0021 property alias view: tableView 0022 property alias delegate: tableView.delegate 0023 0024 property alias sortColumn: heading.sortColumn 0025 property alias sortOrder: heading.sortOrder 0026 property alias sortName: heading.sortName 0027 property alias idRole: heading.idRole 0028 0029 // Column widths in fractions of the entire view width 0030 // Since column sizes are relative to a given view width, the widths of individual 0031 // columns need to be expressed as a fraction of the entire width. columnWidths 0032 // and defaultColumnWidth both store these fractions. Note that minimumColumnWidth 0033 // is expressed as a pixel value since we do not want that to scale with view width. 0034 property var columnWidths: [] 0035 property real defaultColumnWidth: 0.1 0036 property real minimumColumnWidth: Kirigami.Units.gridUnit * 4 0037 0038 readonly property alias headerHeight: heading.height 0039 0040 readonly property alias selection: tableView.selectionModel 0041 readonly property alias rows: tableView.rows 0042 readonly property alias columns: tableView.columns 0043 0044 signal contextMenuRequested(var index, point position) 0045 signal headerContextMenuRequested(int column, point position) 0046 signal sort(int column, int order) 0047 0048 Layout.minimumHeight: heading.height + root.rowHeight * 3 0049 0050 clip: true 0051 0052 Kirigami.Theme.inherit: false 0053 Kirigami.Theme.colorSet: Kirigami.Theme.View 0054 0055 TableViewHeader { 0056 id: heading 0057 0058 view: tableView 0059 0060 width: scrollView.width 0061 0062 onSort: (column, order) => { 0063 root.sort(column, order) 0064 } 0065 0066 onResize: (column, width) => { 0067 root.setColumnWidth(column, width) 0068 } 0069 0070 onContextMenuRequested:(column, position) => { 0071 root.headerContextMenuRequested(column, position) 0072 } 0073 } 0074 0075 ScrollView { 0076 id: scrollView 0077 anchors.fill: parent 0078 anchors.topMargin: heading.height 0079 0080 property real innerWidth: LayoutMirroring.enabled ? width - leftPadding : width - rightPadding 0081 0082 background: Rectangle { color: Kirigami.Theme.backgroundColor; Kirigami.Theme.colorSet: Kirigami.Theme.View } 0083 0084 TreeView { 0085 id: tableView 0086 anchors.left: parent.left 0087 selectionModel: ItemSelectionModel { 0088 id: selectionModel 0089 model: tableView.model 0090 } 0091 property int hoveredRow: -1 0092 property int sortColumn: root.sortColumn 0093 0094 signal contextMenuRequested(var index, point position) 0095 onContextMenuRequested: (index, position) => { 0096 root.contextMenuRequested(index, position); 0097 } 0098 0099 // FIXME Until Tableview correctly reverses its columns, see QTBUG-90547 0100 model: root.model 0101 Binding on model { 0102 when: scrollView.LayoutMirroring.enabled 0103 value: Table.ReverseColumnsProxyModel { 0104 sourceModel: root.model 0105 } 0106 } 0107 0108 activeFocusOnTab: true 0109 0110 clip: true 0111 boundsBehavior: Flickable.StopAtBounds 0112 0113 Keys.onPressed: event => { 0114 switch (event.key) { 0115 case Qt.Key_Up: 0116 selectRelative(-1) 0117 if (!atYBeginning) { 0118 contentY -= root.rowHeight 0119 returnToBounds() 0120 } 0121 event.accepted = true 0122 return; 0123 case Qt.Key_Down: 0124 selectRelative(1) 0125 if (!atYEnd) { 0126 contentY += root.rowHeight 0127 returnToBounds() 0128 } 0129 event.accepted = true 0130 return; 0131 case Qt.Key_PageUp: 0132 if (!atYBeginning) { 0133 if ((contentY - (tableView.height - root.rowHeight)) < 0) { 0134 contentY = 0 0135 } else { 0136 contentY -= tableView.height - root.rowHeight // subtracting root.rowHeight so the last row still visible 0137 } 0138 returnToBounds() 0139 } 0140 return; 0141 case Qt.Key_PageDown: 0142 if (!atYEnd) { 0143 if ((contentY + (tableView.height - root.rowHeight)) > contentHeight - height) { 0144 contentY = contentHeight - height 0145 } else { 0146 contentY += tableView.height - root.rowHeight // subtracting root.rowHeight so the last row still visible 0147 } 0148 returnToBounds() 0149 } 0150 return; 0151 case Qt.Key_Home: 0152 if (!atYBeginning) { 0153 contentY = 0 0154 returnToBounds() 0155 } 0156 return; 0157 case Qt.Key_End: 0158 if (!atYEnd) { 0159 contentY = contentHeight - height 0160 returnToBounds() 0161 } 0162 return; 0163 case Qt.Key_Menu: 0164 contextMenuRequested(selectionModel.currentIndex, mapToGlobal(0, 0)) 0165 return; 0166 default: 0167 break; 0168 } 0169 if (event.matches(StandardKey.SelectAll)) { 0170 selectionModel.select(model.index(0, 0), ItemSelectionModel.ClearAndSelect | ItemSelectionModel.Columns); 0171 return; 0172 } 0173 } 0174 0175 onActiveFocusChanged: { 0176 if (activeFocus && !selectionModel.hasSelection) { 0177 selectionModel.setCurrentIndex(model.index(0, 0), ItemSelectionModel.ClearAndSelect) 0178 } 0179 } 0180 0181 function selectRelative(delta) { 0182 var nextRow = selectionModel.currentIndex.row + delta 0183 if (nextRow < 0) { 0184 nextRow = 0 0185 } 0186 if (nextRow >= rows) { 0187 nextRow = rows - 1 0188 } 0189 var index = model.index(nextRow, selectionModel.currentIndex.column) 0190 selectionModel.setCurrentIndex(index, ItemSelectionModel.ClearAndSelect | ItemSelectionModel.Rows) 0191 } 0192 0193 columnWidthProvider: function(index) { 0194 let column = index 0195 // FIXME Until Tableview correctly reverses its columns, see QTBUG-90547 0196 if (LayoutMirroring.enabled) { 0197 column = root.columnWidths.length - index - 1 0198 } 0199 0200 // Resizing sets the explicit column width and has no other trigger. If 0201 // we don't make use of that value we can't resize. So read the value, 0202 // convert it to a fraction of total width and write it back to 0203 // columnWidths, then clear the explicit column width again so that 0204 // resizing updates the column width properly. This isn't the prettiest 0205 // of solutions but at least makes things work the way we want. 0206 let explicitWidth = explicitColumnWidth(index) 0207 if (explicitWidth >= 0) { 0208 let w = explicitWidth / width 0209 root.columnWidths[column] = w 0210 root.columnWidthsChanged() 0211 clearColumnWidths() 0212 } 0213 0214 let columnWidth = root.columnWidths[column] 0215 return Math.max(Math.floor((columnWidth ?? root.defaultColumnWidth) * scrollView.innerWidth), root.minimumColumnWidth) 0216 } 0217 } 0218 } 0219 } 0220