KDDockWidgets API Documentation  1.6
MainWindowBase.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KDDockWidgets.
3 
4  SPDX-FileCopyrightText: 2019-2022 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 
20 #include "MainWindowBase.h"
21 #include "private/DockRegistry_p.h"
22 #include "private/MDILayoutWidget_p.h"
23 #include "private/DropArea_p.h"
24 #include "private/Frame_p.h"
25 #include "private/Utils_p.h"
26 #include "private/SideBar_p.h"
27 #include "private/Logging_p.h"
28 #include "private/WidgetResizeHandler_p.h"
29 #include "FrameworkWidgetFactory.h"
30 #include "private/DropAreaWithCentralFrame_p.h"
31 #include "private/LayoutSaver_p.h"
32 #include "private/DockWidgetBase_p.h"
33 #include "private/multisplitter/Item_p.h"
34 
35 // Or we can have a createDockWidget() in the factory
36 #ifdef KDDOCKWIDGETS_QTQUICK
37 #include "DockWidgetQuick.h"
38 #else
39 #include "DockWidget.h"
40 #endif
41 
42 #include <QCloseEvent>
43 
44 using namespace KDDockWidgets;
45 
46 static LayoutWidget *createLayoutWidget(MainWindowBase *mainWindow, MainWindowOptions options)
47 {
48  if (options & MainWindowOption_MDI)
49  return new MDILayoutWidget(mainWindow);
50 
51  return new DropAreaWithCentralFrame(mainWindow, options);
52 }
53 
54 class MainWindowBase::Private
55 {
56 public:
57  explicit Private(MainWindowBase *mainWindow, const QString &uniqueName, MainWindowOptions options)
58  : m_options(options)
59  , q(mainWindow)
60  , m_layoutWidget(createLayoutWidget(mainWindow, options))
61  , m_persistentCentralDockWidget(createPersistentCentralDockWidget(uniqueName))
62  {
63  }
64 
65  bool supportsCentralFrame() const
66  {
67  return m_options & MainWindowOption_HasCentralFrame;
68  }
69 
70  bool supportsPersistentCentralWidget() const
71  {
72  if (!dropArea()) {
73  // This is the MDI case
74  return false;
75  }
76 
78  }
79 
80  DockWidgetBase *createPersistentCentralDockWidget(const QString &uniqueName) const
81  {
82  if (!supportsPersistentCentralWidget())
83  return nullptr;
84 
85  auto dw = new DockWidgetType(QStringLiteral("%1-persistentCentralDockWidget").arg(uniqueName));
86  dw->dptr()->m_isPersistentCentralDockWidget = true;
87  Frame *frame = dropArea()->m_centralFrame;
88  if (!frame) {
89  qWarning() << Q_FUNC_INFO << "Expected central frame";
90  return nullptr;
91  }
92 
93  frame->addWidget(dw);
94  return dw;
95  }
96 
97  DropAreaWithCentralFrame *dropArea() const
98  {
99  return qobject_cast<DropAreaWithCentralFrame *>(m_layoutWidget);
100  }
101 
102  CursorPositions allowedResizeSides(SideBarLocation loc) const;
103 
104  QRect rectForOverlay(Frame *, SideBarLocation) const;
105  SideBarLocation preferredSideBar(DockWidgetBase *) const;
106  void updateOverlayGeometry(QSize suggestedSize);
107  void clearSideBars();
108 
109  QString name;
111  const MainWindowOptions m_options;
112  MainWindowBase *const q;
113  QPointer<DockWidgetBase> m_overlayedDockWidget;
114  LayoutWidget *const m_layoutWidget;
115  DockWidgetBase *const m_persistentCentralDockWidget;
116  int m_overlayMargin = 1;
117 };
118 
119 MainWindowBase::MainWindowBase(const QString &uniqueName, KDDockWidgets::MainWindowOptions options,
120  WidgetType *parent, Qt::WindowFlags flags)
121  : QMainWindowOrQuick(parent, flags)
122  , d(new Private(this, uniqueName, options))
123 {
125 
126  connect(d->m_layoutWidget, &LayoutWidget::visibleWidgetCountChanged, this,
128 }
129 
131 {
132  DockRegistry::self()->unregisterMainWindow(this);
133  delete d;
134 }
135 
137 {
138  Q_ASSERT(widget);
139  qCDebug(addwidget) << Q_FUNC_INFO << widget;
140 
141  if (!DockRegistry::self()->affinitiesMatch(d->affinities, widget->affinities())) {
142  qWarning() << Q_FUNC_INFO << "Refusing to dock widget with incompatible affinity."
143  << widget->affinities() << affinities();
144  return;
145  }
146 
147  if (widget->options() & DockWidgetBase::Option_NotDockable) {
148  qWarning() << Q_FUNC_INFO << "Refusing to dock non-dockable widget" << widget;
149  return;
150  }
151 
152  if (isMDI()) {
153  // Not applicable to MDI
154  return;
155  }
156 
157  if (d->supportsPersistentCentralWidget()) {
158  qWarning() << Q_FUNC_INFO << "Not supported with MainWindowOption_HasCentralWidget."
159  << "MainWindowOption_HasCentralWidget can only have 1 widget in the center."
160  << "Use MainWindowOption_HasCentralFrame instead, which is similar but supports tabbing";
161  } else if (d->supportsCentralFrame()) {
162  dropArea()->m_centralFrame->addWidget(widget);
163  } else {
164  qWarning() << Q_FUNC_INFO << "Not supported without MainWindowOption_HasCentralFrame";
165  }
166 }
167 
169  DockWidgetBase *relativeTo, InitialOption option)
170 {
171  Q_ASSERT(dw);
173  qWarning() << Q_FUNC_INFO << "Refusing to dock non-dockable widget" << dw;
174  return;
175  }
176 
177  if (isMDI()) {
178  // Not applicable to MDI
179  return;
180  }
181 
182  dropArea()->addDockWidget(dw, location, relativeTo, option);
183 }
184 
186 {
187  return d->name;
188 }
189 
190 MainWindowOptions MainWindowBase::options() const
191 {
192  return d->m_options;
193 }
194 
195 DropAreaWithCentralFrame *MainWindowBase::dropArea() const
196 {
197  return qobject_cast<DropAreaWithCentralFrame *>(d->m_layoutWidget);
198 }
199 
200 MultiSplitter *MainWindowBase::multiSplitter() const
201 {
202  return dropArea();
203 }
204 
205 LayoutWidget *MainWindowBase::layoutWidget() const
206 {
207  return d->m_layoutWidget;
208 }
209 
210 MDILayoutWidget *MainWindowBase::mdiLayoutWidget() const
211 {
212  return qobject_cast<MDILayoutWidget *>(layoutWidget());
213 }
214 
215 void MainWindowBase::setAffinities(const QStringList &affinityNames)
216 {
217  QStringList affinities = affinityNames;
219 
220  if (d->affinities == affinities)
221  return;
222 
223  if (!d->affinities.isEmpty()) {
224  qWarning() << Q_FUNC_INFO
225  << "Affinity is already set, refusing to change."
226  << "Submit a feature request with a good justification.";
227  return;
228  }
229 
230  d->affinities = affinities;
231 }
232 
234 {
235  return d->affinities;
236 }
237 
239 {
240  dropArea()->layoutEqually();
241 }
242 
244 {
245  dropArea()->layoutParentContainerEqually(dockWidget);
246 }
247 
248 CursorPositions MainWindowBase::Private::allowedResizeSides(SideBarLocation loc) const
249 {
250  // When a sidebar is on top, you can only resize its bottom.
251  // and so forth...
252 
253  switch (loc) {
255  return CursorPosition_Bottom;
257  return CursorPosition_Left;
259  return CursorPosition_Right;
261  return CursorPosition_Top;
264  }
265 
267 }
268 
269 QRect MainWindowBase::Private::rectForOverlay(Frame *frame, SideBarLocation location) const
270 {
271  SideBar *sb = q->sideBar(location);
272  if (!sb)
273  return {};
274 
275  const QRect centralAreaGeo = q->centralAreaGeometry();
276  const QMargins centerWidgetMargins = q->centerWidgetMargins();
277 
278  QRect rect;
279  const int margin = m_overlayMargin;
280  switch (location) {
282  case SideBarLocation::South: {
283 
284  SideBar *leftSideBar = q->sideBar(SideBarLocation::West);
285  SideBar *rightSideBar = q->sideBar(SideBarLocation::East);
286  const int leftSideBarWidth = (leftSideBar && leftSideBar->isVisible()) ? leftSideBar->width()
287  : 0;
288  const int rightSideBarWidth = (rightSideBar && rightSideBar->isVisible()) ? rightSideBar->width()
289  : 0;
290  rect.setHeight(qMax(300, frame->minSize().height()));
291  rect.setWidth(centralAreaGeo.width() - margin * 2 - leftSideBarWidth - rightSideBarWidth);
292  rect.moveLeft(margin + leftSideBarWidth);
293  if (location == SideBarLocation::South) {
294  rect.moveTop(centralAreaGeo.bottom() - centerWidgetMargins.bottom() - rect.height() - sb->height());
295  } else {
296  rect.moveTop(centralAreaGeo.y() + sb->height() + centerWidgetMargins.top());
297  }
298  break;
299  }
301  case SideBarLocation::East: {
302  SideBar *topSideBar = q->sideBar(SideBarLocation::North);
303  SideBar *bottomSideBar = q->sideBar(SideBarLocation::South);
304  const int topSideBarHeight = (topSideBar && topSideBar->isVisible()) ? topSideBar->height()
305  : 0;
306  const int bottomSideBarHeight = (bottomSideBar && bottomSideBar->isVisible()) ? bottomSideBar->height()
307  : 0;
308  rect.setWidth(qMax(300, frame->minSize().width()));
309  rect.setHeight(centralAreaGeo.height() - topSideBarHeight - bottomSideBarHeight - centerWidgetMargins.top() - centerWidgetMargins.bottom());
310  rect.moveTop(sb->mapTo(q, QPoint(0, 0)).y() + topSideBarHeight - 1);
311  if (location == SideBarLocation::East) {
312  rect.moveLeft(centralAreaGeo.x() + centralAreaGeo.width() - rect.width() - sb->width() - centerWidgetMargins.right() - margin);
313  } else {
314  rect.moveLeft(margin + centralAreaGeo.x() + centerWidgetMargins.left() + sb->width());
315  }
316 
317  break;
318  }
320  break;
321  }
322 
323  return rect;
324 }
325 
326 static SideBarLocation opposedSideBarLocationForBorder(Layouting::LayoutBorderLocation loc)
327 {
328  switch (loc) {
329  case Layouting::LayoutBorderLocation_North:
330  return SideBarLocation::South;
331  case Layouting::LayoutBorderLocation_East:
332  return SideBarLocation::West;
333  case Layouting::LayoutBorderLocation_West:
334  return SideBarLocation::East;
335  case Layouting::LayoutBorderLocation_South:
336  return SideBarLocation::North;
337  case Layouting::LayoutBorderLocation_All:
338  case Layouting::LayoutBorderLocation_Verticals:
339  case Layouting::LayoutBorderLocation_Horizontals:
340  case Layouting::LayoutBorderLocation_None:
341  break;
342  }
343 
344  qWarning() << Q_FUNC_INFO << "Unknown loc" << loc;
345  return SideBarLocation::None;
346 }
347 
348 static SideBarLocation sideBarLocationForBorder(Layouting::LayoutBorderLocations loc)
349 {
350  switch (loc) {
351  case Layouting::LayoutBorderLocation_North:
352  return SideBarLocation::North;
353  case Layouting::LayoutBorderLocation_East:
354  return SideBarLocation::East;
355  case Layouting::LayoutBorderLocation_West:
356  return SideBarLocation::West;
357  case Layouting::LayoutBorderLocation_South:
358  return SideBarLocation::South;
359  case Layouting::LayoutBorderLocation_All:
360  case Layouting::LayoutBorderLocation_Verticals:
361  case Layouting::LayoutBorderLocation_Horizontals:
362  case Layouting::LayoutBorderLocation_None:
363  break;
364  }
365 
366  return SideBarLocation::None;
367 }
368 
369 SideBarLocation MainWindowBase::Private::preferredSideBar(DockWidgetBase *dw) const
370 {
371  // TODO: Algorithm can still be made smarter
372 
373  Layouting::Item *item = q->layoutWidget()->itemForFrame(dw->d->frame());
374  if (!item) {
375  qWarning() << Q_FUNC_INFO << "No item for dock widget";
376  return SideBarLocation::None;
377  }
378 
379  const Layouting::LayoutBorderLocations borders = item->adjacentLayoutBorders();
380  const qreal aspectRatio = dw->width() / (std::max(1, dw->height()) * 1.0);
381 
383  if (borders == Layouting::LayoutBorderLocation_All) {
384  return aspectRatio > 1.0 ? SideBarLocation::South
386  }
387 
389  for (auto borderLoc : { Layouting::LayoutBorderLocation_North, Layouting::LayoutBorderLocation_East,
390  Layouting::LayoutBorderLocation_West, Layouting::LayoutBorderLocation_South }) {
391  if (borders == (Layouting::LayoutBorderLocation_All & ~borderLoc))
392  return opposedSideBarLocationForBorder(borderLoc);
393  }
394 
396  if ((borders & Layouting::LayoutBorderLocation_Verticals) == Layouting::LayoutBorderLocation_Verticals) {
397  // We could measure the distance to the top though.
398  return SideBarLocation::South;
399  }
400 
402  if ((borders & Layouting::LayoutBorderLocation_Horizontals) == Layouting::LayoutBorderLocation_Horizontals) {
403  // We could measure the distance to the left though.
404  return SideBarLocation::East;
405  }
406 
407  // 5. It's in a corner
408  if (borders == (Layouting::LayoutBorderLocation_West | Layouting::LayoutBorderLocation_South)) {
409  return aspectRatio > 1.0 ? SideBarLocation::South
411  } else if (borders == (Layouting::LayoutBorderLocation_East | Layouting::LayoutBorderLocation_South)) {
412  return aspectRatio > 1.0 ? SideBarLocation::South
414  } else if (borders == (Layouting::LayoutBorderLocation_West | Layouting::LayoutBorderLocation_North)) {
415  return aspectRatio > 1.0 ? SideBarLocation::North
417  } else if (borders == (Layouting::LayoutBorderLocation_East | Layouting::LayoutBorderLocation_North)) {
418  return aspectRatio > 1.0 ? SideBarLocation::North
420  }
421 
422 
423  {
424  // 6. It's only touching 1 border
426  if (loc != SideBarLocation::None)
427  return loc;
428  }
429 
430  // It's not touching any border, use aspect ratio.
431  return aspectRatio > 1.0 ? SideBarLocation::South
433 }
434 
435 void MainWindowBase::Private::updateOverlayGeometry(QSize suggestedSize)
436 {
437  if (!m_overlayedDockWidget)
438  return;
439 
440  SideBar *sb = q->sideBarForDockWidget(m_overlayedDockWidget);
441  if (!sb) {
442  qWarning() << Q_FUNC_INFO << "Expected a sidebar";
443  return;
444  }
445 
446  const QRect defaultGeometry = rectForOverlay(m_overlayedDockWidget->d->frame(), sb->location());
447  QRect newGeometry = defaultGeometry;
448 
449  Frame *frame = m_overlayedDockWidget->d->frame();
450 
451  if (suggestedSize.isValid() && !suggestedSize.isEmpty()) {
452  // Let's try to honour the suggested overlay size
453  switch (sb->location()) {
454  case SideBarLocation::North: {
455  const int maxHeight = q->height() - frame->pos().y() - 10; // gap
456  newGeometry.setHeight(qMin(suggestedSize.height(), maxHeight));
457  break;
458  }
459  case SideBarLocation::South: {
460  const int maxHeight = sb->pos().y() - m_layoutWidget->pos().y() - 10; // gap
461  const int bottom = newGeometry.bottom();
462  newGeometry.setHeight(qMin(suggestedSize.height(), maxHeight));
463  newGeometry.moveBottom(bottom);
464  break;
465  }
466  case SideBarLocation::East: {
467  const int maxWidth = sb->pos().x() - m_layoutWidget->pos().x() - 10; // gap
468  const int right = newGeometry.right();
469  newGeometry.setWidth(qMin(suggestedSize.width(), maxWidth));
470  newGeometry.moveRight(right);
471  break;
472  }
473  case SideBarLocation::West: {
474  const int maxWidth = q->width() - frame->pos().x() - 10; // gap
475  newGeometry.setWidth(qMin(suggestedSize.width(), maxWidth));
476  break;
477  }
479  qWarning() << Q_FUNC_INFO << "Unexpected sidebar value";
480  break;
481  }
482  }
483 
484  m_overlayedDockWidget->d->frame()->QWidgetAdapter::setGeometry(newGeometry);
485 }
486 
487 void MainWindowBase::Private::clearSideBars()
488 {
491  if (SideBar *sb = q->sideBar(loc))
492  sb->clear();
493  }
494 }
495 
497 {
498  moveToSideBar(dw, d->preferredSideBar(dw));
499 }
500 
502 {
504  return;
505 
506  if (SideBar *sb = sideBar(location)) {
507  QScopedValueRollback<bool> rollback(dw->d->m_isMovingToSideBar, true);
508  dw->forceClose();
509  sb->addDockWidget(dw);
510  } else {
511  // Shouldn't happen
512  qWarning() << Q_FUNC_INFO << "Minimization supported, probably disabled in Config::self().flags()";
513  }
514 }
515 
517 {
518  // First un-overlay it, if it's overlayed
519  if (dw == d->m_overlayedDockWidget)
521 
522  SideBar *sb = sideBarForDockWidget(dw);
523  if (!sb) {
524  // Doesn't happen
525  qWarning() << Q_FUNC_INFO << "Dock widget isn't in any sidebar";
526  return;
527  }
528 
529  sb->removeDockWidget(dw);
530  dw->setFloating(false); // dock it
531 }
532 
534 {
535  if (!dw || dw->isPersistentCentralDockWidget())
536  return;
537 
538  const SideBar *sb = sideBarForDockWidget(dw);
539  if (!sb) {
540  qWarning() << Q_FUNC_INFO << "You need to add the dock widget to the sidebar before you can overlay it";
541  return;
542  }
543 
544  if (d->m_overlayedDockWidget == dw) {
545  // Already overlayed
546  return;
547  }
548 
549  // We only support one overlay at a time, remove any existing overlay
551 
553  d->m_overlayedDockWidget = dw;
554  frame->addWidget(dw);
555  d->updateOverlayGeometry(dw->d->lastPosition()->lastOverlayedGeometry(sb->location()).size());
556 
557  frame->setAllowedResizeSides(d->allowedResizeSides(sb->location()));
558  frame->QWidgetAdapter::show();
559 
560  Q_EMIT dw->isOverlayedChanged(true);
561 }
562 
564 {
565  const bool wasOverlayed = d->m_overlayedDockWidget == dw;
566  clearSideBarOverlay(); // Because only 1 dock widget can be overlayed each time
567  if (!wasOverlayed) {
568  overlayOnSideBar(dw);
569  }
570 }
571 
573 {
574  if (!d->m_overlayedDockWidget)
575  return;
576 
577  Frame *frame = d->m_overlayedDockWidget->d->frame();
578  if (!frame) { // prophylactic check
579  d->m_overlayedDockWidget = nullptr;
580  return;
581  }
582 
583  const SideBarLocation loc = d->m_overlayedDockWidget->sideBarLocation();
584  d->m_overlayedDockWidget->d->lastPosition()->setLastOverlayedGeometry(
585  loc, frame->QWidgetAdapter::geometry());
586 
587  frame->unoverlay();
588 
589  if (deleteFrame) {
590  d->m_overlayedDockWidget->setParent(nullptr);
591  Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(false);
592  d->m_overlayedDockWidget = nullptr;
593  delete frame;
594  } else {
595  // No cleanup, just unset. When we drag the overlay it becomes a normal floating window
596  // meaning we reuse Frame. Don't delete it.
597  Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(false);
598  d->m_overlayedDockWidget = nullptr;
599  }
600 }
601 
603 {
606 
607  if (SideBar *sb = sideBar(loc)) {
608  if (sb->containsDockWidget(const_cast<DockWidgetBase *>(dw)))
609  return sb;
610  }
611  }
612 
613  return nullptr;
614 }
615 
617 {
618  return d->m_overlayedDockWidget;
619 }
620 
622 {
623  if (SideBar *sb = sideBar(loc)) {
624  return !sb->isEmpty(); // isVisible() is always true, but its height is 0 when empty.
625  }
626 
627  return false;
628 }
629 
631 {
634  if (sideBarIsVisible(loc))
635  return true;
636  }
637 
638  return false;
639 }
640 
642 {
643  return d->m_options & MainWindowOption_MDI;
644 }
645 
647 {
648  bool allClosed = true;
649 
650  const auto dockWidgets = d->m_layoutWidget->dockWidgets();
651  for (DockWidgetBase *dw : dockWidgets) {
652  Frame *frame = dw->d->frame();
653 
654  if (force) {
655  dw->forceClose();
656  } else {
657  const bool closed = dw->close();
658  allClosed = allClosed && closed;
659  }
660 
661  if (frame->beingDeletedLater()) {
662  // The dock widget was closed and this frame is empty, delete immediately instead of
663  // waiting. I'm not a big fan of deleting stuff later, as state becomes inconsistent
664 
665  // Empty frames are historically deleted later since they are triggered by mouse click
666  // on the title bar, and the title bar is inside the frame.
667  // When doing it programmatically we can delete immediately.
668 
669  delete frame;
670  }
671  }
672 
673  return allClosed;
674 }
675 
676 void MainWindowBase::setUniqueName(const QString &uniqueName)
677 {
678  if (uniqueName.isEmpty())
679  return;
680 
681  if (d->name.isEmpty()) {
682  d->name = uniqueName;
684  DockRegistry::self()->registerMainWindow(this);
685  } else {
686  qWarning() << Q_FUNC_INFO << "Already has a name." << this->uniqueName() << uniqueName;
687  }
688 }
689 
691 {
692  if (d->m_overlayedDockWidget)
693  d->updateOverlayGeometry(d->m_overlayedDockWidget->d->frame()->QWidgetAdapter::size());
694 }
695 
696 bool MainWindowBase::deserialize(const LayoutSaver::MainWindow &mw)
697 {
698  if (mw.options != options()) {
699  qWarning() << Q_FUNC_INFO << "Refusing to restore MainWindow with different options"
700  << "; expected=" << mw.options << "; has=" << options();
701  return false;
702  }
703 
704  if (d->affinities != mw.affinities) {
705  qWarning() << Q_FUNC_INFO << "Affinity name changed from" << d->affinities
706  << "; to" << mw.affinities;
707 
708  d->affinities = mw.affinities;
709  }
710 
711  const bool success = layoutWidget()->deserialize(mw.multiSplitterLayout);
712 
713  // Restore the SideBars
714  d->clearSideBars();
716  SideBar *sb = sideBar(loc);
717  if (!sb)
718  continue;
719 
720  const QStringList dockWidgets = mw.dockWidgetsPerSideBar.value(loc);
721  for (const QString &uniqueName : dockWidgets) {
722 
723  DockWidgetBase *dw = DockRegistry::self()->dockByName(uniqueName, DockRegistry::DockByNameFlag::CreateIfNotFound);
724  if (!dw) {
725  qWarning() << Q_FUNC_INFO << "Could not find dock widget" << uniqueName
726  << ". Won't restore it to sidebar";
727  continue;
728  }
729 
730  sb->addDockWidget(dw);
731  }
732  }
733 
734  // Commented-out for now, we don't want to restore the popup/overlay. popups are perishable
735  // if (!mw.overlayedDockWidget.isEmpty())
736  // overlayOnSideBar(DockRegistry::self()->dockByName(mw.overlayedDockWidget));
737 
738  return success;
739 }
740 
741 LayoutSaver::MainWindow MainWindowBase::serialize() const
742 {
743  LayoutSaver::MainWindow m;
744 
745  m.options = options();
746  m.geometry = windowGeometry();
747  m.normalGeometry = normalGeometry();
748  m.isVisible = isVisible();
749  m.uniqueName = uniqueName();
750  m.screenIndex = screenNumberForWidget(this);
751  m.screenSize = screenSizeForWidget(this);
752  m.multiSplitterLayout = layoutWidget()->serialize();
753  m.affinities = d->affinities;
754  m.windowState = windowHandle() ? windowHandle()->windowState()
756 
758  if (SideBar *sb = sideBar(loc)) {
759  const QStringList dockwidgets = sb->serialize();
760  if (!dockwidgets.isEmpty())
761  m.dockWidgetsPerSideBar.insert(loc, dockwidgets);
762  }
763  }
764 
765  return m;
766 }
767 
769 {
770  if (QWindow *window = windowHandle())
771  return window->geometry();
772 
773  return window()->geometry();
774 }
775 
777 {
778  return d->m_overlayMargin;
779 }
780 
782 {
783  if (margin == d->m_overlayMargin) {
784  return;
785  }
786 
787  d->m_overlayMargin = margin;
789 }
790 
792 {
793  if (!d->supportsPersistentCentralWidget()) {
794  qWarning() << "MainWindow::setPersistentCentralWidget() requires MainWindowOption_HasCentralWidget";
795  return;
796  }
797 
798  auto dw = d->m_persistentCentralDockWidget;
799  if (dw) {
800  dw->setWidget(widget);
801  } else {
802  qWarning() << Q_FUNC_INFO << "Unexpected null central dock widget";
803  }
804 }
805 
807 {
808  if (auto dw = d->m_persistentCentralDockWidget)
809  return dw->widget();
810 
811  return nullptr;
812 }
813 
815 {
816  d->m_layoutWidget->onCloseEvent(e);
817 }
QPointer
KDDockWidgets::MainWindowBase::clearSideBarOverlay
Q_INVOKABLE void clearSideBarOverlay(bool deleteFrame=true)
closes any overlayed dock widget. The sidebar still displays them as button.
Definition: MainWindowBase.cpp:572
KDDockWidgets::MainWindowBase::setUniqueName
void setUniqueName(const QString &uniqueName)
Definition: MainWindowBase.cpp:676
Qt::right
QTextStream & right(QTextStream &stream)
QWidget::window
QWidget * window() const const
DockWidgetQuick.h
Represents a dock widget.
QRect::setWidth
void setWidth(int width)
QMainWindow
KDDockWidgets::MainWindowBase::addDockWidget
Q_INVOKABLE void addDockWidget(KDDockWidgets::DockWidgetBase *dockWidget, KDDockWidgets::Location location, KDDockWidgets::DockWidgetBase *relativeTo=nullptr, KDDockWidgets::InitialOption initialOption={})
Docks a DockWidget into this main window.
Definition: MainWindowBase.cpp:168
QMargins::bottom
int bottom() const const
QSize::isValid
bool isValid() const const
KDDockWidgets::MainWindowBase::frameCountChanged
void frameCountChanged(int)
emitted when the number of docked frames changes Note that we're using the "Frame" nomenculature inst...
KDDockWidgets::MainWindowBase::setPersistentCentralWidget
Q_INVOKABLE void setPersistentCentralWidget(KDDockWidgets::QWidgetOrQuick *widget)
Sets a persistent central widget. It can't be detached.
Definition: MainWindowBase.cpp:791
KDDockWidgets::DockWidgetBase::affinities
QStringList affinities() const
Returns the affinity name. Empty by default.
Definition: DockWidgetBase.cpp:385
QRect::moveBottom
void moveBottom(int y)
KDDockWidgets::MainWindowBase::isMDI
bool isMDI
Definition: MainWindowBase.h:61
QRect
QRect::right
int right() const const
KDDockWidgets::DockWidgetBase::setFloating
bool setFloating(bool floats)
setter to make the dock widget float or dock.
Definition: DockWidgetBase.cpp:179
QObject::Q_EMIT
Q_EMITQ_EMIT
QList::removeAll
int removeAll(const T &value)
KDDockWidgets::InitialOption
Struct describing the preferred dock widget size and visibility when adding it to a layout.
Definition: KDDockWidgets.h:101
KDDockWidgets::MainWindowBase::layoutWidget
LayoutWidget * layoutWidget() const
Definition: MainWindowBase.cpp:205
KDDockWidgets::DockWidgetBase::forceClose
Q_INVOKABLE void forceClose()
Like QWidget::close() but the hosted widget won't be asked if we should close.
Definition: DockWidgetBase.cpp:367
KDDockWidgets::MainWindowBase::overlayMargin
int overlayMargin
Definition: MainWindowBase.h:62
QSize::isEmpty
bool isEmpty() const const
QWindow
QWidget
KDDockWidgets::MainWindowBase::closeDockWidgets
Q_INVOKABLE bool closeDockWidgets(bool force=false)
Closes all dock widgets which are docked into this main window This is convenience to calling DockWid...
Definition: MainWindowBase.cpp:646
KDDockWidgets::MainWindowBase::affinities
QStringList affinities
Definition: MainWindowBase.h:58
QRect::width
int width() const const
KDDockWidgets::Location
Location
Definition: KDDockWidgets.h:44
KDDockWidgets::SideBarLocation::West
@ West
QSize
QRect::x
int x() const const
QRect::y
int y() const const
KDDockWidgets::MainWindowBase::layoutEqually
Q_INVOKABLE void layoutEqually()
layouts all the widgets so they have an equal size within their parent container
Definition: MainWindowBase.cpp:238
KDDockWidgets::DockWidgetBase::isPersistentCentralDockWidget
bool isPersistentCentralDockWidget() const
Returns whether this dock widget is the main window persistent central widget This only applies when ...
Definition: DockWidgetBase.cpp:950
DockWidget.h
Represents a dock widget.
KDDockWidgets::MainWindowBase::addDockWidgetAsTab
Q_INVOKABLE void addDockWidgetAsTab(KDDockWidgets::DockWidgetBase *dockwidget)
Docks a DockWidget into the central frame, tabbed.
Definition: MainWindowBase.cpp:136
KDDockWidgets::DockWidgetBase::Option_NotDockable
@ Option_NotDockable
The DockWidget can't be docked, it's always floating.
Definition: DockWidgetBase.h:77
QSize::width
int width() const const
KDDockWidgets::MainWindowBase::anySideBarIsVisible
bool anySideBarIsVisible() const
Returns whether any side bar is visible.
Definition: MainWindowBase.cpp:630
KDDockWidgets::CursorPosition_Left
@ CursorPosition_Left
Definition: KDDockWidgets.h:256
KDDockWidgets::CursorPosition_Bottom
@ CursorPosition_Bottom
Definition: KDDockWidgets.h:259
KDDockWidgets::CursorPosition_Undefined
@ CursorPosition_Undefined
Definition: KDDockWidgets.h:255
QObject::connect
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KDDockWidgets::MainWindowBase::overlayOnSideBar
Q_INVOKABLE void overlayOnSideBar(KDDockWidgets::DockWidgetBase *)
Shows the dock widget overlayed on top of the main window, placed next to the sidebar.
Definition: MainWindowBase.cpp:533
KDDockWidgets::DockWidgetBase::widget
QObject * widget
Definition: DockWidgetBase.h:67
MainWindowBase.h
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
KDDockWidgets::MainWindowBase::options
KDDockWidgets::MainWindowOptions options
Definition: MainWindowBase.h:60
KDDockWidgets::FrameOption_IsOverlayed
@ FrameOption_IsOverlayed
Definition: KDDockWidgets.h:277
KDDockWidgets::MainWindowBase::sideBar
virtual SideBar * sideBar(SideBarLocation) const =0
QWidget::isVisible
bool isVisible() const const
QMargins::right
int right() const const
Qt::WindowFlags
typedef WindowFlags
KDDockWidgets::MainWindowOption_MDI
@ MainWindowOption_MDI
Makes the MainWindow always have a central frame, for tabbing documents
Definition: KDDockWidgets.h:56
QRect::bottom
int bottom() const const
KDDockWidgets::DockWidgetBase::setWidget
virtual void setWidget(QWidgetOrQuick *widget)
sets the widget which this dock widget hosts.
Definition: DockWidgetBase.cpp:148
QCloseEvent
QSize::height
int height() const const
QRect::setHeight
void setHeight(int height)
KDDockWidgets::SideBarLocation::None
@ None
KDDockWidgets::MainWindowOption_HasCentralWidget
@ MainWindowOption_HasCentralWidget
The layout will be MDI. DockWidgets can have arbitrary positions, not restricted by any layout
Definition: KDDockWidgets.h:57
QString
createLayoutWidget
static LayoutWidget * createLayoutWidget(MainWindowBase *mainWindow, MainWindowOptions options)
Definition: MainWindowBase.cpp:46
KDDockWidgets::MainWindowBase::~MainWindowBase
~MainWindowBase() override
Definition: MainWindowBase.cpp:130
QString::isEmpty
bool isEmpty() const const
KDDockWidgets::MainWindowBase::multiSplitter
MultiSplitter * multiSplitter() const
Definition: MainWindowBase.cpp:200
QRect::moveTop
void moveTop(int y)
KDDockWidgets::MainWindowBase::mdiLayoutWidget
MDILayoutWidget * mdiLayoutWidget() const
Definition: MainWindowBase.cpp:210
KDDockWidgets::MainWindowBase::dropArea
DropAreaWithCentralFrame * dropArea() const
Definition: MainWindowBase.cpp:195
KDDockWidgets::MainWindowBase::uniqueNameChanged
void uniqueNameChanged()
KDDockWidgets::MainWindowBase::uniqueName
QString uniqueName
Definition: MainWindowBase.h:59
KDDockWidgets::MainWindowBase::persistentCentralWidget
QWidgetOrQuick * persistentCentralWidget() const
Definition: MainWindowBase.cpp:806
QList::isEmpty
bool isEmpty() const const
Qt::WindowNoState
WindowNoState
KDDockWidgets::Config::frameworkWidgetFactory
FrameworkWidgetFactory * frameworkWidgetFactory() const
getter for the framework widget factory
Definition: Config.cpp:145
KDDockWidgets::MainWindowBase::toggleOverlayOnSideBar
Q_INVOKABLE void toggleOverlayOnSideBar(KDDockWidgets::DockWidgetBase *)
Shows or hides an overlay. It's assumed the dock widget is already in a side-bar.
Definition: MainWindowBase.cpp:563
opposedSideBarLocationForBorder
static SideBarLocation opposedSideBarLocationForBorder(Layouting::LayoutBorderLocation loc)
Definition: MainWindowBase.cpp:326
KDDockWidgets::MainWindowBase::setOverlayMargin
void setOverlayMargin(int margin)
Sets the margin used by overlay docks. Does not modify currently overlayed docks.
Definition: MainWindowBase.cpp:781
KDDockWidgets::MainWindowBase::overlayMarginChanged
void overlayMarginChanged(int)
KDDockWidgets::MainWindowBase::onCloseEvent
void onCloseEvent(QCloseEvent *)
Definition: MainWindowBase.cpp:814
KDDockWidgets::MainWindowBase::sideBarIsVisible
Q_INVOKABLE bool sideBarIsVisible(KDDockWidgets::SideBarLocation) const
Returns whether the specified sidebar is visible.
Definition: MainWindowBase.cpp:621
QMargins
KDDockWidgets::FrameworkWidgetFactory::createFrame
virtual Frame * createFrame(QWidgetOrQuick *parent=nullptr, FrameOptions options=FrameOption_None) const =0
Called internally by the framework to create a Frame class Override to provide your own Frame sub-cla...
KDDockWidgets::SideBarLocation
SideBarLocation
Each main window supports 4 sidebars.
Definition: KDDockWidgets.h:208
QList::insert
void insert(int i, const T &value)
KDDockWidgets::SideBarLocation::East
@ East
KDDockWidgets::SideBarLocation::South
@ South
QWidget::windowHandle
QWindow * windowHandle() const const
KDDockWidgets::MainWindowBase::setAffinities
void setAffinities(const QStringList &names)
Sets the affinities names. Dock widgets can only dock into main windows of the same affinity.
Definition: MainWindowBase.cpp:215
KDDockWidgets::MainWindowBase::moveToSideBar
Q_INVOKABLE void moveToSideBar(KDDockWidgets::DockWidgetBase *)
Moves the dock widget into one of the MainWindow's sidebar. Means the dock widget is removed from the...
Definition: MainWindowBase.cpp:496
QRect::height
int height() const const
KDDockWidgets::MainWindowBase::sideBarForDockWidget
Q_INVOKABLE KDDockWidgets::SideBar * sideBarForDockWidget(const KDDockWidgets::DockWidgetBase *) const
Returns the sidebar this dockwidget is in. nullptr if not in any.
Definition: MainWindowBase.cpp:602
KDDockWidgets::SideBarLocation::North
@ North
QMargins::left
int left() const const
QResizeEvent
KDDockWidgets::DockWidgetBase
The DockWidget base-class. DockWidget and DockWidgetBase are only split in two so we can share some c...
Definition: DockWidgetBase.h:61
KDDockWidgets::CursorPosition_Right
@ CursorPosition_Right
Definition: KDDockWidgets.h:257
KDDockWidgets
Definition: Config.cpp:37
QScopedValueRollback
KDDockWidgets::DockWidgetType
KDDockWidgets::DockWidget DockWidgetType
Definition: QWidgetAdapter.h:51
QWidget::geometry
geometry
KDDockWidgets::MainWindowBase::windowGeometry
QRect windowGeometry() const
Returns the window geometry This is usually the same as MainWindowBase::geometry() But fixes the foll...
Definition: MainWindowBase.cpp:768
KDDockWidgets::MainWindowBase::layoutParentContainerEqually
Q_INVOKABLE void layoutParentContainerEqually(KDDockWidgets::DockWidgetBase *dockWidget)
like layoutEqually() but starts with the container that has dockWidget. While layoutEqually() starts ...
Definition: MainWindowBase.cpp:243
KDDockWidgets::MainWindowBase
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
Definition: MainWindowBase.h:56
QWindow::windowState
Qt::WindowState windowState() const const
QRect::moveLeft
void moveLeft(int x)
sideBarLocationForBorder
static SideBarLocation sideBarLocationForBorder(Layouting::LayoutBorderLocations loc)
Definition: MainWindowBase.cpp:348
KDDockWidgets::MainWindowBase::onResized
void onResized(QResizeEvent *)
Definition: MainWindowBase.cpp:690
KDDockWidgets::DockWidgetBase::options
KDDockWidgets::DockWidgetBase::Options options
Definition: DockWidgetBase.h:69
KDDockWidgets::MainWindowBase::restoreFromSideBar
Q_INVOKABLE void restoreFromSideBar(KDDockWidgets::DockWidgetBase *)
Removes the dock widget from the sidebar and docks it into the main window again.
Definition: MainWindowBase.cpp:516
QMargins::top
int top() const const
QList::value
T value(int i) const const
QPoint
QWidget::normalGeometry
normalGeometry
KDDockWidgets::MainWindowBase::MainWindowBase
MainWindowBase(const QString &uniqueName, MainWindowOptions options=MainWindowOption_HasCentralFrame, WidgetType *parent=nullptr, Qt::WindowFlags flags=Qt::WindowFlags())
Definition: MainWindowBase.cpp:119
KDDockWidgets::Config::self
static Config & self()
returns the singleton Config instance
Definition: Config.cpp:84
FrameworkWidgetFactory.h
A factory class for allowing the user to customize some internal widgets.
QStringList
KDDockWidgets::MainWindowOption_HasCentralFrame
@ MainWindowOption_HasCentralFrame
No option set
Definition: KDDockWidgets.h:55
KDDockWidgets::CursorPosition_Top
@ CursorPosition_Top
Definition: KDDockWidgets.h:258
QRect::moveRight
void moveRight(int x)
KDDockWidgets::MainWindowBase::overlayedDockWidget
DockWidgetBase * overlayedDockWidget() const
returns the dock widget which is currently overlayed. nullptr if none. This is only relevant when usi...
Definition: MainWindowBase.cpp:616
KDDockWidgets::DockWidgetBase::isOverlayedChanged
void isOverlayedChanged(bool)
emitted when isOverlayed changes

© 2019-2022 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 on Thu Sep 15 2022 00:16:29 for KDDockWidgets API Documentation by doxygen 1.8.20