Kirigami-addons

AbstractTable.qml
1/*
2 * Copyright 2023 Evgeny Chesnokov <echesnokov@astralinux.ru>
3 * SPDX-License-Identifier: LGPL-2.0-or-later
4 */
5
6import QtQuick
7import QtQuick.Controls as QQC2
8
9import org.kde.kirigami as Kirigami
10
11Flickable {
12 id: root
13
14 Accessible.role: Accessible.Table
15 interactive: false
16 focus: true
17
18 /**
19 * @brief This property holds the model that provides data for the table.
20 *
21 * The model provides the set of data that is used to create the items in the view.
22 */
23 property var model
24
25 /**
26 * @brief The default property that stores the components for forming the columns of this table.
27 *
28 * @property list<AbstractHeaderComponent> headerComponents
29 * @see org::kde::kirigamiaddons::AbstractHeaderComponent
30 */
31 property list<AbstractHeaderComponent> headerComponents
32 onHeaderComponentsChanged: updateModel()
33
34 /**
35 * @brief This property holds the number of rows in the view
36 */
37 readonly property int rowCount: __rowCount
38
39 /**
40 * @brief This property holds the number of columns in the component include invisibles
41 */
42 readonly property int columnCount: __columnCount
43
44 /**
45 * @brief This property controls whether the background color of the rows should alternate.
46 *
47 * default: `true`
48 */
49 property bool alternatingRows: true
50
51
52 /**
53 * @brief If this property is enabled, the table will be displayed in a compact form.
54 *
55 * default: `true`
56 */
57 property bool compact: true
58
59 /**
60 * @brief Is a link to a list of context menu items.
61 *
62 * @see QtQuick.Controls.Menu
63 */
64 property alias actions: menu.contentData
65
66 /**
67 * @brief The property is responsible for the direction in which sorting will be performed.
68 *
69 * @note You must implement sorting yourself for this property to be valid.
70 * @see sortRole
71 *
72 * @property Qt::SortOrder sortOrder
73 */
74 property int sortOrder
75
76 /**
77 * @brief This property specifies based on which role the table will be sorted.
78 *
79 * @note You must implement sorting yourself for this property to be valid.
80 * @see sortOrder
81 */
82 property int sortRole: -1
83
84 /**
85 * @brief This property can be set to control which delegate items should be shown as selected, and which item should be shown as current.
86 *
87 * Using the selectionType and selectionMode properties you can adjust the selection behavior
88 *
89 * @property ItemSelectionModel selectionModel
90 *
91 * @see selectionType
92 * @see selectionMode
93 */
94 property ItemSelectionModel selectionModel: ItemSelectionModel { model: root.model }
95
96 /**
97 * @brief This property holds whether the user can select cells, rows or columns.
98 *
99 * default: `TableView.SelectRows`
100 *
101 * @see TableView.selectionBehavior
102 */
103 property int selectionBehavior: TableView.SelectRows
104
105 /**
106 * @brief If `selectionType` is set to TableView.SelectCells, this property holds whether the user can select one cell at a time, or multiple cells.
107 * If `selectionType` is set to TableView.SelectRows, this property holds whether the user can select one row at a time, or multiple rows.
108 * If `selectionType` is set to TableView.SelectColumns, this property holds whether the user can select one column at a time, or multiple columns.
109 *
110 * default: `TableView.ExtendedSelection`
111 *
112 * @see TableView.selectionMode
113 */
114 property int selectionMode: TableView.ExtendedSelection
115
116 signal columnClicked(int column, var headerComponent)
117 signal columnDoubleClicked(int column, var headerComponent)
118
119 signal rowClicked(int row)
120 signal rowDoubleClicked(int row)
121
122 readonly property var __columnModel: ListModel { id: columnModel }
123 readonly property real __rowHeight: root.compact ? Kirigami.Units.gridUnit * 2
124 : Kirigami.Units.gridUnit * 3
125
126 property int __rowCount
127 property int __columnCount: columnModel.count
128
129 property bool __isControlModifier: false
130 property bool __isShiftModifier: false
131
132 Keys.onPressed: function(event) {
133 __isControlModifier = event.modifiers & Qt.ControlModifier
134 __isShiftModifier = event.modifiers & Qt.ShiftModifier
135 }
136
137 Keys.onReleased: function(event) {
138 __isControlModifier = event.modifiers & Qt.ControlModifier
139 __isShiftModifier = event.modifiers & Qt.ShiftModifier
140 }
141
142 onRowClicked: function(row) {
143 __selectCell(row, 0);
144 }
145
146 QQC2.Menu { id: menu }
147
148 MouseArea {
149 z: -2
150 anchors.fill: parent
151 propagateComposedEvents: true
152 acceptedButtons: Qt.RightButton
153 onClicked: function(mouse) {
154 root.forceActiveFocus();
155 if (mouse.button === Qt.RightButton) {
156 if (menu.count > 0) {
157 menu.x = mouse.x
158 menu.y = mouse.y
159 menu.open()
160 mouse.accepted = true
161 return;
162 }
163 }
164
165 mouse.accepted = false
166 }
167 }
168
169 function updateModel(): void {
170 __columnModel.clear();
171 for(let index = 0; index < root.headerComponents.length; index++) {
172 let object = root.headerComponents[index];
173
174 if (object instanceof AbstractHeaderComponent && object.visible) {
175 __columnModel.append({ headerComponent: object });
176 }
177 }
178 }
179
180 function __columnsContentWidth(): real {
181 let contentWidth = 0
182
183 for(let index = 0; index < __columnModel.count; index++) {
184 let column = __columnModel.get(index).headerComponent;
185
186 if (column.visible) {
187 contentWidth += column.width;
188 }
189 }
190
191 return contentWidth
192 }
193
194 function __columnWidth(column: int, explicitWidth: real): real {
195 const columnItem = root.__columnModel.get(column).headerComponent;
196 if (!columnItem.resizable) {
197 return columnItem.width;
198 }
199
200 if (explicitWidth > 0) {
201 if (explicitWidth < columnItem.minimumWidth) {
202 return columnItem.minimumWidth;
203 }
204
205 return explicitWidth;
206 }
207
208 return columnItem.width;
209 }
210
211 function __selectCell(row: int, column: int): void {
212 if (!root.selectionModel || root.selectionBehavior === TableView.SelectionDisabled) {
213 return;
214 }
215
216 const modelIndex = root.model.index(row, column);
217
218 if (__isControlModifier && root.selectionMode !== TableView.SingleSelection) {
219 root.selectionModel.setCurrentIndex(modelIndex, ItemSelectionModel.Toggle);
220
221 if (!root.selectionModel.hasSelection) {
222 root.selectionModel.clearSelection();
223 root.selectionModel.clearCurrentIndex();
224 }
225
226 return;
227 }
228
229 if (__isShiftModifier && root.selectionMode !== TableView.SingleSelection) {
230 const currentIndex = root.selectionModel.currentIndex;
231
232 const startRow = Math.min(row, currentIndex.row);
233 const endRow = Math.max(row, currentIndex.row);
234 const startColumn = Math.min(column, currentIndex.column);
235 const endColumn = Math.max(column, currentIndex.column);
236
237 for (let _row = startRow; _row <= endRow; _row++) {
238 for (let _column = startColumn; _column <= endColumn; _column++) {
239 root.selectionModel.select(root.model.index(_row, _column), ItemSelectionModel.Select);
240 }
241 }
242
243 return;
244 }
245
246 root.selectionModel.setCurrentIndex(modelIndex, ItemSelectionModel.ClearAndSelect);
247 }
248
249 function __selectRow(row: int): void {
250 for (let column = 0; column < root.__columnCount; column++) {
251 __selectCell(row, column);
252 }
253 }
254
255 function __selectColumn(column: int): void {
256 for (let row = 0; row < root.__rowCount; row++) {
257 __selectCell(row, column);
258 }
259 }
260}
Abstract header component.
KIOCORE_EXPORT TransferJob * get(const QUrl &url, LoadType reload=NoReload, JobFlags flags=DefaultFlags)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 10 2024 11:50:14 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.