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 && m_groups.isEmpty())
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 auto old = d->m_focusedDockWidget;
120 d->m_focusedDockWidget = dw;
123 old->
d->isFocusedChanged.emit(
false);
126 dw->
d->isFocusedChanged.emit(
true);
131 if (!m_dockWidgets.isEmpty() || !m_mainWindows.isEmpty())
143 for (
const QString &a1 : affinities1) {
144 for (
const QString &a2 : affinities2) {
156 names.
reserve(m_mainWindows.size());
157 for (
auto mw : m_mainWindows)
158 names.push_back(mw->uniqueName());
166 names.
reserve(m_dockWidgets.size());
167 for (
auto dw : m_dockWidgets)
179 const Rect geo = window->geometry();
181 Window::Ptr fwWindow = fw->view()->window();
182 if (fw == exclude || fwWindow->equals(window))
185 if (fwWindow->geometry().intersects(geo)) {
194 const bool targetIsToolWindow =
195 fw && fw->isUtilityWindow();
198 Window::Ptr mwWindow = mw->view()->window();
200 if (mwWindow && !mwWindow->equals(window) && !targetIsToolWindow
201 && mwWindow->geometry().intersects(geo)) {
214 exclude ? exclude->floatingWindow() :
nullptr;
223 return sb->location();
230 for (
auto mw : m_mainWindows) {
240 for (
auto mw : m_mainWindows) {
244 Layout *layout = mw->layout();
247 if (WidgetResizeHandler *wrh = group->resizeHandler()) {
248 if (wrh->isResizing())
259 d->m_currentCloseReason = reason;
264 return d->m_currentCloseReason;
276 result.
reserve(m_mainWindows.size());
278 for (
auto mw : m_mainWindows) {
281 result.push_back(mw);
295 return layout->isInMainWindow(
true);
303 static ObjectGuard<DockRegistry> s_dockRegistry;
305 if (!s_dockRegistry) {
309 return s_dockRegistry;
315 KDDW_ERROR(
"DockWidget doesn't have an ID");
317 KDDW_ERROR(
"Another DockWidget {} with name {} already exists.", (
void * )other, dock->
uniqueName(), (
void * )dock);
320 m_dockWidgets.push_back(dock);
325 if (d->m_focusedDockWidget == dock)
326 d->m_focusedDockWidget =
nullptr;
328 m_dockWidgets.removeOne(dock);
329 m_sideBarGroupings->removeFromGroupings(dock);
337 KDDW_ERROR(
"MainWindow doesn't have an ID");
339 KDDW_ERROR(
"Another MainWindow {} with name {} already exists {}", (
void * )other, mainWindow->
uniqueName(), (
void * )mainWindow);
342 m_mainWindows.push_back(mainWindow);
348 m_mainWindows.removeOne(mainWindow);
355 m_floatingWindows.push_back(fw);
361 m_floatingWindows.removeOne(fw);
368 m_groups.push_back(group);
373 m_groups.removeOne(group);
379 d->m_numLayoutSavers++;
384 d->m_numLayoutSavers--;
390 return d->m_focusedDockWidget;
405 for (
auto dock : std::as_const(m_dockWidgets)) {
406 if (dock->uniqueName() == name)
412 auto it = m_dockWidgetIdRemapping.find(name);
413 const QString newName = it == m_dockWidgetIdRemapping.cend() ?
QString() : it->second;
420 if (
auto factoryFunc =
Config::self().dockWidgetFactoryFunc()) {
421 auto dw = factoryFunc(name);
426 m_dockWidgetIdRemapping[name] = dw->
uniqueName();
430 KDDW_ERROR(
"Couldn't find dock widget named={}", name);
439 for (
auto mainWindow : std::as_const(m_mainWindows)) {
440 if (mainWindow->uniqueName() == name)
449 std::set<QString> names;
450 for (
auto dock : std::as_const(m_dockWidgets)) {
451 const QString name = dock->uniqueName();
453 KDDW_ERROR(
"DockRegistry::isSane: DockWidget is missing a name");
455 }
else if (names.find(name) != names.cend()) {
456 KDDW_ERROR(
"DockRegistry::isSane: dockWidgets with duplicate names: {}", name);
464 for (
auto mainwindow : std::as_const(m_mainWindows)) {
465 const QString name = mainwindow->uniqueName();
467 KDDW_ERROR(
"DockRegistry::isSane: MainWindow is missing a name");
469 }
else if (names.find(name) != names.cend()) {
470 KDDW_ERROR(
"DockRegistry::isSane: mainWindow with duplicate names: {}", name);
476 if (!mainwindow->layout()->checkSanity())
485 return m_dockWidgets;
493 for (
auto dw : std::as_const(m_dockWidgets)) {
495 result.push_back(dw);
506 for (
auto mw : std::as_const(m_mainWindows)) {
507 if (names.
contains(mw->uniqueName()))
508 result.push_back(mw);
517 result.
reserve(m_dockWidgets.size());
521 if (!shouldSkip && dw->parent() ==
nullptr && !dw->
isVisible())
522 result.push_back(dw);
530 return m_mainWindows;
537 for (
auto mw : m_mainWindows) {
538 if (
View *view = mw->view()) {
540 areas.push_back(viewInterface);
556 result.
reserve(m_floatingWindows.size());
564 result.push_back(fw);
572 Window::List windows;
573 windows.
reserve(m_floatingWindows.size());
576 if (Core::Window::Ptr window = fw->
view()->
window()) {
577 windows.push_back(window);
579 KDDW_ERROR(
"FloatingWindow doesn't have QWindow");
589 return std::any_of(m_floatingWindows.begin(), m_floatingWindows.end(),
596 if (fw->
view()->
window()->equals(windowHandle))
607 if (window && window->handle() == hwnd)
620 if (mw->view()->d->isInWindow(window))
629 Window::List windows;
630 windows.reserve(m_floatingWindows.size() + m_mainWindows.size());
632 if (!excludeFloatingDocks) {
635 if (Core::Window::Ptr window = fw->
view()->
window()) {
636 windows.push_back(window);
638 KDDW_ERROR(
"FloatingWindow doesn't have QWindow");
645 if (m->isVisible()) {
646 if (Core::Window::Ptr window = m->view()->window()) {
647 windows.push_back(window);
649 KDDW_ERROR(
"MainWindow doesn't have QWindow");
660 clear(m_dockWidgets, m_mainWindows, affinities);
670 dw->
d->lastPosition()->removePlaceholders();
676 mw->layout()->clearLayout();
685 dw->
d->morphIntoFloatingWindow();
689bool DockRegistry::onMouseButtonPress(
View *view, MouseEvent *event)
696 if (
Controller *c = view->
d->firstParentOfType(ViewType::Group)) {
697 auto group =
static_cast<Group *
>(c);
707 if (view->
is(ViewType::Group)) {
714 if (
auto dw = p->asDockWidgetController())
715 return onDockWidgetPressed(dw, event);
717 if (
auto layout = p->asLayout()) {
718 if (
auto mw = layout->mainWindow()) {
721 mw->clearSideBarOverlay();
750 if (ev->isAccepted()) {
755 if (dw != overlayedDockWidget) {
765bool DockRegistry::onExposeEvent(Core::Window::Ptr window)
769 m_floatingWindows.removeOne(fw);
770 m_floatingWindows.append(fw);
778 m_sideBarGroupings->addGrouping(dws);
783 m_sideBarGroupings->removeGrouping(dws);
788 return m_sideBarGroupings->groupingFor(dw);
793 if (dws.
size() < 2) {
798 m_groupings.push_back(dws);
803 m_groupings.removeAll(dws);
808 return const_cast<SideBarGroupings *
>(
this)->groupingByRef(dw);
811void SideBarGroupings::removeFromGroupings(
DockWidget *dw)
814 auto &grouping = groupingByRef(dw);
815 if (grouping.isEmpty())
817 grouping.removeAll(dw);
825 for (
auto &grouping : m_groupings) {
826 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...
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...
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