MauiKit Controls

TabView.qml
1import QtQuick
2import QtQml
3
4import QtQuick.Controls
5import QtQuick.Layouts
6import QtQuick.Effects
7
8import org.mauikit.controls as Maui
9
10/**
11 * @brief Container to organize items as a tab view.
12 *
13 * <a href="https://doc.qt.io/qt-6/qml-qtquick-controls-pane.html">This controls inherits from QQC2 Pane, to checkout its inherited properties refer to the Qt Docs.</a>
14 *
15 * The TabView organizes its children into different tabs - a tab for each child.
16 * There are two ways for adding tabs to this view. The first one and easier is to declare the items as children. This will create a tab for each declared child item.
17 * @see content
18 *
19 * @code
20 * TabView
21 * {
22 * Rectangle
23 * {
24 * Controls.title: "Tab1"
25 * Controls.iconName: "folder"
26 * color: "blue"
27 * }
28 *
29 * Rectangle
30 * {
31 * Controls.title: "Tab2"
32 * Controls.iconName: "folder"
33 * color: "yellow"
34 * }
35 * }
36 * @endcode
37 *
38 * The second way to create tabs dynamically by adding new items using the control functions.
39 * @see addTab
40 *
41 * @code
42 * TabView
43 * {
44 * id: _tabView
45 * tabBar.leftContent: Button
46 * {
47 * text: "Add Tab"
48 * onClicked:
49 * {
50 * _tabView.addTab(_component)
51 * }
52 * }
53 *
54 * Component
55 * {
56 * id: _component
57 * Rectangle
58 * {
59 * Controls.title: "Tab1"
60 * Controls.iconName: "folder"
61 * color: "blue"
62 * }
63 * }
64 * }
65 * @endcode
66 *
67 * @section structure Structure
68 *
69 * @note If you use this as the application window main control, remember you can use the attached Controls.showCSD property to display the window control buttons.
70 * @code
71 * TabView
72 * {
73 * Controls.showCSD : true
74 * }
75 * @endcode
76 *
77 * The TabView has two main sections, [1] the main contents area and [2] the tab bar, where the tab buttons - representing all the tab views - are listed.
78 *
79 * The tab bar listing has two "modes": one designed to fit desktop computers as a horizontal set of tab buttons; and the other one - more mobile friendly - as a grid overview of miniatures of the tab-views. Both modes can be toggle by using the mobile property.
80 * @see mobile
81 *
82 * The main tab bar - usually in the top section - can be moved to the bottom area, for better reachability.
83 * @see altTabBar
84 *
85 * The tab bar component is exposed via an alias, and items can be added to it - to the left or right side, using the leftContent or rightContent properties. This tab bar is handled by a MauiKit TabBar.
86 * @see tabBar
87 * @see TabBar
88 *
89 * @image html TabView/tabviews.png "TabView different states/sections. Further down the regular tab view with a tab bar on top, in the middle the tab view overview mode, and in the front the mobile mode with a single tab - other tab buttons can be flicked."
90 *
91 * @subsection finder Finder
92 * The TabView has an integrated dialog to quickly perform searchers for an tab.
93 *
94 * @section notes Notes
95 *
96 * @subsection tabinfo Tabs Info
97 * To add information, such as title, icon, etc, to the views, there is the `Controls` metadata attached property.
98 * Some of the available properties are:
99 * - Controls.title
100 * - Controls.toolTipText
101 * - Controls.color
102 * - Controls.iconName
103 * @see Controls
104 *
105 * @subsection menus Menus
106 * It is possible to add actions to the the tab contextual menus.
107 * @see menuActions
108 *
109 * @subsection customize Custom Tab Button
110 * It is possible to set a different tab button for the tab bar. This will allow you to have more control about how the tab button is presented. To make it easier to integrate there is a control template that can be use as a base TabViewButton - different from TabButton.
111 * @see tabViewButton
112 * @see TabViewButton
113 *
114 * @note If you plan to change the tab button, consider using TabViewButton as a base, since it already has many of the needed things by the TabView to be integrated smoothly.
115 *
116 * @subsection functionality Functionality
117 *
118 * By default when clicking/tapping on the current tab button, the overview of tabs miniatures will be opened. The overview can also be oped using the corresponding function.
119 * @see openOverview
120 * @see closeOverview
121 *
122 * <a href="https://invent.kde.org/maui/mauikit/-/blob/qt6-2/examples/TabView.qml">You can find a more complete example at this link.</a>
123 *
124 */
125Pane
126{
127 id: control
128
129 /**
130 * @brief Each one of the items declared as the children of this component will become a tab view.
131 * @property list<QtObject> TabView::content
132 */
133 default property alias content: _listView.contentData
134
135 /**
136 * @brief An alias to the model of the container.
137 * @property model TabView::contentModel
138 */
139 readonly property alias contentModel: _listView.contentModel
141 /**
142 * @brief Current index number of the current tab in the view port.
143 * @property int TabView::currentIndex
144 */
145 property alias currentIndex: _listView.currentIndex
147 /**
148 * @brief The current item/tab view in focus.
149 * @property Item TabView::currentItem
150 */
151 readonly property alias currentItem: _listView.currentItem
153 /**
154 * @brief The total amount of views in this container.
155 * @property int TabView::count
156 */
157 readonly property alias count: _listView.count
159 /**
160 * @brief An alias to a place holder text handled by a MauiKit Holder control. This is useful to display messages when there is not tab views in this container. To see how to set the message, icon and actions to it checkout the Holder documentation.
161 * @see holder
162 * @property Holder TabView::holder
163 */
164 property alias holder : _holder
165
166 /**
167 * @brief Whether the layout of the tab bar should be in mobile or desktop mode. In mobile mode there is only one tab button in the tab bar view port, other tab button can be navigated by using the touch swipe gesture. In mobile mode the main method to switch between tab views is using the overview.
168 * @see structure
169 */
170 property bool mobile : control.width <= Maui.Style.units.gridUnit * 30
171
172 /**
173 * @brief Whether the tab bar hosting the tab buttons, should go in the bottom section or not. Moving it to the bottom section is a good idea for reachability in hand-held devices, such a phones. You can check if the current platform is a mobile one using the Handy attached property `Handy.isMobile`
174 * @see Handy
175 *
176 */
177 property bool altTabBar : false
179 /**
180 * @brief Whether the view will support swipe gestures for switching between tab views.
181 */
182 property bool interactive: Maui.Handy.isTouch
183
184 /**
185 * @brief Checks if the overview mode is open.
186 */
187 readonly property bool overviewMode : _stackView.depth === 2
188
189 /**
190 * @brief An alias to the tab bar element. This is exposed so any other items can be placed on the right or left sections of it, or to fine tweak its public properties.
191 * @see TabBar
192 * @property TabBar TabView::tabBar
193 */
194 property alias tabBar: _tabBar
195
196 /**
197 * @brief An alias to the contextual menu for the tab buttons. This has a child property named index, which refers to the index number of the tab for which the contextual menu was opened.
198 * @see ContextualMenu
199 * @property ContextualMenu TabView::menu
200 */
201 property alias menu :_menu
202
203 /**
204 * @brief A set of actions can be added to the tab button contextual menu.
205 * @code
206 * TabView
207 * {
208 * id: _tabView
209 * menuActions: Action
210 * {
211 * text: "Detach Tab"
212 * onTriggered:
213 * {
214 * console.log("Detach tab at index, ", _tabView.menu.index)
215 * }
216 * }
217 * }
218 * @endcode
219 */
220 property list<Action> menuActions
221
222 /**
223 * @brief The component to be used as the tab button in the tab bar. This can be changed to any other item, but it is recommend it to use TabViewButton as the base of the new custom control for the better integration.
224 * @see TabViewButton
225 */
226 property Component tabViewButton : _tabButtonComponent
227
228 onWidthChanged: _tabBar.positionViewAtIndex(control.currentIndex)
229 onCurrentIndexChanged: _tabBar.positionViewAtIndex(control.currentIndex)
230
231 spacing: 0
232 padding: 0
233
234 Component
235 {
236 id: _tabButtonComponent
237
238 Maui.TabViewButton
239 {
240 id: _tabButton
241 tabView: control
242 closeButtonVisible: !control.mobile
243
244 onClicked:
245 {
246 if(_tabButton.mindex === control.currentIndex && control.count > 1)
248 control.openOverview()
249 return
250 }
251
252 _listView.setCurrentIndex(_tabButton.mindex)
253 _listView.itemAt(_tabButton.mindex).forceActiveFocus()
255
256 onRightClicked:
257 {
258 openTabMenu(_tabButton.mindex)
259 }
260
261 onCloseClicked:
263 control.closeTabClicked(_tabButton.mindex)
264 }
265 }
267
268 /**
269 * @brief Emitted when the new-tab button has been clicked. This is the same as catching the signal from the TabBar element itself, using the exposed alias property.
270 * @see tabBar
271 */
272 signal newTabClicked()
273
274 /**
275 * @brief Emitted when the close button has been clicked on a tab button, or tab miniature in the overview. This signal sends the index of the tab. To correctly close the tab and release the resources, use the function `closeTab()`.
276 * @param The index of the tab requested to be closed.
277 * @see closeTab
278 */
279 signal closeTabClicked(int index)
280
281 Keys.enabled: true
282 Keys.onPressed: (event) =>
283 {
284 if((event.key === Qt.Key_H) && (event.modifiers & Qt.ControlModifier))
285 {
286 control.findTab()
287 }
288 }
289
290 Maui.ContextualMenu
291 {
292 id: _menu
293 parent: control
294 property int index //tabindex
295
296 Repeater
297 {
298 model: control.menuActions
299 delegate: MenuItem
300 {
301 action: modelData
302 }
303 }
304
305 MenuItem
306 {
307 text: i18nd("mauikit", "Open")
308 icon.name: "tab-new"
309 onTriggered:
310 {
311 _listView.setCurrentIndex(_menu.index)
312 control.closeOverview()
313 }
314 }
315
316 MenuItem
317 {
318 text: i18nd("mauikit", "Close")
319 icon.name: "tab-close"
320 onTriggered:
321 {
322 control.closeTabClicked(_menu.index)
323 }
324 }
325 }
326
327 data: Loader
328 {
329 id: _loader
330 }
331
332 Component
333 {
334 id: _quickSearchComponent
335
336 Maui.PopupPage
337 {
338 id: _quickSearch
339 persistent: false
340 headBar.visible: true
341
342 onOpened: _quickSearchField.forceActiveFocus()
343
344 function find(query)
345 {
346 for(var i = 0; i < control.count; i ++)
347 {
348 var obj = _listView.contentModel.get(i)
349 if(obj.Maui.Controls.title)
350 {
351 console.log("Trying to find tab", i, query, obj.Maui.Controls.title, String(obj.Maui.Controls.title).indexOf(query))
352
353 if(String(obj.Maui.Controls.title).toLowerCase().indexOf(query.toLowerCase()) !== -1)
354 {
355 return i
356 }
357 }
358 }
359
360 return -1
361 }
362
363 Timer
364 {
365 id: _typingTimer
366 interval: 250
367 onTriggered:
368 {
369 var index = _quickSearch.find(_quickSearchField.text)
370 if(index > -1)
371 {
372 _filterTabsList.currentIndex = index
373 }
374 }
375 }
376
377 headBar.middleContent: TextField
378 {
379 id: _quickSearchField
380 Layout.fillWidth: true
381 Layout.maximumWidth: 500
382
383 onTextChanged: _typingTimer.restart()
384
385 onAccepted:
386 {
387 control.setCurrentIndex(_filterTabsList.currentIndex)
388 _quickSearch.close()
389 }
390
391 Keys.enabled: true
392
393 Keys.onPressed: (event) =>
394 {
395 if((event.key === Qt.Key_Up))
396 {
397 _filterTabsList.flickable.decrementCurrentIndex()
398 }
399
400 if((event.key === Qt.Key_Down))
401 {
402 _filterTabsList.flickable.incrementCurrentIndex()
403 }
404 }
405 }
406
407 stack: Maui.ListBrowser
408 {
409 id: _filterTabsList
410 Layout.fillWidth: true
411 Layout.fillHeight: true
412 currentIndex: _listView.currentIndex
413
414 model: _listView.count
415
416 delegate: Maui.ListDelegate
417 {
418 width: ListView.view.width
419
420 label: _listView.contentModel.get(index).Maui.Controls.title
421
422 onClicked:
423 {
424 currentIndex =index
425 _listView.setCurrentIndex(index)
426 _quickSearch.close()
427 }
428 }
429 }
430 }
431 }
432
433 contentItem: Item
434 {
435 StackView
436 {
437 anchors.fill: parent
438 id: _stackView
439
440 initialItem: Item
441 {
442 Maui.TabBar
443 {
444 id: _tabBar
445
446 z : _listView.z+1
447
448 anchors.left: parent.left
449 anchors.right: parent.right
450
451 Maui.Controls.showCSD : control.Maui.Controls.showCSD === true && position === TabBar.Header
452
453 visible: _listView.count > 1
454
455 interactive: control.interactive
456 showNewTabButton: !control.mobile
457
458 onNewTabClicked: control.newTabClicked()
459 onNewTabFocused:
460 {
461 if(control.mobile)
462 {
463 _listView.setCurrentIndex(index)
464 }
465 }
466
467 position: control.altTabBar ? TabBar.Footer : TabBar.Header
468
469 Repeater
470 {
471 model: control.count
472 delegate: control.tabViewButton
473 }
474
475 Keys.onPressed: (event) =>
476 {
477 if(event.key == Qt.Key_Return)
478 {
479 _listView.setCurrentIndex(currentIndex)
480 event.accepted = true
481 }
482
483 if(event.key == Qt.Key_Down)
484 {
485 _listView.currentItem.forceActiveFocus()
486 event.accepted = true
487 }
488 }
489
490 states: [ State
491 {
492 when: !control.altTabBar && control.tabBar.visible
493
494 AnchorChanges
495 {
496 target: _tabBar
497 anchors.top: parent.top
498 anchors.bottom: undefined
499 }
500
501 PropertyChanges
502 {
503 target: _tabBar
504 position: TabBar.Header
505 }
506 },
507
508 State
509 {
510 when: control.altTabBar && control.tabBar.visible
511
512 AnchorChanges
513 {
514 target: _tabBar
515 anchors.top: undefined
516 anchors.bottom: parent.bottom
517 }
518
519 PropertyChanges
520 {
521 target: _tabBar
522 position: TabBar.Footer
523 }
524 } ]
525 }
526
527 SwipeView
528 {
529 id: _listView
530 anchors.fill: parent
531
532 anchors.bottomMargin: control.altTabBar && _tabBar.visible ? _tabBar.height : 0
533 anchors.topMargin: !control.altTabBar && _tabBar.visible ? _tabBar.height : 0
534
535 interactive: false
536
537 spacing: control.spacing
538
539 clip: control.clip
540
541 orientation: ListView.Horizontal
542 background: null
543
544 contentItem: ListView
545 {
546 id: _listView2
547 model: _listView.contentModel
548 interactive: false
549 currentIndex: _listView.currentIndex
550
551 spacing: _listView.spacing
552
553 clip: false
554
555 orientation: ListView.Horizontal
556 snapMode: ListView.SnapOneItem
557
558 boundsBehavior: Flickable.StopAtBounds
559 boundsMovement :Flickable.StopAtBounds
560
561 preferredHighlightBegin: 0
562 preferredHighlightEnd: width
563
564 highlightRangeMode: ListView.StrictlyEnforceRange
565 highlightMoveDuration: 0
566 highlightFollowsCurrentItem: true
567 highlightResizeDuration: 0
568 highlightMoveVelocity: -1
569 highlightResizeVelocity: -1
570
571 maximumFlickVelocity: 4 * width
572
573 cacheBuffer: _listView.count * width
574 keyNavigationEnabled : false
575 keyNavigationWraps : false
576 }
577 }
578
579 Loader
580 {
581 active: control.Maui.Controls.showCSD === true && control.altTabBar && !Maui.Handy.isMobile
582 asynchronous: true
583 width: parent.width
584
585 sourceComponent: Maui.ToolBar
586 {
587 anchors.top: parent.top
588 Maui.Controls.showCSD: true
589 background: Rectangle
590 {
591 Maui.Theme.colorSet: control.Maui.Theme.colorSet
592 Maui.Theme.inherit: false
593 opacity: 0.8
594 scale: -1 //for mirroring
595 gradient: Gradient {
596 orientation: Gradient.Horizontal
597 GradientStop { position: 0.0; color: Maui.Theme.backgroundColor }
598 GradientStop { position: 0.33; color: "transparent" }
599 GradientStop { position: 1.0; color: "transparent" }
600 }
601 }
602 }
603 }
604
605 Maui.Holder
606 {
607 id: _holder
608 anchors.fill: parent
609 visible: !control.count
610 emojiSize: Maui.Style.iconSizes.huge
611 }
612 }
613
614 Component
615 {
616 id: _overviewComponent
617
618 Pane
619 {
620 id: _pane
621 Maui.Theme.colorSet: Maui.Theme.View
622 Maui.Theme.inherit: false
623
624 background: Rectangle
625 {
626 color: Maui.Theme.backgroundColor
627 Loader
628 {
629 active: !Maui.Handy.isMobile
630 asynchronous: true
631 anchors.fill: parent
632 sourceComponent: Item
633 {
634 DragHandler
635 {
636 // acceptedDevices: PointerDevice.GenericPointer
637 grabPermissions: PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything
638 onActiveChanged: if (active) { control.Window.window.startSystemMove(); }
639 }
640 }
641 }
642 }
643
644 contentItem: Maui.GridBrowser
645 {
646 id: _overviewGrid
647 model: control.count
648
649 currentIndex: control.currentIndex
650
651 itemSize: Math.min(200, availableWidth /2)
652
653 Loader
654 {
655 asynchronous: true
656 anchors.bottom: parent.bottom
657 anchors.right: parent.right
658 anchors.margins: Maui.Style.space.big
659 sourceComponent: Maui.FloatingButton
660 {
661 icon.name: "list-add"
662 onClicked: control.newTabClicked()
663 }
664 }
665
666 onAreaClicked:
667 {
668 control.closeOverview()
669 }
670
671 delegate: Item
672 {
673 height: GridView.view.cellHeight
674 width: GridView.view.cellWidth
675
676 Maui.GridBrowserDelegate
677 {
678 id: _delegate
679
680 anchors.fill: parent
681 anchors.margins: Maui.Style.space.medium
682
683 isCurrentItem : parent.GridView.isCurrentItem
684 label1.text: _listView.contentModel.get(index).Maui.Controls.title
685 // template.labelSizeHint: 32
686 iconSource: "tab-new"
687 flat: false
688
689 tooltipText: _listView.contentModel.get(index).Maui.Controls.toolTipText
690
691 Rectangle
692 {
693 parent: _delegate.background
694 color: _listView.contentModel.get(index).Maui.Controls.color
695 height: 2
696 width: parent.width*0.9
697 anchors.bottom: parent.bottom
698 anchors.horizontalCenter: parent.horizontalCenter
699 }
700
701 onRightClicked:
702 {
703 _listView.setCurrentIndex(index)
704 openTabMenu(_listView.currentIndex)
705 }
706
707 onClicked:
708 {
709 control.closeOverview()
710 _listView.setCurrentIndex(index)
711 }
712
713 onPressAndHold:
714 {
715 _listView.setCurrentIndex(index)
716 openTabMenu(control.currentIndex)
717 }
718
719 template.iconComponent: Item
720 {
721 clip: true
722
723 ShaderEffectSource
724 {
725 id: _effect
726
727 anchors.centerIn: parent
728
729 readonly property double m_scale: Math.min(parent.height/sourceItem.height, parent.width/sourceItem.width)
730
731 height: sourceItem.height * m_scale
732 width: sourceItem.width * m_scale
733
734 hideSource: false
735 live: false
736 smooth: true
737
738 textureSize: Qt.size(width,height)
739 sourceItem: _listView.contentModel.get(index)
740 layer.enabled: Maui.Style.enableEffects
741 layer.smooth: true
742 layer.effect: MultiEffect
743 {
744 maskEnabled: true
745 maskThresholdMin: 0.5
746 maskSpreadAtMin: 1.0
747 maskSpreadAtMax: 0.0
748 maskThresholdMax: 1.0
749 maskSource: ShaderEffectSource
750 {
751 sourceItem: Rectangle
752 {
753 width: _effect.width
754 height: _effect.height
755 radius: Maui.Style.radiusV
756 }
757 }
758 }
759 }
760
761 Maui.CloseButton
762 {
763 id: _closeButton
764 visible: _delegate.isCurrentItem || _delegate.hovered || Maui.Handy.isMobile
765 anchors.top: parent.top
766 anchors.right: parent.right
767 // anchors.margins: Maui.Style.space.small
768
769 onClicked: control.closeTabClicked(index)
770
771 background: Rectangle
772 {
773 radius: height/2
774 color: _closeButton.hovered || _closeButton.containsPress ? Maui.Theme.negativeBackgroundColor : Maui.Theme.backgroundColor
775
776 Behavior on color
777 {
778 Maui.ColorTransition{}
779 }
780 }
781 }
782 }
783 }
784 }
785 }
786 }
787 }
788 }
789 }
790
791 /**
792 * @brief Close a tab view at a given index. This will release the resources, and move the focus to the previous tab view
793 * @param index index of the tab to be closed
794 */
795 function closeTab(index)
796 {
797 _listView.removeItem(_listView.itemAt(index))
798 // _tabBar.removeItem(_tabBar.itemAt(index))
799
800 _listView.currentItemChanged()
801 _listView.currentItem.forceActiveFocus()
802 }
803
804 /**
805 * @brief Adds a new tab view element, the passed element must be a component which will be created by the function and then added to the container
806 * @param component a Component element hosting the actual element to be created.
807 * @param properties set of values that can be passed as a map of properties to be assigned to the component when created
808 * @param quiet optionally you can choose to create the tab quietly or not: by quietly it means that the tab-component will be instantiated and created but will not be focused right away. If quiet is set to `false` - to which it defaults - then after the creation of the component the new tab will get focused.
809 */
810 function addTab(component, properties, quiet = false) : Item
811 {
812 if(control.overviewMode)
813 {
814 control.closeOverview()
815 }
816
817 const object = component.createObject(control, properties);
818
819 _listView.addItem(object)
820
821 if(!quiet)
822 {
823 _listView.setCurrentIndex(Math.max(_listView.count -1, 0))
824 object.forceActiveFocus()
825 }
826
827 return object
828 }
829
830 /**
831 * @brief Method to open the tab finder.
832 */
833 function findTab()
834 {
835 if(control.count > 1)
836 {
837 _loader.sourceComponent = _quickSearchComponent
838 _loader.item.open()
839 }
840 }
841
842 /**
843 * @brief Method to open the tabs overview.
844 */
845 function openOverview()
846 {
847 if(_stackView.depth === 2)
848 {
849 return
850 }
851 _stackView.push(_overviewComponent)
852 }
853
854 /**
855 * @brief Close the overview of miniature tabs.
856 */
857 function closeOverview()
858 {
859 if(_stackView.depth === 1)
860 {
861 return
862 }
863
864 _stackView.pop()
865 }
866
867 /**
868 * @brief Method to correctly move a tab from one place to another by using the index numbers
869 * @param from the current index number of the tab to be moved
870 * @param to the new index value to where to move the tab
871 */
872 function moveTab(from, to)
873 {
874 _listView.moveItem(from, to)
875 _tabBar.moveItem(from, to)
876
877 _listView.setCurrentIndex(to)
878 _tabBar.setCurrentIndex(_listView.currentIndex)
879
880 _listView2.positionViewAtIndex(_listView.currentIndex, ListView.Contain)
881
882 _listView.currentItemChanged()
883 _listView.currentItem.forceActiveFocus()
884 }
885
886 /**
887 * @brief This allows to change the current tab without breaking the bindings from the `currentIndex` property
888 * @param index the index to change to
889 */
890 function setCurrentIndex(index)
891 {
892 _tabBar.setCurrentIndex(index)
893 _listView.setCurrentIndex(index)
894 _listView.currentItem.forceActiveFocus()
895 }
896
897 /**
898 * @brief Return the Item of the tab view at a given index number
899 * @return the Item element representing the tab view
900 */
901 function tabAt(index)
902 {
903 return _listView.itemAt(index)
904 }
905
906 /**
907 * @brief Opens the tab contextual menu at a given index number
908 */
909 function openTabMenu(index)
910 {
911 _menu.index = index
912 _menu.show()
913 }
914}
alias view
Tab bar alternative to QQC TabBar, and based on it.
Definition TabBar.qml:52
alias interactive
Whether the control will react to touch events to flick the tabs.
Definition TabBar.qml:75
QString i18nd(const char *domain, const char *text, const TYPE &arg...)
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
KGuiItem find()
QString label(StandardShortcut id)
void forceActiveFocus()
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.