13#include "DockRegistry_p.h"
14#include "DelayedCall_p.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"
33#include "core/Window_p.h"
61DockRegistry::DockRegistry(Core::Object *parent)
62 : Core::Object(parent)
64 , m_sideBarGroupings(new SideBarGroupings())
69 &DockRegistry::onFocusedViewChanged,
this);
74 delete m_sideBarGroupings;
76 d->m_connection.disconnect();
80void DockRegistry::maybeDelete()
85 if (
isEmpty() && d->m_numLayoutSavers == 0)
89void DockRegistry::onFocusedViewChanged(std::shared_ptr<View> view)
92 while (p && !p->isNull()) {
93 if (
auto group = p->asGroupController()) {
97 if (
auto dw = group->currentDockWidget()) {
98 setFocusedDockWidget(dw);
104 if (
auto dw = p->asDockWidgetController()) {
111 setFocusedDockWidget(
nullptr);
116 if (d->m_focusedDockWidget.data() == dw)
119 if (d->m_focusedDockWidget) {
126 d->m_focusedDockWidget = dw;
138 if (!m_dockWidgets.isEmpty() || !m_mainWindows.isEmpty())
146 for (
auto layout : std::as_const(m_layouts)) {
147 layout->checkSanity();
149 layout->dumpLayout();
159 for (
const QString &a1 : affinities1) {
160 for (
const QString &a2 : affinities2) {
172 names.
reserve(m_mainWindows.size());
173 for (
auto mw : m_mainWindows)
174 names.push_back(mw->uniqueName());
182 names.
reserve(m_dockWidgets.size());
183 for (
auto dw : m_dockWidgets)
195 const Rect geo = window->geometry();
197 Window::Ptr fwWindow = fw->view()->window();
198 if (fw == exclude || fwWindow->equals(window))
201 if (fwWindow->geometry().intersects(geo)) {
210 const bool targetIsToolWindow =
211 fw && fw->isUtilityWindow();
214 Window::Ptr mwWindow = mw->view()->window();
216 if (mwWindow && !mwWindow->equals(window) && !targetIsToolWindow
217 && mwWindow->geometry().intersects(geo)) {
230 exclude ? exclude->floatingWindow() :
nullptr;
239 return sb->location();
246 for (
auto mw : m_mainWindows) {
256 for (
auto mw : m_mainWindows) {
260 Layout *layout = mw->layout();
263 if (WidgetResizeHandler *wrh = group->resizeHandler()) {
264 if (wrh->isResizing())
282 result.
reserve(m_mainWindows.size());
284 for (
auto mw : m_mainWindows) {
287 result.push_back(mw);
301 return layout->isInMainWindow(
true);
309 static ObjectGuard<DockRegistry> s_dockRegistry;
311 if (!s_dockRegistry) {
315 return s_dockRegistry;
321 KDDW_ERROR(
"DockWidget doesn't have an ID");
323 KDDW_ERROR(
"Another DockWidget {} with name {} already exists.", (
void * )other, dock->
uniqueName(), (
void * )dock);
326 m_dockWidgets.push_back(dock);
331 if (d->m_focusedDockWidget == dock)
332 d->m_focusedDockWidget =
nullptr;
334 m_dockWidgets.removeOne(dock);
335 m_sideBarGroupings->removeFromGroupings(dock);
343 KDDW_ERROR(
"MainWindow doesn't have an ID");
345 KDDW_ERROR(
"Another MainWindow {} with name {} already exists {}", (
void * )other, mainWindow->
uniqueName(), (
void * )mainWindow);
348 m_mainWindows.push_back(mainWindow);
354 m_mainWindows.removeOne(mainWindow);
361 m_floatingWindows.push_back(fw);
367 m_floatingWindows.removeOne(fw);
374 m_layouts.push_back(layout);
379 m_layouts.removeOne(layout);
384 m_groups.push_back(group);
389 m_groups.removeOne(group);
394 d->m_numLayoutSavers++;
399 d->m_numLayoutSavers--;
404 return d->m_focusedDockWidget;
419 for (
auto dock : std::as_const(m_dockWidgets)) {
420 if (dock->uniqueName() == name)
426 auto it = m_dockWidgetIdRemapping.find(name);
427 const QString newName = it == m_dockWidgetIdRemapping.cend() ?
QString() : it->second;
434 if (
auto factoryFunc =
Config::self().dockWidgetFactoryFunc()) {
435 auto dw = factoryFunc(name);
440 m_dockWidgetIdRemapping[name] = dw->
uniqueName();
444 KDDW_ERROR(
"Couldn't find dock widget name={}", name);
453 for (
auto mainWindow : std::as_const(m_mainWindows)) {
454 if (mainWindow->uniqueName() == name)
463 std::set<QString> names;
464 for (
auto dock : std::as_const(m_dockWidgets)) {
465 const QString name = dock->uniqueName();
467 KDDW_ERROR(
"DockRegistry::isSane: DockWidget is missing a name");
469 }
else if (names.find(name) != names.cend()) {
470 KDDW_ERROR(
"DockRegistry::isSane: dockWidgets with duplicate names: {}", name);
478 for (
auto mainwindow : std::as_const(m_mainWindows)) {
479 const QString name = mainwindow->uniqueName();
481 KDDW_ERROR(
"DockRegistry::isSane: MainWindow is missing a name");
483 }
else if (names.find(name) != names.cend()) {
484 KDDW_ERROR(
"DockRegistry::isSane: mainWindow with duplicate names: {}", name);
490 if (!mainwindow->layout()->checkSanity())
499 return m_dockWidgets;
507 for (
auto dw : std::as_const(m_dockWidgets)) {
509 result.push_back(dw);
520 for (
auto mw : std::as_const(m_mainWindows)) {
521 if (names.
contains(mw->uniqueName()))
522 result.push_back(mw);
531 result.
reserve(m_dockWidgets.size());
535 if (!shouldSkip && dw->parent() ==
nullptr && !dw->
isVisible())
536 result.push_back(dw);
544 return m_mainWindows;
551 for (
auto mw : m_mainWindows) {
552 if (
View *view = mw->view()) {
554 areas.push_back(viewInterface);
575 result.
reserve(m_floatingWindows.size());
583 result.push_back(fw);
591 Window::List windows;
592 windows.
reserve(m_floatingWindows.size());
595 if (Core::Window::Ptr window = fw->
view()->
window()) {
596 windows.push_back(window);
598 KDDW_ERROR(
"FloatingWindow doesn't have QWindow");
608 return std::any_of(m_floatingWindows.begin(), m_floatingWindows.end(),
615 if (fw->
view()->
window()->equals(windowHandle))
626 if (window && window->handle() == hwnd)
639 if (mw->view()->d->isInWindow(window))
648 Window::List windows;
649 windows.reserve(m_floatingWindows.size() + m_mainWindows.size());
651 if (!excludeFloatingDocks) {
654 if (Core::Window::Ptr window = fw->
view()->
window()) {
655 windows.push_back(window);
657 KDDW_ERROR(
"FloatingWindow doesn't have QWindow");
664 if (m->isVisible()) {
665 if (Core::Window::Ptr window = m->view()->window()) {
666 windows.push_back(window);
668 KDDW_ERROR(
"MainWindow doesn't have QWindow");
679 clear(m_dockWidgets, m_mainWindows, affinities);
689 dw->
d->lastPosition()->removePlaceholders();
695 mw->layout()->clearLayout();
704 dw->
d->morphIntoFloatingWindow();
708bool DockRegistry::onMouseButtonPress(
View *view, MouseEvent *event)
714 if (
Controller *c = view->
d->firstParentOfType(ViewType::Frame)) {
715 auto group =
static_cast<Group *
>(c);
724 if (view->
is(ViewType::Frame)) {
731 if (
auto dw = p->asDockWidgetController())
732 return onDockWidgetPressed(dw, event);
734 if (
auto layout = p->asLayout()) {
735 if (
auto mw = layout->mainWindow()) {
738 mw->clearSideBarOverlay();
767 if (ev->isAccepted()) {
772 if (dw != overlayedDockWidget) {
782bool DockRegistry::onExposeEvent(Core::Window::Ptr window)
786 m_floatingWindows.removeOne(fw);
787 m_floatingWindows.append(fw);
795 m_sideBarGroupings->addGrouping(dws);
800 m_sideBarGroupings->removeGrouping(dws);
805 return m_sideBarGroupings->groupingFor(dw);
810 if (dws.
size() < 2) {
815 m_groupings.push_back(dws);
820 m_groupings.removeAll(dws);
825 return const_cast<SideBarGroupings *
>(
this)->groupingByRef(dw);
828void SideBarGroupings::removeFromGroupings(
DockWidget *dw)
831 auto &grouping = groupingByRef(dw);
832 if (grouping.isEmpty())
834 grouping.removeAll(dw);
842 for (
auto &grouping : m_groupings) {
843 if (grouping.contains(dw))
Application-wide config to tune certain behaviours of the framework.
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...
void clearSideBarOverlay(bool deleteFrame=true)
closes any overlayed dock widget. The sidebar still displays them as button.
QString uniqueName() const
Returns the unique name that was passed via constructor. Used internally by the save/restore mechanis...
Core::DockWidget * overlayedDockWidget() const
returns the dock widget which is currently overlayed. nullptr if none. This is only relevant when usi...
A MultiSplitter with support for drop indicators when hovering over.
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
bool isEmpty() const const