MauiKit Controls

GridBrowser.qml
1/*
2 * Copyright 2018 Camilo Higuita <milo.h@aol.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20import QtQuick
21import QtQuick.Controls
22
23import org.mauikit.controls as Maui
24
25/**
26 * @inherit QtQuick.Item
27 * @brief A browser view with a grid layout.
28 *
29 * <a href="https://doc.qt.io/qt-6/qml-qtquick-controls-item.html">This controls inherits from QQC2 Item, to checkout its inherited properties refer to the Qt Docs.</a>
30 *
31 * This component might seem similar to QQC2 GridView - and it does uses it underneath - but this one includes a few more predefined elements, such as auto adaptable uniform cell width, a placeholder element, pinch to zoom gestures, and lasso selection support.
32 *
33 * @section structure Structure
34 * The browser has a dedicated placeholder element handled by MauiKit Holder, where a message can be set when the view is on a determined state the user should be warned about, such as if the view is empty, or not search results were found.
35 * @see Holder
36 *
37 * The lasso selection feature works with a mouse or a track-pad, and allows to select multiple items in the browser-view that are under the lasso rectangle area. A signal is emitted when the selection has been triggered - this is when the lasso rectangle is released - sending as an argument an array of numbers representing the indexes of the selected items.
38 * @see itemsSelected
39 *
40 * @image html Browsers/gridbrowser_resize.gif "The GridBrowser with adaptable content enabled"
41 *
42 * @note Notice the yellow rectangles vs the grey ones. The yellow rectangles will preserve the `itemSize` dimensions, while the cell area, represented by the gray rectangle, will vary. The example below demonstrates this behavior.
43 *
44 * @section notes Notes
45 * Use the `itemSize` property to set an uniform size for the cell item. At first the `cellWidth` will have the same value as the `itemSize`.
46 *
47 * If the `adaptContent` is enabled, the cell width will vary, while the cell height will maintain the same value as the `itemSize`.
48 * @see adaptContent
49 *
50 * When the view is resized and the `adaptContent` is enabled, the cell width - `cellWidth` - values will be updated to a value that can fill the width of the view-port uniformly. The modified values of the `cellWidth` will never be less than the value defined in the `itemSize` property.
51 * @see itemSize
52 *
53 * @warning Keep in mind that the `cellWidth` values will be modified when enabling the `adaptContent` property. So any binding to this property will break.
54 *
55 * @code
56 * Maui.Page
57 * {
58 * id: _page
59 * anchors.fill: parent
60 * Maui.Controls.showCSD: true
61 * headBar.forceCenterMiddleContent: true
62 *
63 * headBar.leftContent: Switch
64 * {
65 * text: "Adapt Content"
66 * checked: _gridBrowser.adaptContent
67 * onToggled: _gridBrowser.adaptContent = !_gridBrowser.adaptContent
68 * }
69 *
70 * Maui.GridBrowser
71 * {
72 * id: _gridBrowser
73 * anchors.fill: parent
74 * model: 30
75 *
76 * itemSize: 200
77 * itemHeight: 300
78 *
79 * adaptContent: true
80 *
81 * delegate: Rectangle
82 * {
83 * width: GridView.view.cellWidth
84 * height: GridView.view.cellHeight
85 * color: "gray"
86 * border.color: "white"
87 *
88 * Rectangle
89 * {
90 * width: _gridBrowser.itemSize
91 * height: _gridBrowser.itemSize
92 *
93 * color: "yellow"
94 *
95 * anchors.centerIn: parent
96 * }
97 * }
98 * }
99 * }
100 * @endcode
101 *
102 * @note You can use the GridView attached properties to refer to the control properties from the delegates. For example, you could use `GridView.view.itemSize` or GridView.view.cellWidth`. *
103 *
104 * @image html Browsers/gridbrowser_alt.png "The GridBrowser with adaptable content disabled"
105 *
106 * @note Notice the yellow rectangles vs the grey ones. The yellow rectangles will preserve the `itemSize` dimensions, and the cell width - as the gray area- will also keep the same dimensions as `itemSize`.
107 *
108 * <a href="https://invent.kde.org/maui/mauikit/-/blob/qt6-2/examples/GridBrowser.qml">You can find a more complete example at this link.</a>
109 */
110Item
111{
112 id: control
113 focus: true
114 clip: false
115
116 implicitHeight: contentHeight + topPadding + bottomPadding
117 implicitWidth: contentWidth + leftPadding + rightPadding
118
119 /**
120 * @brief The uniform size of the element in the cell. This value is used for the width and height. This value will stay the same even when the width of the cell changes.
121 *
122 * The dimensions of the item can be changed manually for its height and its width.
123 * @see itemHeight
124 * @see itemWidth
125 *
126 * @note This is meant to set an initial uniform size, so notice this value will be use for the `cellWidth`, `cellHeight`, `itemHeight` and `itemWidth`.
127 *
128 * @property int GridBrowser::itemSize
129 */
130 property alias itemSize: controlView.itemSize
131
132 /**
133 * @brief The width of the element in the cell. This value will vary even if `adaptContent` is enabled.
134 * This value is used as the `cellWidth` value by default.
135 * @property int GridBrowser::itemWidth
136 */
137 property alias itemWidth : controlView.itemWidth
138
139 /**
140 * @brief The height of the element in the cell. This value will vary even if `adaptContent` is enabled.
141 * This value is used as the `cellHeight` value by default.
142 * @property int GridBrowser::itemHeight
143 */
144 property alias itemHeight : controlView.itemHeight
145
146 /**
147 * @brief The width size of the cell area.
148 *
149 * @warning This value will be modified when the viewport area is resized and the `adaptContent` is enabled. So any binding will be lost. To have a fixed cell width value, set `adaptContent: false`.
150 * @see adaptContent
151 * @property int GridBrowser::cellWidth
152 */
153 property alias cellWidth: controlView.cellWidth
154
155 /**
156 * @brief The height size of the cell area.
157 * This value is set to the `itemHeight` value, or `itemSize` if the formerly one has not been set.
158 * This value will not be modified by the adaptable behaviour.
159 * Notice you can make the cell bigger than the itemHeight, in order to create a sense of vertical padding for each cell element.
160 * @property int GridBrowser::cellHeight
161 */
162 property alias cellHeight: controlView.cellHeight
164 /**
165 * @brief The model to be used to populate the browsing view.
166 * @property var GridBrowser::model
167 */
168 property alias model : controlView.model
169
170 /**
171 * @brief The component to be used as the delegate.
172 * @note Consider using the MauiKit delegate controls, such as GridBrowserDelegate, GalleryRollItem or CollageItem.
173 * @property Component GridBrowser::delegate
174 */
175 property alias delegate : controlView.delegate
176
177 /**
178 * @brief The position of the view contents on the Y axis.
179 * @property double GridBrowser::contentY
180 */
181 property alias contentY: controlView.contentY
182
183 /**
184 * @brief The index number of the current element selected.
185 * @property int GridBrowser::currentIndex
186 */
187 property alias currentIndex : controlView.currentIndex
188
189 /**
190 * @brief The total amount of elements listed in the view.
191 * @property int GridBrowser::count
192 */
193 property alias count : controlView.count
194
195 /**
196 * @brief The cache buffer.
197 * Refer to the QQC2 GridView documentation.
198 * @property int GridBrowser::cacheBuffer
199 */
200 property alias cacheBuffer : controlView.cacheBuffer
201
202 /**
203 * @brief The element controlling the layout fo element, AKA the flickable element.
204 * This is an alias to the QQC2 GridView control.
205 * @property GridView GridBrowser::flickable
206 */
207 property alias flickable : controlView
208
209 /**
210 * @brief The total height of all the elements listed in the view.
211 * @property int GridBrowser::contentHeight
212 */
213 property alias contentHeight : controlView.contentHeight
214
215 /**
216 * @brief The total width of all the elements.
217 * @property int GridBrowser::contentWidth
218 */
219 property alias contentWidth : controlView.contentWidth
220
221 /**
222 * @brief An alias to the QQC2 ScrollView element attached to the view.
223 * @property ScrollView GridBrowser::scrollView
224 */
225 property alias scrollView: _scrollView
226
227 /**
228 * @brief Top padding of the view. This padding is added to the scroll view container.
229 * @see scrollView
230 * @property int GridBrowser::topPadding
231 */
232 property alias topPadding: _scrollView.topPadding
233
234 /**
235 * @brief Bottom padding of the view. This padding is added to the scroll view container.
236 * @see scrollView
237 * @property int GridBrowser::bottomPadding
238 */
239 property alias bottomPadding: _scrollView.bottomPadding
240
241 /**
242 * @brief Right padding of the view. This padding is added to the scroll view container.
243 * @see scrollView
244 * @property int GridBrowser::rightPadding
245 */
246 property alias rightPadding: _scrollView.rightPadding
247
248 /**
249 * @brief Left padding of the view. This padding is added to the scroll view container.
250 * @see scrollView
251 * @property int GridBrowser::leftPadding
252 */
253 property alias leftPadding: _scrollView.leftPadding
254
255 /**
256 * @brief Padding of the view. This padding is added to the scroll view container.
257 * @see scrollView
258 * @property int GridBrowser::padding
259 */
260 property alias padding: _scrollView.padding
261
262 /**
263 * @brief The policy of the vertical scroll bar from the scroll view.
264 * @see scrollView
265 * The default value of this is picked based on the Style property `Style.scrollBarPolicy`, unless the orientation of the view is set to horizontal, in which case this is set to 'ScrollBar.AlwaysOff`.
266 * Possible values are:
267 * - ScrollBar.AlwaysOff
268 * - ScrollBar.AlwaysOn
269 * - ScrollBar.AsNeeded
270 */
271 property int verticalScrollBarPolicy:
272 {
273 if(control.orientation === GridView.Horizontal)
274 return ScrollBar.AlwaysOff
275
276 switch(Maui.Style.scrollBarPolicy)
278 case Maui.Style.AlwaysOn: return ScrollBar.AlwaysOn;
279 case Maui.Style.AlwaysOff: return ScrollBar.AlwaysOff;
280 case Maui.Style.AsNeeded: return ScrollBar.AsNeeded;
281 case Maui.Style.AutoHide: return ScrollBar.AsNeeded;
282 }
283 }
284
285 /**
286 * @brief The policy of the horizontal scroll bar from the scroll view.
287 * @see scrollView
288 * The default value of this is picked based on the Style property `Style.scrollBarPolicy`, unless the orientation of the view is set to vertical, in which case this is set to 'ScrollBar.AlwaysOff`.
289 * Possible values are:
290 * - ScrollBar.AlwaysOff
291 * - ScrollBar.AlwaysOn
292 * - ScrollBar.AsNeeded
293 */
294 property int horizontalScrollBarPolicy:
295 {
296 if(control.orientation === GridView.Vertical)
297 return ScrollBar.AlwaysOff
298
299 switch(Maui.Style.scrollBarPolicy)
300 {
301 case Maui.Style.AlwaysOn: return ScrollBar.AlwaysOn;
302 case Maui.Style.AlwaysOff: return ScrollBar.AlwaysOff;
303 case Maui.Style.AsNeeded: return ScrollBar.AsNeeded;
304 case Maui.Style.AutoHide: return ScrollBar.AsNeeded;
305 }
306 }
307
308 /**
309 * @brief An alias to access the placeholder properties. This is handled by a MauiKit Holder.
310 * @see Holder::title
311 * @see Holder::body
312 *
313 * @property Holder GridBrowser::holder
314 */
315 property alias holder : _holder
316
317 /**
318 * @brief Whether the width value of the cells should be recalculated when the view-port is resized. This will result in a uniform set of cells. The minimum width of the cells is constrained by the `itemSize` property.
319 * By default this is set to `true`.
320 */
321 property bool adaptContent: true
322 onAdaptContentChanged:
323 {
324 if(adaptContent)
325 control.adaptGrid()
326 else
327 control.resetCellWidth()
328 }
330 /**
331 * @brief Whether to enable the lasso selection, to select multiple items.
332 * By default this is set to `false`.
333 * @see itemsSelected
334 */
335 property bool enableLassoSelection : false
336
337 /**
338 * @brief
339 */
340 property bool selectionMode: false
341
342 /**
343 * @brief An alias to the lasso rectangle.
344 * @property Rectangle GridBrowser::lassoRec
345 */
346 readonly property alias lassoRec : selectLayer
347
348 /**
349 * @brief Whether the pinch-to-zoom gesture is enabled.
350 * By default this is set to `false`.
351 */
352 property bool pinchEnabled : false
353
354 /**
355 * @brief The current item selected.
356 * @property Item GridBrowser::currentItem
357 */
358 property alias currentItem : controlView.currentItem
359
360 /**
361 * @brief The header section of the GridView element.
362 * @see flickable
363 * @property Component GridBrowser::header
364 */
365 property alias header : controlView.header
366
367 /**
368 * @brief The footer section of the GridView element
369 * @see flickable
370 * @property Component GridBrowser::footer
371 */
372 property alias footer : controlView.footer
373
374 /**
375 * @brief The actual width of the view-port. This is the actual width without any padding.
376 * @property int GridBrowser::availableWidth
377 */
378 readonly property alias availableWidth: controlView.width
379
380 /**
381 * @brief The actual height of the view-port. This is the actual height without any padding.
382 * @property int GridBrowser::availableHeight
383 */
384 readonly property alias availableHeight: controlView.height
385
386 /**
387 * @brief Whether the view is moving horizontally or vertically. This reacts to changes in the content Y and/or X axis.
388 * @see contentY
389 * @see contentX
390 * @property bool GridBrowser::moving
391 */
392 readonly property alias moving: updateContentDelay.running
393
394 /**
395 * @brief Emitted when the lasso selection has been released.
396 * @param indexes A array of index numbers is sent as the argument, representing the index value of the items under the lasso rectangle area.
397 */
398 signal itemsSelected(var indexes)
399
400 /**
401 * @brief Emitted when an empty space of the background area has been clicked.
402 * @param mouse Object with information about the click event.
403 */
404 signal areaClicked(var mouse)
405
406 /**
407 * @brief Emitted when an empty space of the area area background has been right clicked.
408 */
409 signal areaRightClicked()
410
411 /**
412 * @brief Emitted when a physical key from the device has been pressed.
413 * @param event The object with information about the event.
414 */
415 signal keyPress(var event)
416
417 Keys.enabled : true
418 Keys.forwardTo : controlView
419
420 onItemSizeChanged :
421 {
422 controlView.size_ = itemSize
423 control.itemWidth = itemSize
424 control.cellWidth = itemWidth
425 if(adaptContent)
426 control.adaptGrid()
427 }
428
430 {
431 id: _scrollView
432 anchors.fill: parent
433 focus: true
434 padding: Maui.Style.contentMargins
435
436 clip: control.clip
437
438 ScrollBar.horizontal.policy: control.horizontalScrollBarPolicy
439 ScrollBar.vertical.policy: control.verticalScrollBarPolicy
440
441 contentHeight: controlView.contentHeight
442 contentWidth: availableWidth
443
445 {
446 id: controlView
447 focus: true
448
449 /**
450 * itemSize : int
451 */
452 property int itemSize: 0
453
454 /**
455 * itemWidth : int
456 */
457 property int itemWidth : itemSize
458
459 /**
460 * itemHeight : int
461 */
462 property int itemHeight : itemSize
463
464
465 property bool firstSelectionPress
466 property var selectedIndexes : []
467
468 //nasty trick
469 property int size_
470 Component.onCompleted:
471 {
472 controlView.size_ = control.itemWidth
473 }
474
475 flow: GridView.FlowLeftToRight
476 clip: control.clip
477
478 displayMarginBeginning: Maui.Style.effectsEnabled ? Maui.Style.toolBarHeight * 4 : 0
479 displayMarginEnd: displayMarginBeginning
480 cacheBuffer: control.itemHeight * 4
481
482 cellWidth: control.itemWidth
483 cellHeight: control.itemHeight
484
485 boundsBehavior: Flickable.StopAtBounds
486
487 flickableDirection: Flickable.AutoFlickDirection
488 snapMode: GridView.NoSnap
489 highlightMoveDuration: 0
490
491 interactive: Maui.Handy.isTouch
492
493 onWidthChanged: if(adaptContent) control.adaptGrid()
494 onCountChanged: if(adaptContent) control.adaptGrid()
495
496 keyNavigationEnabled : true
497 keyNavigationWraps : true
498
499 Keys.onPressed: (event) =>
500 {
501 control.keyPress(event)
502 }
503
504 Maui.Holder
505 {
506 id: _holder
507 visible: false
508 anchors.fill : parent
509 anchors.topMargin: controlView.headerItem ? controlView.headerItem.height : 0
510 anchors.bottomMargin: controlView.footerItem ? controlView.footerItem.height : 0
511 }
512
513 onContentXChanged:
514 {
515 updateContentDelay.restart()
516 }
517
518 onContentYChanged:
519 {
520 updateContentDelay.restart()
521 }
522
523 Timer
524 {
525 id: updateContentDelay
526 interval: 500
527 repeat: false
528 }
529
530 Loader
531 {
532 asynchronous: true
533 active: control.pinchEnabled
534
535 anchors.fill: parent
536 z: -1
537
538 sourceComponent: PinchArea
539 {
540 onPinchFinished: (pinch) =>
541 {
542 resizeContent(pinch.scale)
543 }
544 }
545 }
546
547 Loader
548 {
549 asynchronous: true
550 // active: !Maui.Handy.hasTransientTouchInput && !Maui.Handy.isMobile
551 anchors.fill: parent
552 z: parent.z-1
553 clip: false
554
555 sourceComponent: MouseArea
556 {
557 id: _mouseArea
558
559 propagateComposedEvents: true
560 preventStealing: true
561 acceptedButtons: Qt.RightButton | Qt.LeftButton
562
563 onClicked: (mouse) =>
564 {
565 console.log("Area clicked")
566 control.areaClicked(mouse)
567 control.forceActiveFocus()
568
569 if(mouse.button === Qt.RightButton)
570 {
571 control.areaRightClicked()
572 return
573 }
574 }
575
576 onWheel: (wheel) =>
577 {
578 if (wheel.modifiers & Qt.ControlModifier)
579 {
580 if (wheel.angleDelta.y != 0)
581 {
582 var factor = 1 + wheel.angleDelta.y / 600;
583 control.resizeContent(factor)
584 }
585 }else
586 wheel.accepted = false
587 }
588
589 onPositionChanged: (mouse) =>
590 {
591 console.log("Area clicked >>> Moving")
592
593 if(_mouseArea.pressed && control.enableLassoSelection && selectLayer.visible)
594 {
595 if(mouseX >= selectLayer.newX)
596 {
597 selectLayer.width = (mouseX + 10) < (control.x + control.width) ? (mouseX - selectLayer.x) : selectLayer.width;
598 } else {
599 selectLayer.x = mouseX < control.x ? control.x : mouseX;
600 selectLayer.width = selectLayer.newX - selectLayer.x;
601 }
602
603 if(mouseY >= selectLayer.newY) {
604 selectLayer.height = (mouseY + 10) < (control.y + control.height) ? (mouseY - selectLayer.y) : selectLayer.height;
605 if(!controlView.atYEnd && mouseY > (control.y + control.height))
606 controlView.contentY += 10
607 } else {
608 selectLayer.y = mouseY < control.y ? control.y : mouseY;
609 selectLayer.height = selectLayer.newY - selectLayer.y;
610
611 if(!controlView.atYBeginning && selectLayer.y === 0)
612 controlView.contentY -= 10
613 }
614 }
615 }
616
617 onPressed: (mouse) =>
618 {
619 if (mouse.source === Qt.MouseEventNotSynthesized)
620 {
621 if(control.enableLassoSelection && mouse.button === Qt.LeftButton && control.count > 0)
622 {
623 selectLayer.visible = true;
624 selectLayer.x = mouseX;
625 selectLayer.y = mouseY;
626 selectLayer.newX = mouseX;
627 selectLayer.newY = mouseY;
628 selectLayer.width = 0
629 selectLayer.height = 0;
630 }
631 }
632 }
633
634 onPressAndHold: (mouse) =>
635 {
636 if ( mouse.source !== Qt.MouseEventNotSynthesized && control.enableLassoSelection && !selectLayer.visible )
637 {
638 selectLayer.visible = true;
639 selectLayer.x = mouseX;
640 selectLayer.y = mouseY;
641 selectLayer.newX = mouseX;
642 selectLayer.newY = mouseY;
643 selectLayer.width = 0
644 selectLayer.height = 0;
645
646 mouse.accepted = true
647 }else
648 {
649 mouse.accepted = false
650 }
651 }
652
653 onReleased: (mouse) =>
654 {
655 if(mouse.button !== Qt.LeftButton || !control.enableLassoSelection || !selectLayer.visible)
656 {
657 mouse.accepted = false
658 return;
659 }
660
661 if(selectLayer.y > controlView.contentHeight)
662 {
663 return selectLayer.reset();
664 }
665
666 var lassoIndexes = []
667 const limitX = mouse.x === lassoRec.x ? lassoRec.x+lassoRec.width : mouse.x
668 const limitY = mouse.y === lassoRec.y ? lassoRec.y+lassoRec.height : mouse.y
669
670 for(var i =lassoRec.x; i < limitX; i+=(lassoRec.width/(controlView.cellWidth* 0.5)))
671 {
672 for(var y = lassoRec.y; y < limitY; y+=(lassoRec.height/(controlView.cellHeight * 0.5)))
673 {
674 const index = controlView.indexAt(i,y+controlView.contentY)
675 if(!lassoIndexes.includes(index) && index>-1 && index< controlView.count)
676 lassoIndexes.push(index)
677 }
678 }
679
680 if(lassoIndexes.length > 0)
681 {
682 control.itemsSelected(lassoIndexes)
683 }
684
685 selectLayer.reset()
686 }
687 }
688 }
689
690 Maui.Rectangle
691 {
692 id: selectLayer
693 property int newX: 0
694 property int newY: 0
695 height: 0
696 width: 0
697 x: 0
698 y: 0
699 visible: false
700 color: Qt.rgba(control.Maui.Theme.highlightColor.r,control.Maui.Theme.highlightColor.g, control.Maui.Theme.highlightColor.b, 0.2)
701 opacity: 0.7
702
703 borderColor: control.Maui.Theme.highlightColor
704 borderWidth: 2
705 solidBorder: false
706
707 function reset()
708 {
709 selectLayer.x = 0;
710 selectLayer.y = 0;
711 selectLayer.newX = 0;
712 selectLayer.newY = 0;
713 selectLayer.visible = false;
714 selectLayer.width = 0;
715 selectLayer.height = 0;
716 }
717 }
718 }
719
720
721 }
722
723 /**
724 * @brief Request to resize the view elements. This will result in the `itemSize` property being modified.
725 * @param factor a factor for resizing.
726 * The minimum size is `Style.iconSizes.small`.
727 */
728 function resizeContent(factor)
729 {
730 const newSize = control.itemSize * factor
731
732 if(newSize > control.itemSize)
733 {
734 control.itemSize = newSize
735 }
736 else
737 {
738 if(newSize >= Maui.Style.iconSizes.small)
739 control.itemSize = newSize
740 }
741 }
742
743 /**
744 * @brief Forces to adapt the width of the grid cells. This will result on the `cellWidth` property being modified.
745 */
746 function adaptGrid()
747 {
748 var fullWidth = controlView.width
749 var realAmount = parseInt(fullWidth / controlView.size_, 0)
750 var amount = parseInt(fullWidth / control.cellWidth, 0)
751
752 var leftSpace = parseInt(fullWidth - ( realAmount * controlView.size_ ), 0)
753 var size = Math.min(amount, realAmount) >= control.count ? Math.max(control.cellWidth, control.itemSize) : parseInt((controlView.size_) + (parseInt(leftSpace/realAmount, 0)), 0)
754
755 control.cellWidth = size
756 }
757
758 /**
759 * @brief Resets the value of the `cellWidth` back to the initial size set with `itemSize`.
760 */
761 function resetCellWidth()
762 {
763 control.cellWidth = control.itemSize
764 }
765}
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
QAction * repeat(const QObject *recvr, const char *slot, QObject *parent)
KGuiItem reset()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:17:11 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.