KDDockWidgets API Documentation 2.0
Loading...
Searching...
No Matches
DockRegistry.cpp
Go to the documentation of this file.
1/*
2 This file is part of KDDockWidgets.
3
4 SPDX-FileCopyrightText: 2019 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5 Author: SĂ©rgio Martins <sergio.martins@kdab.com>
6
7 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
8
9 Contact KDAB at <info@kdab.com> for commercial licensing options.
10*/
11
12#include "DockRegistry.h"
13#include "DockRegistry_p.h"
14#include "DelayedCall_p.h"
15#include "Config.h"
16#include "core/Logging_p.h"
17#include "core/Position_p.h"
18#include "core/Utils_p.h"
19#include "core/Platform_p.h"
20#include "core/WidgetResizeHandler_p.h"
21#include "core/WindowBeingDragged_p.h"
22#include "core/layouting/Item_p.h"
23#include "core/layouting/LayoutingHost_p.h"
24#include "core/DockWidget_p.h"
25#include "core/ObjectGuard_p.h"
27#include "core/FloatingWindow.h"
28#include "core/SideBar.h"
29#include "core/MainWindow.h"
30#include "core/DockWidget.h"
31#include "core/DropArea.h"
32#include "core/Platform.h"
33#include "core/Window_p.h"
34
35#include "kdbindings/signal.h"
36
37#include <set>
38#include <utility>
39
40using namespace KDDockWidgets;
41using namespace KDDockWidgets::Core;
42
43namespace KDDockWidgets::Core {
44
45// Helper class to help implement Config::Flag_AutoHideAsTabGroups
46class SideBarGroupings
47{
48public:
49 void addGrouping(const DockWidget::List &);
50 void removeGrouping(const DockWidget::List &);
51 DockWidget::List groupingFor(DockWidget *) const;
52 void removeFromGroupings(DockWidget *);
53
54private:
55 DockWidget::List &groupingByRef(DockWidget *);
56 Vector<DockWidget::List> m_groupings;
57};
58
59}
60
61DockRegistry::DockRegistry(Core::Object *parent)
62 : Core::Object(parent)
63 , d(new Private())
64 , m_sideBarGroupings(new SideBarGroupings())
65{
67
68 d->m_connection = Platform::instance()->d->focusedViewChanged.connect(
69 &DockRegistry::onFocusedViewChanged, this);
70}
71
73{
74 delete m_sideBarGroupings;
76 d->m_connection.disconnect();
77 delete d;
78}
79
80void DockRegistry::maybeDelete()
81{
82 // We delete the singleton just to make LSAN happy.
83 // We could also simply ask the user do call something like KDDockWidgets::deinit() in the future,
84 // Also, please don't change this to be deleted at static dtor time with Q_GLOBAL_STATIC.
85 if (isEmpty() && d->m_numLayoutSavers == 0 && m_groups.isEmpty())
86 delete this;
87}
88
89void DockRegistry::onFocusedViewChanged(std::shared_ptr<View> view)
90{
91 auto p = view;
92 while (p && !p->isNull()) {
93 if (auto group = p->asGroupController()) {
94 // Special case: The focused widget is inside the group but not inside the dockwidget.
95 // For example, it's a line edit in the QTabBar. We still need to send the signal for
96 // the current dw in the tab group
97 if (auto dw = group->currentDockWidget()) {
98 setFocusedDockWidget(dw);
99 }
100
101 return;
102 }
103
104 if (auto dw = p->asDockWidgetController()) {
105 DockRegistry::self()->setFocusedDockWidget(dw);
106 return;
107 }
108 p = p->parentView();
109 }
110
111 setFocusedDockWidget(nullptr);
112}
113
114void DockRegistry::setFocusedDockWidget(Core::DockWidget *dw)
115{
116 if (d->m_focusedDockWidget.data() == dw)
117 return;
118
119 auto old = d->m_focusedDockWidget;
120 d->m_focusedDockWidget = dw;
121
122 if (old)
123 old->d->isFocusedChanged.emit(false);
124
125 if (dw)
126 dw->d->isFocusedChanged.emit(true);
127}
128
129bool DockRegistry::isEmpty(bool excludeBeingDeleted) const
130{
131 if (!m_dockWidgets.isEmpty() || !m_mainWindows.isEmpty())
132 return false;
133
134 return excludeBeingDeleted ? !hasFloatingWindows() : m_floatingWindows.isEmpty();
135}
136
138 const Vector<QString> &affinities2) const
139{
140 if (affinities1.isEmpty() && affinities2.isEmpty())
141 return true;
142
143 for (const QString &a1 : affinities1) {
144 for (const QString &a2 : affinities2) {
145 if (a1 == a2)
146 return true;
147 }
148 }
149
150 return false;
151}
152
154{
155 Vector<QString> names;
156 names.reserve(m_mainWindows.size());
157 for (auto mw : m_mainWindows)
158 names.push_back(mw->uniqueName());
159
160 return names;
161}
162
164{
165 Vector<QString> names;
166 names.reserve(m_dockWidgets.size());
167 for (auto dw : m_dockWidgets)
168 names.push_back(dw->uniqueName());
169
170 return names;
171}
172
173bool DockRegistry::isProbablyObscured(Core::Window::Ptr window,
174 Core::FloatingWindow *exclude) const
175{
176 if (!window)
177 return false;
178
179 const Rect geo = window->geometry();
180 for (Core::FloatingWindow *fw : m_floatingWindows) {
181 Window::Ptr fwWindow = fw->view()->window();
182 if (fw == exclude || fwWindow->equals(window))
183 continue;
184
185 if (fwWindow->geometry().intersects(geo)) {
186 // fw might be below, but we don't have a way to check. So be conservative and return
187 // true.
188 return true;
189 }
190 }
191
192 // Floating windows are Tool (keep above), unless we disabled it in Config
193 auto fw = floatingWindowForHandle(window);
194 const bool targetIsToolWindow =
195 fw && fw->isUtilityWindow();
196
197 for (Core::MainWindow *mw : m_mainWindows) {
198 Window::Ptr mwWindow = mw->view()->window();
199
200 if (mwWindow && !mwWindow->equals(window) && !targetIsToolWindow
201 && mwWindow->geometry().intersects(geo)) {
202 // Two main windows that intersect. Return true. If the target is a tool window it will
203 // be above, so we don't care.
204 return true;
205 }
206 }
207
208 return false;
209}
210
211bool DockRegistry::isProbablyObscured(Core::Window::Ptr target, WindowBeingDragged *exclude) const
212{
214 exclude ? exclude->floatingWindow() : nullptr; // It's null on Wayland. On wayland obscuring
215 // never happens anyway, so not a problem.
216
217 return isProbablyObscured(target, fw);
218}
219
221{
223 return sb->location();
224
226}
227
229{
230 for (auto mw : m_mainWindows) {
231 if (Core::SideBar *sb = mw->sideBarForDockWidget(dw))
232 return sb;
233 }
234
235 return nullptr;
236}
237
239{
240 for (auto mw : m_mainWindows) {
241 if (!mw->isMDI())
242 continue;
243
244 Layout *layout = mw->layout();
245 const Vector<Core::Group *> groups = layout->groups();
246 for (Core::Group *group : groups) {
247 if (WidgetResizeHandler *wrh = group->resizeHandler()) {
248 if (wrh->isResizing())
249 return group;
250 }
251 }
252 }
253
254 return nullptr;
255}
256
258{
259 d->m_currentCloseReason = reason;
260}
261
263{
264 return d->m_currentCloseReason;
265}
266
267DockRegistry::Private *DockRegistry::dptr() const
268{
269 return d;
270}
271
274{
276 result.reserve(m_mainWindows.size());
277
278 for (auto mw : m_mainWindows) {
279 const Vector<QString> mwAffinities = mw->affinities();
280 if (affinitiesMatch(mwAffinities, affinities))
281 result.push_back(mw);
282 }
283
284 return result;
285}
286
288{
289 return Layout::fromLayoutingHost(item->host());
290}
291
292bool DockRegistry::itemIsInMainWindow(const Item *item) const
293{
294 if (Core::Layout *layout = layoutForItem(item)) {
295 return layout->isInMainWindow(/*honourNesting=*/true);
296 }
297
298 return false;
299}
300
302{
303 static ObjectGuard<DockRegistry> s_dockRegistry;
304
305 if (!s_dockRegistry) {
306 s_dockRegistry = new DockRegistry();
307 }
308
309 return s_dockRegistry;
310}
311
313{
314 if (dock->uniqueName().isEmpty()) {
315 KDDW_ERROR("DockWidget doesn't have an ID");
316 } else if (auto other = dockByName(dock->uniqueName())) {
317 KDDW_ERROR("Another DockWidget {} with name {} already exists.", ( void * )other, dock->uniqueName(), ( void * )dock);
318 }
319
320 m_dockWidgets.push_back(dock);
321}
322
324{
325 if (d->m_focusedDockWidget == dock)
326 d->m_focusedDockWidget = nullptr;
327
328 m_dockWidgets.removeOne(dock);
329 m_sideBarGroupings->removeFromGroupings(dock);
330
331 maybeDelete();
332}
333
335{
336 if (mainWindow->uniqueName().isEmpty()) {
337 KDDW_ERROR("MainWindow doesn't have an ID");
338 } else if (auto other = mainWindowByName(mainWindow->uniqueName())) {
339 KDDW_ERROR("Another MainWindow {} with name {} already exists {}", ( void * )other, mainWindow->uniqueName(), ( void * )mainWindow);
340 }
341
342 m_mainWindows.push_back(mainWindow);
344}
345
347{
348 m_mainWindows.removeOne(mainWindow);
350 maybeDelete();
351}
352
354{
355 m_floatingWindows.push_back(fw);
357}
358
360{
361 m_floatingWindows.removeOne(fw);
363 maybeDelete();
364}
365
367{
368 m_groups.push_back(group);
369}
370
372{
373 m_groups.removeOne(group);
374 maybeDelete();
375}
376
378{
379 d->m_numLayoutSavers++;
380}
381
383{
384 d->m_numLayoutSavers--;
385 maybeDelete();
386}
387
389{
390 return d->m_focusedDockWidget;
391}
392
393bool DockRegistry::containsDockWidget(const QString &uniqueName) const
394{
395 return dockByName(uniqueName) != nullptr;
396}
397
398bool DockRegistry::containsMainWindow(const QString &uniqueName) const
399{
400 return mainWindowByName(uniqueName) != nullptr;
401}
402
403Core::DockWidget *DockRegistry::dockByName(const QString &name, DockByNameFlags flags) const
404{
405 for (auto dock : std::as_const(m_dockWidgets)) {
406 if (dock->uniqueName() == name)
407 return dock;
408 }
409
410 if (flags.testFlag(DockByNameFlag::ConsultRemapping)) {
411 // Name doesn't exist, let's check if it was remapped during a layout restore.
412 auto it = m_dockWidgetIdRemapping.find(name);
413 const QString newName = it == m_dockWidgetIdRemapping.cend() ? QString() : it->second;
414 if (!newName.isEmpty())
415 return dockByName(newName);
416 }
417
418 if (flags.testFlag(DockByNameFlag::CreateIfNotFound)) {
419 // DockWidget doesn't exist, ask to create it
420 if (auto factoryFunc = Config::self().dockWidgetFactoryFunc()) {
421 auto dw = factoryFunc(name);
422 if (dw && dw->uniqueName() != name) {
423 // Very special case
424 // The user's factory function returned a dock widget with a different ID.
425 // We support it. Save the mapping though.
426 m_dockWidgetIdRemapping[name] = dw->uniqueName();
427 }
428 return dw;
429 } else if (!flags.testFlag(DockByNameFlag::SilentIfNotFound)) {
430 KDDW_ERROR("Couldn't find dock widget named={}", name);
431 }
432 }
433
434 return nullptr;
435}
436
438{
439 for (auto mainWindow : std::as_const(m_mainWindows)) {
440 if (mainWindow->uniqueName() == name)
441 return mainWindow;
442 }
443
444 return nullptr;
445}
446
448{
449 std::set<QString> names;
450 for (auto dock : std::as_const(m_dockWidgets)) {
451 const QString name = dock->uniqueName();
452 if (name.isEmpty()) {
453 KDDW_ERROR("DockRegistry::isSane: DockWidget is missing a name");
454 return false;
455 } else if (names.find(name) != names.cend()) {
456 KDDW_ERROR("DockRegistry::isSane: dockWidgets with duplicate names: {}", name);
457 return false;
458 } else {
459 names.insert(name);
460 }
461 }
462
463 names.clear();
464 for (auto mainwindow : std::as_const(m_mainWindows)) {
465 const QString name = mainwindow->uniqueName();
466 if (name.isEmpty()) {
467 KDDW_ERROR("DockRegistry::isSane: MainWindow is missing a name");
468 return false;
469 } else if (names.find(name) != names.cend()) {
470 KDDW_ERROR("DockRegistry::isSane: mainWindow with duplicate names: {}", name);
471 return false;
472 } else {
473 names.insert(name);
474 }
475
476 if (!mainwindow->layout()->checkSanity())
477 return false;
478 }
479
480 return true;
481}
482
484{
485 return m_dockWidgets;
486}
487
489{
491 result.reserve(names.size());
492
493 for (auto dw : std::as_const(m_dockWidgets)) {
494 if (names.contains(dw->uniqueName()))
495 result.push_back(dw);
496 }
497
498 return result;
499}
500
502{
504 result.reserve(names.size());
505
506 for (auto mw : std::as_const(m_mainWindows)) {
507 if (names.contains(mw->uniqueName()))
508 result.push_back(mw);
509 }
510
511 return result;
512}
513
515{
517 result.reserve(m_dockWidgets.size());
518
519 for (Core::DockWidget *dw : m_dockWidgets) {
520 const bool shouldSkip = honourSkipped && (dw->layoutSaverOptions() & LayoutSaverOption::Skip);
521 if (!shouldSkip && dw->parent() == nullptr && !dw->isVisible())
522 result.push_back(dw);
523 }
524
525 return result;
526}
527
529{
530 return m_mainWindows;
531}
532
534{
536
537 for (auto mw : m_mainWindows) {
538 if (View *view = mw->view()) {
539 auto viewInterface = dynamic_cast<Core::MainWindowViewInterface *>(view);
540 areas.push_back(viewInterface);
541 }
542 }
543
544 return areas;
545}
546
548{
549 return m_groups;
550}
551
552Vector<Core::FloatingWindow *> DockRegistry::floatingWindows(bool includeBeingDeleted, bool honourSkipped) const
553{
554 // Returns all the FloatingWindow which aren't being deleted
556 result.reserve(m_floatingWindows.size());
557 for (Core::FloatingWindow *fw : m_floatingWindows) {
558 if (!includeBeingDeleted && fw->beingDeleted())
559 continue;
560
561 if (honourSkipped && fw->allDockWidgetsHave(LayoutSaverOption::Skip))
562 continue;
563
564 result.push_back(fw);
565 }
566
567 return result;
568}
569
571{
572 Window::List windows;
573 windows.reserve(m_floatingWindows.size());
574 for (Core::FloatingWindow *fw : m_floatingWindows) {
575 if (!fw->beingDeleted()) {
576 if (Core::Window::Ptr window = fw->view()->window()) {
577 windows.push_back(window);
578 } else {
579 KDDW_ERROR("FloatingWindow doesn't have QWindow");
580 }
581 }
582 }
583
584 return windows;
585}
586
588{
589 return std::any_of(m_floatingWindows.begin(), m_floatingWindows.end(),
590 [](Core::FloatingWindow *fw) { return !fw->beingDeleted(); });
591}
592
593Core::FloatingWindow *DockRegistry::floatingWindowForHandle(Core::Window::Ptr windowHandle) const
594{
595 for (Core::FloatingWindow *fw : m_floatingWindows) {
596 if (fw->view()->window()->equals(windowHandle))
597 return fw;
598 }
599
600 return nullptr;
601}
602
604{
605 for (Core::FloatingWindow *fw : m_floatingWindows) {
606 Window::Ptr window = fw->view()->window();
607 if (window && window->handle() == hwnd)
608 return fw;
609 }
610
611 return nullptr;
612}
613
615{
616 if (!window)
617 return nullptr;
618
619 for (Core::MainWindow *mw : m_mainWindows) {
620 if (mw->view()->d->isInWindow(window))
621 return mw;
622 }
623
624 return nullptr;
625}
626
627Window::List DockRegistry::topLevels(bool excludeFloatingDocks) const
628{
629 Window::List windows;
630 windows.reserve(m_floatingWindows.size() + m_mainWindows.size());
631
632 if (!excludeFloatingDocks) {
633 for (Core::FloatingWindow *fw : m_floatingWindows) {
634 if (fw->isVisible()) {
635 if (Core::Window::Ptr window = fw->view()->window()) {
636 windows.push_back(window);
637 } else {
638 KDDW_ERROR("FloatingWindow doesn't have QWindow");
639 }
640 }
641 }
642 }
643
644 for (Core::MainWindow *m : m_mainWindows) {
645 if (m->isVisible()) {
646 if (Core::Window::Ptr window = m->view()->window()) {
647 windows.push_back(window);
648 } else {
649 KDDW_ERROR("MainWindow doesn't have QWindow");
650 }
651 }
652 }
653
654 return windows;
655}
656
658{
659 // Clears everything
660 clear(m_dockWidgets, m_mainWindows, affinities);
661}
662
663void DockRegistry::clear(const Core::DockWidget::List &dockWidgets,
664 const Core::MainWindow::List &mainWindows,
665 const Vector<QString> &affinities)
666{
667 for (auto dw : std::as_const(dockWidgets)) {
668 if (affinities.isEmpty() || affinitiesMatch(affinities, dw->affinities())) {
669 dw->forceClose();
670 dw->d->lastPosition()->removePlaceholders();
671 }
672 }
673
674 for (auto mw : std::as_const(mainWindows)) {
675 if (affinities.isEmpty() || affinitiesMatch(affinities, mw->affinities())) {
676 mw->layout()->clearLayout();
677 }
678 }
679}
680
682{
683 for (Core::DockWidget *dw : std::as_const(m_dockWidgets)) {
684 if (dw->view()->rootView()->equals(dw->view()) && dw->isVisible())
685 dw->d->morphIntoFloatingWindow();
686 }
687}
688
689bool DockRegistry::onMouseButtonPress(View *view, MouseEvent *event)
690{
691 if (!view)
692 return false;
693
695 // When clicking on a MDI Group we raise the window
696 if (Controller *c = view->d->firstParentOfType(ViewType::Group)) {
697 auto group = static_cast<Group *>(c);
698 if (group->isMDI())
699 group->view()->raise();
700 }
701 }
702
703 // The following code is for hididng the overlay
705 return false;
706
707 if (view->is(ViewType::Group)) {
708 // break recursion
709 return false;
710 }
711
712 auto p = view->asWrapper();
713 while (p) {
714 if (auto dw = p->asDockWidgetController())
715 return onDockWidgetPressed(dw, event);
716
717 if (auto layout = p->asLayout()) {
718 if (auto mw = layout->mainWindow()) {
719 // The user clicked somewhere in the main window's drop area, but outside of the
720 // overlayed dock widget
721 mw->clearSideBarOverlay();
722 return false;
723 }
724 }
725
726 p = p->parentView();
727 }
728
729
730 return false;
731}
732
733bool DockRegistry::onDockWidgetPressed(Core::DockWidget *dw, MouseEvent *ev)
734{
735 // Here we implement "auto-hide". If there's a overlayed dock widget, we hide it if some other
736 // dock widget is clicked.
737
738 // Don't be sending mouse events around if a popup is open, they are sensitive
739 if (Platform::instance()->hasActivePopup())
740 return false;
741
742 Core::MainWindow *mainWindow = dw->mainWindow();
743 if (!mainWindow) // Only docked widgets are interesting
744 return false;
745
746 if (Core::DockWidget *overlayedDockWidget = mainWindow->overlayedDockWidget()) {
747 ev->ignore();
748 Platform::instance()->sendEvent(overlayedDockWidget->d->group()->view(), ev);
749
750 if (ev->isAccepted()) {
751 // The Frame accepted it. It means the user is resizing it. We allow for 4px outside for
752 // better resize.
753 return true; // don't propagate the event further
754 }
755 if (dw != overlayedDockWidget) {
756 // User clicked outside if the overlay, then we close the overlay.
757 mainWindow->clearSideBarOverlay();
758 return false;
759 }
760 }
761
762 return false;
763}
764
765bool DockRegistry::onExposeEvent(Core::Window::Ptr window)
766{
768 // This floating window was exposed
769 m_floatingWindows.removeOne(fw);
770 m_floatingWindows.append(fw);
771 }
772
773 return false;
774}
775
776void DockRegistry::addSideBarGrouping(const DockWidget::List &dws)
777{
778 m_sideBarGroupings->addGrouping(dws);
779}
780
781void DockRegistry::removeSideBarGrouping(const DockWidget::List &dws)
782{
783 m_sideBarGroupings->removeGrouping(dws);
784}
785
786DockWidget::List DockRegistry::sideBarGroupingFor(DockWidget *dw) const
787{
788 return m_sideBarGroupings->groupingFor(dw);
789}
790
791void SideBarGroupings::addGrouping(const DockWidget::List &dws)
792{
793 if (dws.size() < 2) {
794 // Simplification: A single dock widget is not considered to be grouped.
795 return;
796 }
797
798 m_groupings.push_back(dws);
799}
800
801void SideBarGroupings::removeGrouping(const DockWidget::List &dws)
802{
803 m_groupings.removeAll(dws);
804}
805
806DockWidget::List SideBarGroupings::groupingFor(DockWidget *dw) const
807{
808 return const_cast<SideBarGroupings *>(this)->groupingByRef(dw);
809}
810
811void SideBarGroupings::removeFromGroupings(DockWidget *dw)
812{
813 while (true) {
814 auto &grouping = groupingByRef(dw);
815 if (grouping.isEmpty())
816 return;
817 grouping.removeAll(dw);
818 }
819}
820
821DockWidget::List &SideBarGroupings::groupingByRef(DockWidget *dw)
822{
823 static DockWidget::List empty;
824
825 for (auto &grouping : m_groupings) {
826 if (grouping.contains(dw))
827 return grouping;
828 }
829
830 return empty;
831}
832
837
Application-wide config to tune certain behaviours of the framework.
static Config & self()
returns the singleton Config instance
Definition Config.cpp:88
@ MDIFlag_NoClickToRaise
Clicking on a MDI widget won't raise it.
Definition Config.h:184
static bool hasMDIFlag(MDIFlag)
Returns whether the specified MDI flag is set or not.
Definition Config.cpp:150
View * view() const
Returns the view associated with this controller, if any.
The DockWidget base-class. DockWidget and Core::DockWidget are only split in two so we can share some...
MainWindow * mainWindow() const
Returns the main window this dock widget is in. nullptr if it's not inside a main window Also returns...
QString uniqueName() const
the dock widget's unique name.
Vector< QString > affinities() const
Returns the affinity name. Empty by default.
KDDockWidgets::LayoutSaverOptions layoutSaverOptions() const
returns the per-dockwidget options which will affect LayoutSaver These are the options which were pas...
void forceClose()
Like QWidget::close() but the hosted widget won't be asked if we should close.
bool allDockWidgetsHave(DockWidgetOption) const
Returns whether all dock widgets have the specified option set.
bool beingDeleted() const
Returns whether a deleteLater has already been issued.
The widget (QWidget or QQuickItem) which holds a layout of dock widgets.
Definition Layout.h:57
Vector< Core::Group * > groups() const
Returns this list of Group objects contained in this layout.
Definition Layout.cpp:253
static Layout * fromLayoutingHost(LayoutingHost *)
Definition Layout.cpp:396
The interface that MainWindow views should implement.
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
QString uniqueName() const
Returns the unique name that was passed via constructor. Used internally by the save/restore mechanis...
void clearSideBarOverlay(bool deleteGroup=true)
closes any overlayed dock widget. The sidebar still displays them as button.
Core::DockWidget * overlayedDockWidget() const
returns the dock widget which is currently overlayed. nullptr if none. This is only relevant when usi...
virtual void onMainWindowDestroyed(Core::MainWindow *)
Called when a main window is created. Overridden by flutter, so it can destroy the window.
virtual void onFloatingWindowDestroyed(Core::FloatingWindow *)
Called when a floating window is created. Overridden by flutter, so it can destroy the window.
static Platform * instance()
Returns the platform singleton.
void removeGlobalEventFilter(EventFilterInterface *)
Removes a global event filter.
virtual void sendEvent(View *, Event *) const =0
Sends the specified event to the specified view.
void installGlobalEventFilter(EventFilterInterface *)
Installs a global event filter Events will be forwarded to the specified EventFilterInterface.
virtual void onFloatingWindowCreated(Core::FloatingWindow *)
Called when a floating window is created. Overridden by flutter, so it can create a window.
virtual void onMainWindowCreated(Core::MainWindow *)
Called when a main window is created. Overridden by flutter, so it can create a window Used by tests ...
virtual std::shared_ptr< View > rootView() const =0
Returns the top-level gui element which this view is inside It's the root view of the window.
virtual bool is(ViewType) const
Returns whether the view is of the specified type Virtual so it can be overridden by ViewWrapper....
virtual std::shared_ptr< Core::Window > window() const =0
Returns the window this view is inside For the Qt frontend, this wraps a QWindow. Like QWidget::windo...
virtual void raise()=0
virtual std::shared_ptr< View > asWrapper()=0
Returns this view, but as a wrapper.
bool affinitiesMatch(const Vector< QString > &affinities1, const Vector< QString > &affinities2) const
@ CreateIfNotFound
Creates the dock widget via the user's widget factory in case it doesn't exist.
@ SilentIfNotFound
don't print errors if not found, it will be created later
Q_INVOKABLE void clear(const Vector< QString > &affinities={})
Closes all dock widgets, and destroys all FloatingWindows This is called before restoring a layout.
Core::FloatingWindow * floatingWindowForHandle(std::shared_ptr< Core::Window > windowHandle) const
returns the FloatingWindow with handle windowHandle
Core::MainWindow * mainWindowForHandle(std::shared_ptr< Core::Window > windowHandle) const
returns the MainWindow with handle windowHandle
Vector< Core::DockWidget * > dockWidgets(const Vector< QString > &names)
overload returning only the ones with the specified names
void unregisterFloatingWindow(Core::FloatingWindow *)
Q_INVOKABLE KDDockWidgets::Core::DockWidget * dockByName(const QString &, KDDockWidgets::DockRegistry::DockByNameFlags={}) const
void registerMainWindow(Core::MainWindow *)
Vector< QString > dockWidgetNames() const
Returns a list of all known dock widget unique names.
bool isProbablyObscured(std::shared_ptr< Core::Window > target, Core::FloatingWindow *exclude) const
returns if the specified window has some other window on top (with higher Z) This is an approximation...
Vector< Core::MainWindowViewInterface * > mainDockingAreas() const
returns all MainWindow instances Like mainwindows(), but with better suited for QtQuick and better te...
Vector< Core::FloatingWindow * > floatingWindows(bool includeBeingDeleted=false, bool honourSkipped=false) const
returns all FloatingWindow instances. Not necessarily all floating dock widgets, As there might be Do...
Vector< std::shared_ptr< Core::Window > > floatingQWindows() const
overload that returns list of QWindow. This is more friendly for supporting both QtWidgets and QtQuic...
Q_INVOKABLE KDDockWidgets::Core::DockWidget * focusedDockWidget() const
Q_INVOKABLE bool containsMainWindow(const QString &uniqueName) const
void unregisterGroup(Core::Group *)
Vector< Core::Group * > groups() const
returns a list of all Frame instances
void unregisterDockWidget(Core::DockWidget *)
Core::Group * groupInMDIResize() const
Returns the Group which is being resized in a MDI layout. nullptr if none.
Q_INVOKABLE KDDockWidgets::Core::MainWindow * mainWindowByName(const QString &) const
static DockRegistry * self()
Q_INVOKABLE bool hasFloatingWindows() const
returns whether if there's at least one floating window
void ensureAllFloatingWidgetsAreMorphed()
Ensures that all floating DockWidgets have a FloatingWindow as a window.
Q_INVOKABLE bool containsDockWidget(const QString &uniqueName) const
SideBarLocation sideBarLocationForDockWidget(const Core::DockWidget *) const
Returns whether the specified dock widget is in a side bar, and which. SideBarLocation::None is retur...
void registerGroup(Core::Group *)
void unregisterMainWindow(Core::MainWindow *)
Vector< Core::MainWindow * > mainWindows(const Vector< QString > &names)
overload returning only the ones with the specified names
bool isEmpty(bool excludeBeingDeleted=false) const
returns true if there's 0 dockwidgets, 0 main windows
Vector< Core::MainWindow * > mainWindowsWithAffinity(const Vector< QString > &affinities) const
Returns all main windows which match at least one of the affinities.
Core::SideBar * sideBarForDockWidget(const Core::DockWidget *) const
Overload that returns the SideBar itself.
Vector< Core::DockWidget * > closedDockwidgets(bool honourSkipped) const
returns all closed DockWidget instances
bool itemIsInMainWindow(const Core::Item *) const
Returns whether the item is in a main window. Nesting is honoured. (MDIArea inside DropArea inside Ma...
void registerFloatingWindow(Core::FloatingWindow *)
Vector< QString > mainWindowsNames() const
Returns a list of all known main window unique names.
Vector< Core::DockWidget * > dockwidgets() const
returns all DockWidget instances
void registerDockWidget(Core::DockWidget *)
Vector< Core::MainWindow * > mainwindows() const
returns all MainWindow instances
Vector< std::shared_ptr< Core::Window > > topLevels(bool excludeFloatingDocks=false) const
Returns the list with all visiblye top-level parents of our FloatingWindow and MainWindow instances.
Core::Layout * layoutForItem(const Core::Item *) const
Returns the Layout where the specified item is in.
void setCurrentCloseReason(CloseReason)
The DockWidget controller that's shared between QtWidgets and QtQuick frontends.
A MultiSplitter with support for drop indicators when hovering over.
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
Class to abstract QAction, so code still works with QtQuick and Flutter.
SideBarLocation
Each main window supports 4 sidebars.
@ Skip
The dock widget won't participate in save/restore.
Definition utils.h:161
bool isEmpty() const const

© Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDDockWidgets
Advanced Dock Widget Framework for Qt
https://www.kdab.com/development-resources/qt-tools/kddockwidgets/
Generated by doxygen 1.9.8