KDDockWidgets API Documentation  1.5
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 
34 // Or we can have a createDockWidget() in the factory
35 #ifdef KDDOCKWIDGETS_QTQUICK
36 # include "DockWidgetQuick.h"
37 #else
38 # include "DockWidget.h"
39 #endif
40 
41 using namespace KDDockWidgets;
42 
43 static LayoutWidget *createLayoutWidget(MainWindowBase *mainWindow, MainWindowOptions options)
44 {
45  if (options & MainWindowOption_MDI)
46  return new MDILayoutWidget(mainWindow);
47 
48  return new DropAreaWithCentralFrame(mainWindow, options);
49 }
50 
51 class MainWindowBase::Private
52 {
53 public:
54  explicit Private(MainWindowBase *mainWindow, const QString &uniqueName, MainWindowOptions options)
55  : m_options(options)
56  , q(mainWindow)
57  , m_layoutWidget(createLayoutWidget(mainWindow, options))
58  , m_persistentCentralDockWidget(createPersistentCentralDockWidget(uniqueName))
59  {
60  }
61 
62  bool supportsCentralFrame() const
63  {
64  return m_options & MainWindowOption_HasCentralFrame;
65  }
66 
67  bool supportsPersistentCentralWidget() const
68  {
69  if (!dropArea()) {
70  // This is the MDI case
71  return false;
72  }
73 
75  }
76 
77  DockWidgetBase* createPersistentCentralDockWidget(const QString &uniqueName) const
78  {
79  if (!supportsPersistentCentralWidget())
80  return nullptr;
81 
82  auto dw = new DockWidgetType(QStringLiteral("%1-persistentCentralDockWidget").arg(uniqueName));
83  dw->dptr()->m_isPersistentCentralDockWidget = true;
84  Frame *frame = dropArea()->m_centralFrame;
85  if (!frame) {
86  qWarning() << Q_FUNC_INFO << "Expected central frame";
87  return nullptr;
88  }
89 
90  frame->addWidget(dw);
91  return dw;
92  }
93 
94  DropAreaWithCentralFrame *dropArea() const
95  {
96  return qobject_cast<DropAreaWithCentralFrame *>(m_layoutWidget);
97  }
98 
99  CursorPositions allowedResizeSides(SideBarLocation loc) const;
100 
101  QRect rectForOverlay(Frame *, SideBarLocation) const;
102  SideBarLocation preferredSideBar(DockWidgetBase *) const;
103  void updateOverlayGeometry(QSize suggestedSize);
104  void clearSideBars();
105 
106  QString name;
108  const MainWindowOptions m_options;
109  MainWindowBase *const q;
110  QPointer<DockWidgetBase> m_overlayedDockWidget;
111  LayoutWidget *const m_layoutWidget;
112  DockWidgetBase *const m_persistentCentralDockWidget;
113 };
114 
115 MainWindowBase::MainWindowBase(const QString &uniqueName, KDDockWidgets::MainWindowOptions options,
116  WidgetType *parent, Qt::WindowFlags flags)
117  : QMainWindowOrQuick(parent, flags)
118  , d(new Private(this, uniqueName, options))
119 {
121 
122  connect(d->m_layoutWidget, &LayoutWidget::visibleWidgetCountChanged, this,
124 }
125 
127 {
128  DockRegistry::self()->unregisterMainWindow(this);
129  delete d;
130 }
131 
133 {
134  Q_ASSERT(widget);
135  qCDebug(addwidget) << Q_FUNC_INFO << widget;
136 
137  if (!DockRegistry::self()->affinitiesMatch(d->affinities, widget->affinities())) {
138  qWarning() << Q_FUNC_INFO << "Refusing to dock widget with incompatible affinity."
139  << widget->affinities() << affinities();
140  return;
141  }
142 
143  if (widget->options() & DockWidgetBase::Option_NotDockable) {
144  qWarning() << Q_FUNC_INFO << "Refusing to dock non-dockable widget" << widget;
145  return;
146  }
147 
148  if (isMDI()) {
149  // Not applicable to MDI
150  return;
151  }
152 
153  if (d->supportsPersistentCentralWidget()) {
154  qWarning() << Q_FUNC_INFO << "Not supported with MainWindowOption_HasCentralWidget."
155  << "MainWindowOption_HasCentralWidget can only have 1 widget in the center."
156  << "Use MainWindowOption_HasCentralFrame instead, which is similar but supports tabbing";
157  } else if (d->supportsCentralFrame()) {
158  dropArea()->m_centralFrame->addWidget(widget);
159  } else {
160  qWarning() << Q_FUNC_INFO << "Not supported without MainWindowOption_HasCentralFrame";
161  }
162 }
163 
165  DockWidgetBase *relativeTo, InitialOption option)
166 {
168  qWarning() << Q_FUNC_INFO << "Refusing to dock non-dockable widget" << dw;
169  return;
170  }
171 
172  if (isMDI()) {
173  // Not applicable to MDI
174  return;
175  }
176 
177  dropArea()->addDockWidget(dw, location, relativeTo, option);
178 }
179 
181 {
182  return d->name;
183 }
184 
185 MainWindowOptions MainWindowBase::options() const
186 {
187  return d->m_options;
188 }
189 
190 DropAreaWithCentralFrame *MainWindowBase::dropArea() const
191 {
192  return qobject_cast<DropAreaWithCentralFrame *>(d->m_layoutWidget);
193 }
194 
195 MultiSplitter *MainWindowBase::multiSplitter() const
196 {
197  return dropArea();
198 }
199 
200 LayoutWidget *MainWindowBase::layoutWidget() const
201 {
202  return d->m_layoutWidget;
203 }
204 
205 MDILayoutWidget *MainWindowBase::mdiLayoutWidget() const
206 {
207  return qobject_cast<MDILayoutWidget *>(layoutWidget());
208 }
209 
210 void MainWindowBase::setAffinities(const QStringList &affinityNames)
211 {
212  QStringList affinities = affinityNames;
214 
215  if (d->affinities == affinities)
216  return;
217 
218  if (!d->affinities.isEmpty()) {
219  qWarning() << Q_FUNC_INFO
220  << "Affinity is already set, refusing to change."
221  << "Submit a feature request with a good justification.";
222  return;
223  }
224 
225  d->affinities = affinities;
226 }
227 
229 {
230  return d->affinities;
231 }
232 
234 {
235  dropArea()->layoutEqually();
236 }
237 
239 {
240  dropArea()->layoutParentContainerEqually(dockWidget);
241 }
242 
243 CursorPositions MainWindowBase::Private::allowedResizeSides(SideBarLocation loc) const
244 {
245  // When a sidebar is on top, you can only resize its bottom.
246  // and so forth...
247 
248  switch (loc) {
250  return CursorPosition_Bottom;
252  return CursorPosition_Left;
254  return CursorPosition_Right;
256  return CursorPosition_Top;
259  }
260 
262 }
263 
264 QRect MainWindowBase::Private::rectForOverlay(Frame *frame, SideBarLocation location) const
265 {
266  SideBar *sb = q->sideBar(location);
267  if (!sb)
268  return {};
269 
270  const QRect centralAreaGeo = q->centralAreaGeometry();
271  const QMargins centerWidgetMargins = q->centerWidgetMargins();
272 
273  QRect rect;
274  const int margin = 1;
275  switch (location) {
277  case SideBarLocation::South: {
278 
279  SideBar *leftSideBar = q->sideBar(SideBarLocation::West);
280  SideBar *rightSideBar = q->sideBar(SideBarLocation::East);
281  const int leftSideBarWidth = (leftSideBar && leftSideBar->isVisible()) ? leftSideBar->width()
282  : 0;
283  const int rightSideBarWidth = (rightSideBar && rightSideBar->isVisible()) ? rightSideBar->width()
284  : 0;
285  rect.setHeight(qMax(300, frame->minSize().height()));
286  rect.setWidth(centralAreaGeo.width() - margin * 2 - leftSideBarWidth - rightSideBarWidth);
287  rect.moveLeft(margin + leftSideBarWidth);
288  if (location == SideBarLocation::South) {
289  rect.moveTop(centralAreaGeo.bottom() - centerWidgetMargins.bottom() - rect.height() - sb->height());
290  } else {
291  rect.moveTop(centralAreaGeo.y() + sb->height() + centerWidgetMargins.top());
292  }
293  break;
294  }
296  case SideBarLocation::East: {
297  SideBar *topSideBar = q->sideBar(SideBarLocation::North);
298  SideBar *bottomSideBar = q->sideBar(SideBarLocation::South);
299  const int topSideBarHeight = (topSideBar && topSideBar->isVisible()) ? topSideBar->height()
300  : 0;
301  const int bottomSideBarHeight = (bottomSideBar && bottomSideBar->isVisible()) ? bottomSideBar->height()
302  : 0;
303  rect.setWidth(qMax(300, frame->minSize().width()));
304  rect.setHeight(centralAreaGeo.height() - topSideBarHeight - bottomSideBarHeight - centerWidgetMargins.top() - centerWidgetMargins.bottom());
305  rect.moveTop(sb->mapTo(q, QPoint(0, 0)).y() + topSideBarHeight - 1);
306  if (location == SideBarLocation::East) {
307  rect.moveLeft(centralAreaGeo.width() - rect.width() - sb->width() - centerWidgetMargins.right() - margin);
308  } else {
309  rect.moveLeft(margin + centralAreaGeo.x() + centerWidgetMargins.left() + sb->width());
310  }
311 
312  break;
313  }
315  break;
316  }
317 
318  return rect;
319 }
320 
321 static SideBarLocation opposedSideBarLocationForBorder(Layouting::LayoutBorderLocation loc)
322 {
323  switch (loc) {
324  case Layouting::LayoutBorderLocation_North:
325  return SideBarLocation::South;
326  case Layouting::LayoutBorderLocation_East:
327  return SideBarLocation::West;
328  case Layouting::LayoutBorderLocation_West:
329  return SideBarLocation::East;
330  case Layouting::LayoutBorderLocation_South:
331  return SideBarLocation::North;
332  case Layouting::LayoutBorderLocation_All:
333  case Layouting::LayoutBorderLocation_Verticals:
334  case Layouting::LayoutBorderLocation_Horizontals:
335  case Layouting::LayoutBorderLocation_None:
336  break;
337  }
338 
339  qWarning() << Q_FUNC_INFO << "Unknown loc" << loc;
340  return SideBarLocation::None;
341 }
342 
343 static SideBarLocation sideBarLocationForBorder(Layouting::LayoutBorderLocations loc)
344 {
345  switch (loc) {
346  case Layouting::LayoutBorderLocation_North:
347  return SideBarLocation::North;
348  case Layouting::LayoutBorderLocation_East:
349  return SideBarLocation::East;
350  case Layouting::LayoutBorderLocation_West:
351  return SideBarLocation::West;
352  case Layouting::LayoutBorderLocation_South:
353  return SideBarLocation::South;
354  case Layouting::LayoutBorderLocation_All:
355  case Layouting::LayoutBorderLocation_Verticals:
356  case Layouting::LayoutBorderLocation_Horizontals:
357  case Layouting::LayoutBorderLocation_None:
358  break;
359  }
360 
361  return SideBarLocation::None;
362 }
363 
364 SideBarLocation MainWindowBase::Private::preferredSideBar(DockWidgetBase *dw) const
365 {
366  // TODO: Algorithm can still be made smarter
367 
368  Layouting::Item *item = q->layoutWidget()->itemForFrame(dw->d->frame());
369  if (!item) {
370  qWarning() << Q_FUNC_INFO << "No item for dock widget";
371  return SideBarLocation::None;
372  }
373 
374  const Layouting::LayoutBorderLocations borders = item->adjacentLayoutBorders();
375  const qreal aspectRatio = dw->width() / (std::max(1, dw->height()) * 1.0);
376 
378  if (borders == Layouting::LayoutBorderLocation_All) {
379  return aspectRatio > 1.0 ? SideBarLocation::South
381  }
382 
384  for (auto borderLoc : { Layouting::LayoutBorderLocation_North, Layouting::LayoutBorderLocation_East,
385  Layouting::LayoutBorderLocation_West, Layouting::LayoutBorderLocation_South }) {
386  if (borders == (Layouting::LayoutBorderLocation_All & ~borderLoc))
387  return opposedSideBarLocationForBorder(borderLoc);
388  }
389 
391  if ((borders & Layouting::LayoutBorderLocation_Verticals) == Layouting::LayoutBorderLocation_Verticals) {
392  // We could measure the distance to the top though.
393  return SideBarLocation::South;
394  }
395 
397  if ((borders & Layouting::LayoutBorderLocation_Horizontals) == Layouting::LayoutBorderLocation_Horizontals) {
398  // We could measure the distance to the left though.
399  return SideBarLocation::East;
400  }
401 
402  // 5. It's in a corner
403  if (borders == (Layouting::LayoutBorderLocation_West | Layouting::LayoutBorderLocation_South)) {
404  return aspectRatio > 1.0 ? SideBarLocation::South
406  } else if (borders == (Layouting::LayoutBorderLocation_East | Layouting::LayoutBorderLocation_South)) {
407  return aspectRatio > 1.0 ? SideBarLocation::South
409  } else if (borders == (Layouting::LayoutBorderLocation_West | Layouting::LayoutBorderLocation_North)) {
410  return aspectRatio > 1.0 ? SideBarLocation::North
412  } else if (borders == (Layouting::LayoutBorderLocation_East | Layouting::LayoutBorderLocation_North)) {
413  return aspectRatio > 1.0 ? SideBarLocation::North
415  }
416 
417 
418  {
419  // 6. It's only touching 1 border
421  if (loc != SideBarLocation::None)
422  return loc;
423  }
424 
425  // It's not touching any border, use aspect ratio.
426  return aspectRatio > 1.0 ? SideBarLocation::South
428 }
429 
430 void MainWindowBase::Private::updateOverlayGeometry(QSize suggestedSize)
431 {
432  if (!m_overlayedDockWidget)
433  return;
434 
435  SideBar *sb = q->sideBarForDockWidget(m_overlayedDockWidget);
436  if (!sb) {
437  qWarning() << Q_FUNC_INFO << "Expected a sidebar";
438  return;
439  }
440 
441  const QRect defaultGeometry = rectForOverlay(m_overlayedDockWidget->d->frame(), sb->location());
442  QRect newGeometry = defaultGeometry;
443 
444  Frame *frame = m_overlayedDockWidget->d->frame();
445 
446  if (suggestedSize.isValid() && !suggestedSize.isEmpty()) {
447  // Let's try to honour the suggested overlay size
448  switch (sb->location()) {
449  case SideBarLocation::North: {
450  const int maxHeight = q->height() - frame->pos().y() - 10; // gap
451  newGeometry.setHeight(qMin(suggestedSize.height(), maxHeight));
452  break;
453  }
454  case SideBarLocation::South: {
455  const int maxHeight = sb->pos().y() - m_layoutWidget->pos().y() - 10; // gap
456  const int bottom = newGeometry.bottom();
457  newGeometry.setHeight(qMin(suggestedSize.height(), maxHeight));
458  newGeometry.moveBottom(bottom);
459  break;
460  }
461  case SideBarLocation::East: {
462  const int maxWidth = sb->pos().x() - m_layoutWidget->pos().x() - 10; // gap
463  const int right = newGeometry.right();
464  newGeometry.setWidth(qMin(suggestedSize.width(), maxWidth));
465  newGeometry.moveRight(right);
466  break;
467  }
468  case SideBarLocation::West: {
469  const int maxWidth = q->width() - frame->pos().x() - 10; // gap
470  newGeometry.setWidth(qMin(suggestedSize.width(), maxWidth));
471  break;
472  }
474  qWarning() << Q_FUNC_INFO << "Unexpected sidebar value";
475  break;
476  }
477  }
478 
479  m_overlayedDockWidget->d->frame()->QWidgetAdapter::setGeometry(newGeometry);
480 }
481 
482 void MainWindowBase::Private::clearSideBars()
483 {
486  if (SideBar *sb = q->sideBar(loc))
487  sb->clear();
488  }
489 }
490 
492 {
493  moveToSideBar(dw, d->preferredSideBar(dw));
494 }
495 
497 {
499  return;
500 
501  if (SideBar *sb = sideBar(location)) {
502  QScopedValueRollback<bool> rollback(dw->d->m_isMovingToSideBar, true);
503  dw->forceClose();
504  sb->addDockWidget(dw);
505  } else {
506  // Shouldn't happen
507  qWarning() << Q_FUNC_INFO << "Minimization supported, probably disabled in Config::self().flags()";
508  }
509 }
510 
512 {
513  // First un-overlay it, if it's overlayed
514  if (dw == d->m_overlayedDockWidget)
516 
517  SideBar *sb = sideBarForDockWidget(dw);
518  if (!sb) {
519  // Doesn't happen
520  qWarning() << Q_FUNC_INFO << "Dock widget isn't in any sidebar";
521  return;
522  }
523 
524  sb->removeDockWidget(dw);
525  dw->setFloating(false); // dock it
526 }
527 
529 {
530  if (!dw || dw->isPersistentCentralDockWidget())
531  return;
532 
533  const SideBar *sb = sideBarForDockWidget(dw);
534  if (!sb) {
535  qWarning() << Q_FUNC_INFO << "You need to add the dock widget to the sidebar before you can overlay it";
536  return;
537  }
538 
539  if (d->m_overlayedDockWidget == dw) {
540  // Already overlayed
541  return;
542  }
543 
544  // We only support one overlay at a time, remove any existing overlay
546 
548  d->m_overlayedDockWidget = dw;
549  frame->addWidget(dw);
550  d->updateOverlayGeometry(dw->d->lastPositions().lastOverlayedGeometry(sb->location()).size());
551 
552  frame->setAllowedResizeSides(d->allowedResizeSides(sb->location()));
553  frame->QWidgetAdapter::show();
554 
555  Q_EMIT dw->isOverlayedChanged(true);
556 }
557 
559 {
560  const bool wasOverlayed = d->m_overlayedDockWidget == dw;
561  clearSideBarOverlay(); // Because only 1 dock widget can be overlayed each time
562  if (!wasOverlayed) {
563  overlayOnSideBar(dw);
564  }
565 }
566 
568 {
569  if (!d->m_overlayedDockWidget)
570  return;
571 
572  Frame *frame = d->m_overlayedDockWidget->d->frame();
573  if (!frame) { // prophylactic check
574  d->m_overlayedDockWidget = nullptr;
575  return;
576  }
577 
578  const SideBarLocation loc = d->m_overlayedDockWidget->sideBarLocation();
579  d->m_overlayedDockWidget->d->lastPositions().setLastOverlayedGeometry(
580  loc, frame->QWidgetAdapter::geometry());
581 
582  frame->unoverlay();
583 
584  if (deleteFrame) {
585  d->m_overlayedDockWidget->setParent(nullptr);
586  Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(false);
587  d->m_overlayedDockWidget = nullptr;
588  delete frame;
589  } else {
590  // No cleanup, just unset. When we drag the overlay it becomes a normal floating window
591  // meaning we reuse Frame. Don't delete it.
592  Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(false);
593  d->m_overlayedDockWidget = nullptr;
594  }
595 }
596 
598 {
601 
602  if (SideBar *sb = sideBar(loc)) {
603  if (sb->containsDockWidget(const_cast<DockWidgetBase *>(dw)))
604  return sb;
605  }
606  }
607 
608  return nullptr;
609 }
610 
612 {
613  return d->m_overlayedDockWidget;
614 }
615 
617 {
618  if (SideBar *sb = sideBar(loc)) {
619  return !sb->isEmpty(); // isVisible() is always true, but its height is 0 when empty.
620  }
621 
622  return false;
623 }
624 
626 {
629  if (sideBarIsVisible(loc))
630  return true;
631  }
632 
633  return false;
634 }
635 
637 {
638  return d->m_options & MainWindowOption_MDI;
639 }
640 
642 {
643  bool allClosed = true;
644 
645  const auto dockWidgets = d->m_layoutWidget->dockWidgets();
646  for (DockWidgetBase *dw : dockWidgets) {
647  Frame *frame = dw->d->frame();
648 
649  if (force) {
650  dw->forceClose();
651  } else {
652  const bool closed = dw->close();
653  allClosed = allClosed && closed;
654  }
655 
656  if (frame->beingDeletedLater()) {
657  // The dock widget was closed and this frame is empty, delete immediately instead of
658  // waiting. I'm not a big fan of deleting stuff later, as state becomes inconsistent
659 
660  // Empty frames are historically deleted later since they are triggered by mouse click
661  // on the title bar, and the title bar is inside the frame.
662  // When doing it programmatically we can delete immediately.
663 
664  delete frame;
665  }
666  }
667 
668  return allClosed;
669 }
670 
671 void MainWindowBase::setUniqueName(const QString &uniqueName)
672 {
673  if (uniqueName.isEmpty())
674  return;
675 
676  if (d->name.isEmpty()) {
677  d->name = uniqueName;
679  DockRegistry::self()->registerMainWindow(this);
680  } else {
681  qWarning() << Q_FUNC_INFO << "Already has a name." << this->uniqueName() << uniqueName;
682  }
683 }
684 
686 {
687  if (d->m_overlayedDockWidget)
688  d->updateOverlayGeometry(d->m_overlayedDockWidget->d->frame()->QWidgetAdapter::size());
689 }
690 
691 bool MainWindowBase::deserialize(const LayoutSaver::MainWindow &mw)
692 {
693  if (mw.options != options()) {
694  qWarning() << Q_FUNC_INFO << "Refusing to restore MainWindow with different options"
695  << "; expected=" << mw.options << "; has=" << options();
696  return false;
697  }
698 
699  if (d->affinities != mw.affinities) {
700  qWarning() << Q_FUNC_INFO << "Affinty name changed from" << d->affinities
701  << "; to" << mw.affinities;
702 
703  d->affinities = mw.affinities;
704  }
705 
706  const bool success = layoutWidget()->deserialize(mw.multiSplitterLayout);
707 
708  // Restore the SideBars
709  d->clearSideBars();
711  SideBar *sb = sideBar(loc);
712  if (!sb)
713  continue;
714 
715  const QStringList dockWidgets = mw.dockWidgetsPerSideBar.value(loc);
716  for (const QString &uniqueName : dockWidgets) {
717 
718  DockWidgetBase *dw = DockRegistry::self()->dockByName(uniqueName, DockRegistry::DockByNameFlag::CreateIfNotFound);
719  if (!dw) {
720  qWarning() << Q_FUNC_INFO << "Could not find dock widget" << uniqueName
721  << ". Won't restore it to sidebar";
722  continue;
723  }
724 
725  sb->addDockWidget(dw);
726  }
727  }
728 
729  // Commented-out for now, we don't want to restore the popup/overlay. popups are perishable
730  //if (!mw.overlayedDockWidget.isEmpty())
731  // overlayOnSideBar(DockRegistry::self()->dockByName(mw.overlayedDockWidget));
732 
733  return success;
734 }
735 
736 LayoutSaver::MainWindow MainWindowBase::serialize() const
737 {
738  LayoutSaver::MainWindow m;
739 
740  m.options = options();
741  m.geometry = windowGeometry();
742  m.isVisible = isVisible();
743  m.uniqueName = uniqueName();
744  m.screenIndex = screenNumberForWidget(this);
745  m.screenSize = screenSizeForWidget(this);
746  m.multiSplitterLayout = layoutWidget()->serialize();
747  m.affinities = d->affinities;
748  m.windowState = windowHandle() ? windowHandle()->windowState()
750 
752  if (SideBar *sb = sideBar(loc)) {
753  const QStringList dockwidgets = sb->serialize();
754  if (!dockwidgets.isEmpty())
755  m.dockWidgetsPerSideBar.insert(loc, dockwidgets);
756  }
757  }
758 
759  return m;
760 }
761 
763 {
764  if (QWindow *window = windowHandle())
765  return window->geometry();
766 
767  return window()->geometry();
768 }
769 
771 {
772  if (!d->supportsPersistentCentralWidget()) {
773  qWarning() << "MainWindow::setPersistentCentralWidget() requires MainWindowOption_HasCentralWidget";
774  return;
775  }
776 
777  auto dw = d->m_persistentCentralDockWidget;
778  if (dw) {
779  dw->setWidget(widget);
780  } else {
781  qWarning() << Q_FUNC_INFO << "Unexpected null central dock widget";
782  }
783 }
784 
786 {
787  if (auto dw = d->m_persistentCentralDockWidget)
788  return dw->widget();
789 
790  return nullptr;
791 }
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:567
KDDockWidgets::MainWindowBase::setUniqueName
void setUniqueName(const QString &uniqueName)
Definition: MainWindowBase.cpp:671
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:164
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:770
KDDockWidgets::DockWidgetBase::affinities
QStringList affinities() const
Returns the affinity name. Empty by default.
Definition: DockWidgetBase.cpp:366
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:105
KDDockWidgets::MainWindowBase::layoutWidget
LayoutWidget * layoutWidget() const
Definition: MainWindowBase.cpp:200
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:348
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:641
KDDockWidgets::MainWindowBase::affinities
QStringList affinities
Definition: MainWindowBase.h:58
QRect::width
int width() const const
KDDockWidgets::Location
Location
Definition: KDDockWidgets.h:45
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:233
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:853
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:132
KDDockWidgets::DockWidgetBase::Option_NotDockable
@ Option_NotDockable
The DockWidget can't be docked, it's always floating.
Definition: DockWidgetBase.h:78
QSize::width
int width() const const
KDDockWidgets::MainWindowBase::anySideBarIsVisible
bool anySideBarIsVisible() const
Returns whether any side bar is visible.
Definition: MainWindowBase.cpp:625
KDDockWidgets::CursorPosition_Left
@ CursorPosition_Left
Definition: KDDockWidgets.h:242
KDDockWidgets::CursorPosition_Bottom
@ CursorPosition_Bottom
Definition: KDDockWidgets.h:245
KDDockWidgets::CursorPosition_Undefined
@ CursorPosition_Undefined
Definition: KDDockWidgets.h:241
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:528
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:263
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:58
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
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:59
QString
createLayoutWidget
static LayoutWidget * createLayoutWidget(MainWindowBase *mainWindow, MainWindowOptions options)
Definition: MainWindowBase.cpp:43
KDDockWidgets::MainWindowBase::~MainWindowBase
~MainWindowBase() override
Definition: MainWindowBase.cpp:126
QString::isEmpty
bool isEmpty() const const
KDDockWidgets::MainWindowBase::multiSplitter
MultiSplitter * multiSplitter() const
Definition: MainWindowBase.cpp:195
QRect::moveTop
void moveTop(int y)
KDDockWidgets::MainWindowBase::mdiLayoutWidget
MDILayoutWidget * mdiLayoutWidget() const
Definition: MainWindowBase.cpp:205
KDDockWidgets::MainWindowBase::dropArea
DropAreaWithCentralFrame * dropArea() const
Definition: MainWindowBase.cpp:190
KDDockWidgets::MainWindowBase::uniqueNameChanged
void uniqueNameChanged()
KDDockWidgets::MainWindowBase::uniqueName
QString uniqueName
Definition: MainWindowBase.h:59
KDDockWidgets::MainWindowBase::persistentCentralWidget
QWidgetOrQuick * persistentCentralWidget() const
Definition: MainWindowBase.cpp:785
QList::isEmpty
bool isEmpty() const const
Qt::WindowNoState
WindowNoState
KDDockWidgets::Config::frameworkWidgetFactory
FrameworkWidgetFactory * frameworkWidgetFactory() const
getter for the framework widget factory
Definition: Config.cpp:143
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:558
opposedSideBarLocationForBorder
static SideBarLocation opposedSideBarLocationForBorder(Layouting::LayoutBorderLocation loc)
Definition: MainWindowBase.cpp:321
KDDockWidgets::MainWindowBase::sideBarIsVisible
Q_INVOKABLE bool sideBarIsVisible(KDDockWidgets::SideBarLocation) const
Returns whether the specified sidebar is visible.
Definition: MainWindowBase.cpp:616
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:211
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:210
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:491
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:597
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:243
KDDockWidgets
Definition: Config.cpp:36
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:762
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:238
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:343
KDDockWidgets::MainWindowBase::onResized
void onResized(QResizeEvent *)
Definition: MainWindowBase.cpp:685
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:511
QMargins::top
int top() const const
QList::value
T value(int i) const const
QPoint
KDDockWidgets::MainWindowBase::MainWindowBase
MainWindowBase(const QString &uniqueName, MainWindowOptions options=MainWindowOption_HasCentralFrame, WidgetType *parent=nullptr, Qt::WindowFlags flags=Qt::WindowFlags())
Definition: MainWindowBase.cpp:115
KDDockWidgets::Config::self
static Config & self()
returns the singleton Config instance
Definition: Config.cpp:82
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:57
KDDockWidgets::CursorPosition_Top
@ CursorPosition_Top
Definition: KDDockWidgets.h:244
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:611
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 Mon Mar 7 2022 02:01:20 for KDDockWidgets API Documentation by doxygen 1.8.20