KDDockWidgets API Documentation  1.5
Frame.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 
19 #include "Frame_p.h"
20 #include "Config.h"
21 #include "DockRegistry_p.h"
22 #include "DockWidgetBase_p.h"
23 #include "FloatingWindow_p.h"
24 #include "FrameworkWidgetFactory.h"
25 #include "LayoutSaver_p.h"
26 #include "LayoutWidget_p.h"
27 #include "Logging_p.h"
28 #include "Position_p.h"
29 #include "TabWidget_p.h"
30 #include "TitleBar_p.h"
31 #include "Utils_p.h"
32 #include "WidgetResizeHandler_p.h"
33 #include "MDILayoutWidget_p.h"
34 #include "DropAreaWithCentralFrame_p.h"
35 
36 #include <QCloseEvent>
37 #include <QTimer>
38 
39 #define MARGIN_THRESHOLD 100
40 
41 static int s_dbg_numFrames = 0;
42 
43 using namespace KDDockWidgets;
44 
45 namespace KDDockWidgets {
46 static FrameOptions actualOptions(FrameOptions options)
47 {
49  options |= FrameOption_AlwaysShowsTabs;
50 
51  return options;
52 }
53 }
54 
55 Frame::Frame(QWidgetOrQuick *parent, FrameOptions options, int userType)
56  : LayoutGuestWidget(parent)
57  , FocusScope(this)
58  , m_tabWidget(Config::self().frameworkWidgetFactory()->createTabWidget(this))
59  , m_titleBar(Config::self().frameworkWidgetFactory()->createTitleBar(this))
60  , m_options(actualOptions(options))
61  , m_userType(userType)
62 {
64  DockRegistry::self()->registerFrame(this);
65 
66  connect(this, &Frame::currentDockWidgetChanged, this, &Frame::updateTitleAndIcon);
67 
68  connect(m_tabWidget->asWidget(), SIGNAL(currentTabChanged(int)), // clazy:exclude=old-style-connect
69  this, SLOT(onCurrentTabChanged(int)));
70 
71  setLayoutWidget(qobject_cast<LayoutWidget *>(QWidgetAdapter::parentWidget()));
72  m_inCtor = false;
73 }
74 
75 Frame::~Frame()
76 {
77  m_inDtor = true;
79  if (m_layoutItem)
80  m_layoutItem->unref();
81 
82  delete m_resizeHandler;
83  m_resizeHandler = nullptr;
84 
85  DockRegistry::self()->unregisterFrame(this);
86 
87  // Run some disconnects() too, so we don't receive signals during destruction:
88  setLayoutWidget(nullptr);
89 }
90 
91 void Frame::updateTitleAndIcon()
92 {
93  if (DockWidgetBase *dw = currentDockWidget()) {
94  m_titleBar->setTitle(dw->title());
95  m_titleBar->setIcon(dw->icon());
96 
97  if (auto fw = floatingWindow()) {
98  if (fw->hasSingleFrame()) {
99  fw->updateTitleAndIcon();
100  }
101  }
102 
103  setObjectName(dw->uniqueName());
104 
105  } else if (currentTabIndex() != -1) {
106  qWarning() << Q_FUNC_INFO << "Invalid dock widget for frame." << currentTabIndex();
107  }
108 }
109 
110 void Frame::onDockWidgetTitleChanged()
111 {
112  updateTitleAndIcon();
113 
114  if (!m_inCtor) { // don't call pure virtual in ctor
115  if (auto dw = qobject_cast<DockWidgetBase *>(sender())) {
116  int index = indexOfDockWidget(dw);
117  renameTab(index, dw->title());
118  changeTabIcon(index, dw->icon(DockWidgetBase::IconPlace::TabBar));
119  }
120  }
121 }
122 
123 void Frame::addWidget(DockWidgetBase *dockWidget, InitialOption addingOption)
124 {
125  insertWidget(dockWidget, dockWidgetCount(), addingOption); // append
126 }
127 
128 void Frame::addWidget(Frame *frame, InitialOption addingOption)
129 {
130  if (frame->isEmpty()) {
131  qWarning() << "Frame::addWidget: frame is empty." << frame;
132  return;
133  }
134 
135  const auto &docks = frame->dockWidgets();
136  for (DockWidgetBase *dockWidget : docks)
137  addWidget(dockWidget, addingOption);
138 }
139 
140 void Frame::addWidget(FloatingWindow *floatingWindow, InitialOption addingOption)
141 {
142  Q_ASSERT(floatingWindow);
143  for (Frame *f : floatingWindow->frames())
144  addWidget(f, addingOption);
145 }
146 
147 void Frame::insertWidget(DockWidgetBase *dockWidget, int index, InitialOption addingOption)
148 {
149  Q_ASSERT(dockWidget);
150  if (containsDockWidget(dockWidget)) {
151  if (!dockWidget->isPersistentCentralDockWidget())
152  qWarning() << "Frame::addWidget dockWidget already exists. this=" << this << "; dockWidget=" << dockWidget;
153  return;
154  }
155  if (m_layoutItem)
156  dockWidget->d->addPlaceholderItem(m_layoutItem);
157 
158  insertDockWidget(dockWidget, index);
159 
160  if (addingOption.startsHidden()) {
161  dockWidget->close(); // Ensure closed
162  } else {
163  if (hasSingleDockWidget()) {
164  Q_EMIT currentDockWidgetChanged(dockWidget);
165  setObjectName(dockWidget->uniqueName());
166 
167  if (!m_layoutItem) {
168  // When adding the 1st dock widget of a fresh frame, let's give the frame the size
169  // of the dock widget, so that when adding it to the main window, the main window can
170  // use that size as the initial suggested size.
171  resize(dockWidget->size());
172  }
173  }
174  }
175 
176  connect(dockWidget, &DockWidgetBase::titleChanged, this, &Frame::onDockWidgetTitleChanged);
177  connect(dockWidget, &DockWidgetBase::iconChanged, this, &Frame::onDockWidgetTitleChanged);
178 }
179 
180 void Frame::removeWidget(DockWidgetBase *dw)
181 {
182  disconnect(dw, &DockWidgetBase::titleChanged, this, &Frame::onDockWidgetTitleChanged);
183  disconnect(dw, &DockWidgetBase::iconChanged, this, &Frame::onDockWidgetTitleChanged);
184  removeWidget_impl(dw);
185 }
186 
187 FloatingWindow *Frame::detachTab(DockWidgetBase *dockWidget)
188 {
189  if (m_inCtor || m_inDtor)
190  return nullptr;
191 
192  dockWidget->d->saveTabIndex();
193 
194  QRect r = dockWidget->geometry();
195  removeWidget(dockWidget);
196 
197  auto newFrame = Config::self().frameworkWidgetFactory()->createFrame();
198  const QPoint globalPoint = mapToGlobal(QPoint(0, 0));
199  newFrame->addWidget(dockWidget);
200 
201  // We're potentially already dead at this point, as frames with 0 tabs auto-destruct. Don't access members from this point.
202 
203  auto floatingWindow = Config::self().frameworkWidgetFactory()->createFloatingWindow(newFrame);
204  r.moveTopLeft(globalPoint);
205  floatingWindow->setSuggestedGeometry(r, SuggestedGeometryHint_GeometryIsFromDocked);
206  floatingWindow->show();
207 
208  return floatingWindow;
209 }
210 
211 int Frame::indexOfDockWidget(const DockWidgetBase *dw)
212 {
213  if (m_inCtor || m_inDtor)
214  return -1;
215 
216  return indexOfDockWidget_impl(dw);
217 }
218 
219 int Frame::currentIndex() const
220 {
221  if (m_inCtor || m_inDtor)
222  return -1;
223 
224  return currentIndex_impl();
225 }
226 
227 void Frame::setCurrentTabIndex(int index)
228 {
229  if (m_inCtor || m_inDtor)
230  return;
231 
232  setCurrentTabIndex_impl(index);
233 }
234 
235 void Frame::setCurrentDockWidget(DockWidgetBase *dw)
236 {
237  if (m_inCtor || m_inDtor)
238  return;
239 
240  setCurrentDockWidget_impl(dw);
241 }
242 
243 void Frame::insertDockWidget(DockWidgetBase *dw, int index)
244 {
245  if (m_inCtor || m_inDtor)
246  return;
247 
248  insertDockWidget_impl(dw, index);
249 }
250 
251 DockWidgetBase *Frame::dockWidgetAt(int index) const
252 {
253  if (m_inCtor || m_inDtor)
254  return nullptr;
255 
256  return dockWidgetAt_impl(index);
257 }
258 
259 DockWidgetBase *Frame::currentDockWidget() const
260 {
261  if (m_inCtor || m_inDtor)
262  return nullptr;
263 
264  return currentDockWidget_impl();
265 }
266 
267 int Frame::dockWidgetCount() const
268 {
269  if (m_inCtor || m_inDtor)
270  return 0;
271 
272  return m_tabWidget->numDockWidgets();
273 }
274 
275 void Frame::onDockWidgetCountChanged()
276 {
277  qCDebug(docking) << "Frame::onDockWidgetCountChanged:" << this << "; widgetCount=" << dockWidgetCount();
278  if (isEmpty() && !isCentralFrame()) {
279  scheduleDeleteLater();
280  } else {
281  updateTitleBarVisibility();
282 
283  // We don't really keep track of the state, so emit even if the visibility didn't change. No biggie.
284  if (!(m_options & FrameOption_AlwaysShowsTabs))
285  Q_EMIT hasTabsVisibleChanged();
286 
287  const DockWidgetBase::List docks = dockWidgets();
288  for (DockWidgetBase *dock : docks)
289  dock->d->updateFloatAction();
290  }
291 
292  Q_EMIT numDockWidgetsChanged();
293 }
294 
295 void Frame::onCurrentTabChanged(int index)
296 {
297  if (index != -1) {
298  if (auto dock = dockWidgetAt(index)) {
299  Q_EMIT currentDockWidgetChanged(dock);
300  } else {
301  qWarning() << "dockWidgetAt" << index << "returned nullptr" << this;
302  }
303  }
304 }
305 
306 void Frame::isFocusedChangedCallback()
307 {
308  Q_EMIT isFocusedChanged();
309 }
310 
311 void Frame::focusedWidgetChangedCallback()
312 {
313  Q_EMIT focusedWidgetChanged();
314 }
315 
316 void Frame::updateTitleBarVisibility()
317 {
318  if (m_updatingTitleBar || m_beingDeleted) {
319  // To break a cyclic dependency
320  return;
321  }
322 
323  QScopedValueRollback<bool> guard(m_updatingTitleBar, true);
324 
325  bool visible = false;
326  if (isCentralFrame()) {
327  visible = false;
328  } else if ((Config::self().flags() & Config::Flag_HideTitleBarWhenTabsVisible) && hasTabsVisible()) {
329  visible = false;
330  } else if (FloatingWindow *fw = floatingWindow()) {
331  // If there's nested frames then show each Frame's title bar
332  visible = !fw->hasSingleFrame();
333  } else {
334  visible = true;
335  }
336 
337  const bool wasVisible = m_titleBar->isVisible();
338  m_titleBar->setVisible(visible);
339 
340  if (wasVisible != visible) {
341  Q_EMIT actualTitleBarChanged();
342  for (auto dw : dockWidgets())
343  Q_EMIT dw->actualTitleBarChanged();
344  }
345 
346  if (auto fw = floatingWindow()) {
347  // Update the floating window which might be using Flag_HideTitleBarWhenTabsVisible
348  // In that case it might not show title bar depending on the number of tabs that the frame has
349  fw->updateTitleBarVisibility();
350  }
351 }
352 
353 void Frame::updateFloatingActions()
354 {
355  const QVector<DockWidgetBase *> widgets = dockWidgets();
356  for (DockWidgetBase *dw : widgets)
357  dw->d->updateFloatAction();
358 }
359 
360 bool Frame::containsMouse(QPoint globalPos) const
361 {
362  return QWidgetAdapter::rect().contains(KDDockWidgets::QWidgetAdapter::mapFromGlobal(globalPos));
363 }
364 
365 TitleBar *Frame::titleBar() const
366 {
367  return m_titleBar;
368 }
369 
370 TitleBar *Frame::actualTitleBar() const
371 {
372  if (FloatingWindow *fw = floatingWindow()) {
373  // If there's nested frames then show each Frame's title bar
374  if (fw->hasSingleFrame())
375  return fw->titleBar();
376  }
377 
378  return titleBar();
379 }
380 
381 QString Frame::title() const
382 {
383  return m_titleBar->title();
384 }
385 
386 QIcon Frame::icon() const
387 {
388  return m_titleBar->icon();
389 }
390 
391 const DockWidgetBase::List Frame::dockWidgets() const
392 {
393  if (m_inCtor || m_inDtor)
394  return {};
395 
396  DockWidgetBase::List dockWidgets;
397  const int count = dockWidgetCount();
398  dockWidgets.reserve(count);
399  for (int i = 0; i < count; ++i)
400  dockWidgets << dockWidgetAt(i);
401 
402  return dockWidgets;
403 }
404 
405 bool Frame::containsDockWidget(DockWidgetBase *dockWidget) const
406 {
407  const int count = dockWidgetCount();
408  for (int i = 0, e = count; i != e; ++i) {
409  if (dockWidget == dockWidgetAt(i))
410  return true;
411  }
412  return false;
413 }
414 
415 FloatingWindow *Frame::floatingWindow() const
416 {
417  // Returns the first FloatingWindow* parent in the hierarchy.
418  // However, if there's a MainWindow in the hierarchy it stops, which can
419  // happen with nested main windows.
420 
421  auto p = QWidgetAdapter::parentWidget();
422  while (p) {
423  if (qobject_cast<KDDockWidgets::MainWindowBase *>(p))
424  return nullptr;
425 
426  if (auto fw = qobject_cast<FloatingWindow *>(p))
427  return fw;
428 
429  if (p == window()) {
430  // We stop at the window. (top-levels can have parent, but we're not interested)
431  return nullptr;
432  }
433 
434  p = p->parentWidget();
435  }
436 
437  return nullptr;
438 }
439 
440 void Frame::restoreToPreviousPosition()
441 {
442  if (hasSingleDockWidget()) {
443  qWarning() << Q_FUNC_INFO << "Invalid usage, there's no tabs";
444  return;
445  }
446 
447  if (!m_layoutItem) {
448  qCDebug(placeholder) << Q_FUNC_INFO << "There's no previous position known";
449  return;
450  }
451 
452  if (!m_layoutItem->isPlaceholder()) {
453  // Maybe in this case just fold the frame into the placeholder, which probably has other dockwidgets which were added meanwhile. TODO
454  qCDebug(placeholder) << Q_FUNC_INFO << "Previous position isn't a placeholder";
455  return;
456  }
457 
458  m_layoutItem->restore(this);
459 }
460 
461 int Frame::currentTabIndex() const
462 {
463  return currentIndex();
464 }
465 
466 void Frame::onCloseEvent(QCloseEvent *e)
467 {
468  qCDebug(closing) << "Frame::closeEvent";
469  e->accept(); // Accepted by default (will close unless ignored)
470  const DockWidgetBase::List docks = dockWidgets();
471  for (DockWidgetBase *dock : docks) {
472  qApp->sendEvent(dock, e);
473  if (!e->isAccepted())
474  break; // Stop when the first dockwidget prevents closing
475  }
476 }
477 
478 bool Frame::anyNonClosable() const
479 {
480  for (auto dw : dockWidgets()) {
481  if ((dw->options() & DockWidgetBase::Option_NotClosable) && !DockRegistry::self()->isProcessingAppQuitEvent())
482  return true;
483  }
484 
485  return false;
486 }
487 
488 bool Frame::anyNonDockable() const
489 {
490  for (auto dw : dockWidgets()) {
491  if (dw->options() & DockWidgetBase::Option_NotDockable)
492  return true;
493  }
494 
495  return false;
496 }
497 
498 void Frame::onDockWidgetShown(DockWidgetBase *w)
499 {
500  if (hasSingleDockWidget() && containsDockWidget(w)) { // We have to call contains because it might be being in process of being reparented
501  if (!QWidgetAdapter::isVisible()) {
502  qCDebug(hiding) << "Widget" << w << " was shown, we're="
503  << "; visible="
504  << QWidgetAdapter::isVisible();
505  QWidgetAdapter::setVisible(true);
506  }
507  }
508 }
509 
510 void Frame::onDockWidgetHidden(DockWidgetBase *w)
511 {
512  if (!isCentralFrame() && hasSingleDockWidget() && containsDockWidget(w)) { // We have to call contains because it might be being in process of being reparented
513  if (QWidgetAdapter::isVisible()) {
514  qCDebug(hiding) << "Widget" << w << " was hidden, we're="
515  << "; visible=" << QWidgetAdapter::isVisible()
516  << "; dockWidgets=" << dockWidgets();
517  QWidgetAdapter::setVisible(false);
518  }
519  }
520 }
521 
522 void Frame::setLayoutItem(Layouting::Item *item)
523 {
524  if (item == m_layoutItem)
525  return;
526 
527  if (m_layoutItem)
528  m_layoutItem->unref();
529 
530  if (item)
531  item->ref();
532 
533  m_layoutItem = item;
534  if (item) {
535  for (DockWidgetBase *dw : dockWidgets())
536  dw->d->addPlaceholderItem(item);
537  } else {
538  for (DockWidgetBase *dw : dockWidgets())
539  dw->d->lastPositions().removePlaceholders();
540  }
541 }
542 
543 Layouting::Item *Frame::layoutItem() const
544 {
545  return m_layoutItem;
546 }
547 
548 int Frame::dbg_numFrames()
549 {
550  return s_dbg_numFrames;
551 }
552 
553 bool Frame::beingDeletedLater() const
554 {
555  return m_beingDeleted;
556 }
557 
558 bool Frame::hasTabsVisible() const
559 {
560  if (m_beingDeleted)
561  return false;
562 
563  return alwaysShowsTabs() || dockWidgetCount() > 1;
564 }
565 
566 QStringList Frame::affinities() const
567 {
568  if (isEmpty()) {
569  return {};
570  } else {
571  return dockWidgetAt(0)->affinities();
572  }
573 }
574 
575 void Frame::setLayoutWidget(LayoutWidget *dt)
576 {
577  if (dt == m_layoutWidget)
578  return;
579 
580  const bool wasInMainWindow = dt && isInMainWindow();
581  const bool wasMDI = isMDI();
582  if (m_layoutWidget)
583  disconnect(m_visibleWidgetCountChangedConnection);
584 
585  m_layoutWidget = dt;
586  delete m_resizeHandler;
587  m_resizeHandler = nullptr;
588 
589  if (m_layoutWidget) {
590  if (isMDI())
591  m_resizeHandler = new WidgetResizeHandler(/*topLevel=*/false, this);
592 
593  // We keep the connect result so we don't dereference m_layoutWidget at shutdown
594  m_visibleWidgetCountChangedConnection =
595  connect(m_layoutWidget, &LayoutWidget::visibleWidgetCountChanged, this,
596  &Frame::updateTitleBarVisibility);
597  updateTitleBarVisibility();
598  if (wasInMainWindow != isInMainWindow())
599  Q_EMIT isInMainWindowChanged();
600  }
601 
602  if (wasMDI != isMDI())
603  Q_EMIT isMDIChanged();
604 }
605 
606 bool Frame::isTheOnlyFrame() const
607 {
608  return m_layoutWidget && m_layoutWidget->visibleCount() == 1;
609 }
610 
611 bool Frame::isOverlayed() const
612 {
613  return m_options & FrameOption_IsOverlayed;
614 }
615 
616 void Frame::unoverlay()
617 {
618  m_options &= ~FrameOption_IsOverlayed;
619 }
620 
621 bool Frame::isFloating() const
622 {
623  if (isInMainWindow())
624  return false;
625 
626  return isTheOnlyFrame();
627 }
628 
629 bool Frame::isInFloatingWindow() const
630 {
631  return floatingWindow() != nullptr;
632 }
633 
634 bool Frame::isInMainWindow() const
635 {
636  return mainWindow() != nullptr;
637 }
638 
639 bool Frame::event(QEvent *e)
640 {
641  if (e->type() == QEvent::ParentChange) {
642  if (auto layoutWidget = qobject_cast<LayoutWidget *>(QWidgetAdapter::parentWidget())) {
643  setLayoutWidget(layoutWidget);
644  } else {
645  setLayoutWidget(nullptr);
646  }
647  }
648 
649  return QWidgetAdapter::event(e);
650 }
651 
652 Frame *Frame::deserialize(const LayoutSaver::Frame &f)
653 {
654  if (!f.isValid())
655  return nullptr;
656 
657  const FrameOptions options = FrameOptions(f.options);
658  Frame *frame = nullptr;
659  const bool isPersistentCentralFrame = options & FrameOption::FrameOption_IsCentralFrame;
660  auto widgetFactory = Config::self().frameworkWidgetFactory();
661 
662  if (isPersistentCentralFrame) {
663  // Don't create a new Frame if we're restoring the Persistent Central frame (the one created
664  // by MainWindowOption_HasCentralFrame). It already exists.
665 
666  if (f.mainWindowUniqueName.isEmpty()) {
667  // Can happen with older serialization formats
668  qWarning() << Q_FUNC_INFO << "Frame is the persistent central frame but doesn't have"
669  << "an associated window name";
670  } else {
671  if (MainWindowBase *mw = DockRegistry::self()->mainWindowByName(f.mainWindowUniqueName)) {
672  frame = mw->dropArea()->m_centralFrame;
673  if (!frame) {
674  // Doesn't happen...
675  qWarning() << "Main window" << f.mainWindowUniqueName << "doesn't have central frame";
676  }
677  } else {
678  // Doesn't happen...
679  qWarning() << Q_FUNC_INFO << "Couldn't find main window"
680  << f.mainWindowUniqueName;
681  }
682  }
683  }
684 
685  if (!frame)
686  frame = widgetFactory->createFrame(/*parent=*/nullptr, options);
687 
688  frame->setObjectName(f.objectName);
689 
690  for (const auto &savedDock : qAsConst(f.dockWidgets)) {
691  if (DockWidgetBase *dw = DockWidgetBase::deserialize(savedDock)) {
692  frame->addWidget(dw);
693  }
694  }
695 
696  frame->setCurrentTabIndex(f.currentTabIndex);
697  frame->QWidgetAdapter::setGeometry(f.geometry);
698 
699  return frame;
700 }
701 
702 LayoutSaver::Frame Frame::serialize() const
703 {
704  LayoutSaver::Frame frame;
705  frame.isNull = false;
706 
707  const DockWidgetBase::List docks = dockWidgets();
708 
709  frame.objectName = objectName();
710  frame.geometry = QWidgetAdapter::geometry();
711  frame.options = options();
712  frame.currentTabIndex = currentTabIndex();
713  frame.id = id(); // for coorelation purposes
714 
715  if (MainWindowBase *mw = mainWindow())
716  frame.mainWindowUniqueName = mw->uniqueName();
717 
718  for (DockWidgetBase *dock : docks)
719  frame.dockWidgets.push_back(dock->d->serialize());
720 
721  return frame;
722 }
723 
724 void Frame::scheduleDeleteLater()
725 {
726  qCDebug(creation) << Q_FUNC_INFO << this;
727  m_beingDeleted = true;
728  QTimer::singleShot(0, this, [this] {
729  // Can't use deleteLater() here due to QTBUG-83030 (deleteLater() never delivered if triggered by a sendEvent() before event loop starts)
730  delete this;
731  });
732 }
733 
734 QSize Frame::dockWidgetsMinSize() const
735 {
736  QSize size = Layouting::Item::hardcodedMinimumSize;
737  for (DockWidgetBase *dw : dockWidgets())
739 
740  return size;
741 }
742 
743 QSize Frame::biggestDockWidgetMaxSize() const
744 {
745  QSize size = Layouting::Item::hardcodedMaximumSize;
746  for (DockWidgetBase *dw : dockWidgets()) {
747  const QSize dwMax = widgetMaxSize(dw);
748  if (size == Layouting::Item::hardcodedMaximumSize) {
749  size = dwMax;
750  continue;
751  }
752 
753  const bool hasMaxSize = dwMax != Layouting::Item::hardcodedMaximumSize;
754  if (hasMaxSize)
755  size = dw->maximumSize().expandedTo(size);
756  }
757 
758  // Interpret 0 max-size as not having one too.
759  if (size.width() == 0)
760  size.setWidth(Layouting::Item::hardcodedMaximumSize.width());
761  if (size.height() == 0)
762  size.setHeight(Layouting::Item::hardcodedMaximumSize.height());
763 
764  return size;
765 }
766 
767 QRect Frame::dragRect() const
768 {
769  QRect rect;
770  if (m_titleBar->isVisible()) {
771  rect = m_titleBar->rect();
772  rect.moveTopLeft(m_titleBar->mapToGlobal(QPoint(0, 0)));
773  }
774 
775  return rect;
776 }
777 
778 MainWindowBase *Frame::mainWindow() const
779 {
780  return m_layoutWidget ? m_layoutWidget->mainWindow() : nullptr;
781 }
782 
783 TabWidget *Frame::tabWidget() const
784 {
785  return m_tabWidget;
786 }
787 
789 bool Frame::allDockWidgetsHave(DockWidgetBase::Option option) const
790 {
791  const DockWidgetBase::List docks = dockWidgets();
792  return std::all_of(docks.cbegin(), docks.cend(), [option](DockWidgetBase *dw) {
793  return dw->options() & option;
794  });
795 }
796 
798 bool Frame::anyDockWidgetsHas(DockWidgetBase::Option option) const
799 {
800  const DockWidgetBase::List docks = dockWidgets();
801  return std::any_of(docks.cbegin(), docks.cend(), [option](DockWidgetBase *dw) {
802  return dw->options() & option;
803  });
804 }
805 
806 bool Frame::allDockWidgetsHave(DockWidgetBase::LayoutSaverOption option) const
807 {
808  const DockWidgetBase::List docks = dockWidgets();
809  return std::all_of(docks.cbegin(), docks.cend(), [option](DockWidgetBase *dw) {
810  return dw->layoutSaverOptions() & option;
811  });
812 }
813 
814 bool Frame::anyDockWidgetsHas(DockWidgetBase::LayoutSaverOption option) const
815 {
816  const DockWidgetBase::List docks = dockWidgets();
817  return std::any_of(docks.cbegin(), docks.cend(), [option](DockWidgetBase *dw) {
818  return dw->layoutSaverOptions() & option;
819  });
820 }
821 
822 void Frame::setAllowedResizeSides(CursorPositions sides)
823 {
824  if (sides) {
825  delete m_resizeHandler;
826  m_resizeHandler = new WidgetResizeHandler(/*topLevel=*/false, this);
827  m_resizeHandler->setAllowedResizeSides(sides);
828  } else {
829  delete m_resizeHandler;
830  m_resizeHandler = nullptr;
831  }
832 }
833 
834 bool Frame::isMDI() const
835 {
836  return mdiLayoutWidget() != nullptr;
837 }
838 
839 MDILayoutWidget *Frame::mdiLayoutWidget() const
840 {
841  return qobject_cast<MDILayoutWidget *>(m_layoutWidget);
842 }
843 
844 int Frame::userType() const
845 {
846  return m_userType;
847 }
848 
849 WidgetResizeHandler *Frame::resizeHandler() const
850 {
851  return m_resizeHandler;
852 }
QRect::moveTopLeft
void moveTopLeft(const QPoint &position)
Layouting::Widget::widgetMinSize
static QSize widgetMinSize(const T *w)
Definition: Widget.h:152
QEvent::ParentChange
ParentChange
QRect
KDDockWidgets::InitialOption
Struct describing the preferred dock widget size and visibility when adding it to a layout.
Definition: KDDockWidgets.h:105
QTimer::singleShot
singleShot
QVector::cend
QVector::const_iterator cend() const const
QWidget
KDDockWidgets::DockWidgetBase::uniqueName
QString uniqueName
Definition: DockWidgetBase.h:65
QSize
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
QSize::width
int width() const const
QSize::setWidth
void setWidth(int width)
KDDockWidgets::FocusScope
Allows to implement a similar functionality to QtQuick's FocusScope item, in QtWidgets.
Definition: FocusScope.h:28
KDDockWidgets::FrameOption_IsOverlayed
@ FrameOption_IsOverlayed
Definition: KDDockWidgets.h:263
QCloseEvent
QSize::height
int height() const const
QString
QEvent::isAccepted
bool isAccepted() const const
QVector::cbegin
QVector::const_iterator cbegin() const const
KDDockWidgets::FrameOption_AlwaysShowsTabs
@ FrameOption_AlwaysShowsTabs
Definition: KDDockWidgets.h:261
KDDockWidgets::DockWidgetBase::LayoutSaverOption
LayoutSaverOption
Options which will affect LayoutSaver save/restore.
Definition: DockWidgetBase.h:86
KDDockWidgets::Config
Singleton to allow to choose certain behaviours of the framework.
Definition: Config.h:55
KDDockWidgets::LayoutGuestWidget
LayoutGuestWidget is the type that Item will host.
Definition: QWidgetAdapter.h:76
KDDockWidgets::DockWidgetBase::actualTitleBarChanged
void actualTitleBarChanged()
Emitted when the title bar that serves this dock widget changes.
QIcon
QVector::reserve
void reserve(int size)
Config.h
Application-wide config to tune certain behaviours of the framework.
KDDockWidgets::Config::Flag_AlwaysShowTabs
@ Flag_AlwaysShowTabs
Always show tabs, even if there's only one,.
Definition: Config.h:74
QSize::expandedTo
QSize expandedTo(const QSize &otherSize) const const
QEvent::type
QEvent::Type type() const const
QEvent
KDDockWidgets::InitialOption::startsHidden
bool startsHidden() const
Definition: KDDockWidgets.h:133
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
Definition: Config.cpp:36
QScopedValueRollback
KDDockWidgets::FrameOption_IsCentralFrame
@ FrameOption_IsCentralFrame
Definition: KDDockWidgets.h:262
KDDockWidgets::MainWindowBase
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
Definition: MainWindowBase.h:56
QVector
s_dbg_numFrames
static int s_dbg_numFrames
Definition: Frame.cpp:41
KDDockWidgets::DockWidgetBase::Option
Option
DockWidget options to pass at construction time.
Definition: DockWidgetBase.h:75
KDDockWidgets::DockWidgetBase::options
KDDockWidgets::DockWidgetBase::Options options
Definition: DockWidgetBase.h:69
KDDockWidgets::SuggestedGeometryHint_GeometryIsFromDocked
@ SuggestedGeometryHint_GeometryIsFromDocked
Definition: KDDockWidgets.h:204
QSize::setHeight
void setHeight(int height)
KDDockWidgets::actualOptions
static FrameOptions actualOptions(FrameOptions options)
Definition: Frame.cpp:46
QPoint
QEvent::accept
void accept()
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

© 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