KDDockWidgets API Documentation  1.4
DockWidgetBase.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KDDockWidgets.
3 
4  SPDX-FileCopyrightText: 2019-2021 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 #include "DockWidgetBase.h"
13 #include "private/DockWidgetBase_p.h"
14 #include "private/DockRegistry_p.h"
15 #include "private/FloatingWindow_p.h"
16 #include "private/Frame_p.h"
17 #include "private/LayoutSaver_p.h"
18 #include "private/Logging_p.h"
19 #include "private/MDILayoutWidget_p.h"
20 #include "private/SideBar_p.h"
21 #include "private/TitleBar_p.h"
22 #include "private/Utils_p.h"
23 #include "private/WindowBeingDragged_p.h"
24 #include "private/Position_p.h"
25 
26 #include "Config.h"
27 #include "FrameworkWidgetFactory.h"
28 
29 #include <QEvent>
30 #include <QCloseEvent>
31 #include <QTimer>
32 #include <QScopedValueRollback>
33 
41 using namespace KDDockWidgets;
42 
43 DockWidgetBase::DockWidgetBase(const QString &name, Options options,
44  LayoutSaverOptions layoutSaverOptions)
45  : QWidgetAdapter(nullptr, Qt::Tool)
46  , d(new Private(name, options, layoutSaverOptions, this))
47 {
48  d->init();
49  DockRegistry::self()->registerDockWidget(this);
50 
51  if (name.isEmpty())
52  qWarning() << Q_FUNC_INFO << "Name can't be null";
53 
54  setAttribute(Qt::WA_PendingMoveEvent, false);
55 }
56 
58 {
59  DockRegistry::self()->unregisterDockWidget(this);
60  delete d;
61 }
62 
64 {
65  if (other == this) {
66  qWarning() << Q_FUNC_INFO << "Refusing to add dock widget into itself" << other;
67  return;
68  }
69 
70  if (!other) {
71  qWarning() << Q_FUNC_INFO << "dock widget is null";
72  return;
73  }
74 
75  if (!DockRegistry::self()->affinitiesMatch(other->affinities(), d->affinities)) {
76  qWarning() << Q_FUNC_INFO << "Refusing to dock widget with incompatible affinity."
77  << other->affinities() << affinities();
78  return;
79  }
80 
82  qWarning() << Q_FUNC_INFO << "Refusing to dock non-dockable widget" << other;
83  return;
84  }
85 
86  Frame *frame = d->frame();
87 
88  if (frame) {
89  if (frame->containsDockWidget(other)) {
90  qWarning() << Q_FUNC_INFO << "Already contains" << other;
91  return;
92  }
93  } else {
94  if (isWindow()) {
95  // Doesn't have a frame yet
96  d->morphIntoFloatingWindow();
97  frame = d->frame();
98  } else {
99  // Doesn't happen
100  qWarning() << Q_FUNC_INFO << "null frame";
101  return;
102  }
103  }
104 
105  other->setParent(nullptr);
106  frame->addWidget(other, option);
107 }
108 
110  Location location,
111  DockWidgetBase *relativeTo,
112  InitialOption initialOption)
113 {
114  if (auto mainWindow = qobject_cast<MainWindowBase *>(window())) {
115  // It's inside a main window. Simply use the main window API.
116  mainWindow->addDockWidget(other, location, relativeTo, initialOption);
117  return;
118  }
119 
120  if (!DockRegistry::self()->affinitiesMatch(other->affinities(), d->affinities)) {
121  qWarning() << Q_FUNC_INFO << "Refusing to dock widget with incompatible affinity."
122  << other->affinities() << affinities();
123  return;
124  }
125 
127  qWarning() << Q_FUNC_INFO << "Refusing to dock non-dockable widget" << other;
128  return;
129  }
130 
131  if (isWindow())
132  d->morphIntoFloatingWindow();
133 
134  if (auto fw = floatingWindow()) {
135  fw->addDockWidget(other, location, relativeTo, initialOption);
136  } else {
137  qWarning() << Q_FUNC_INFO << "Couldn't find floating nested window";
138  }
139 }
140 
142 {
143  if (w == d->widget)
144  return;
145 
146  if (d->widget) {
147  // Unparent the old widget, we're giving back ownership
148  d->widget->setParent(nullptr);
149  }
150 
151  d->widget = w;
152  if (w)
153  setSizePolicy(w->sizePolicy());
154 
155  Q_EMIT widgetChanged(w);
156 }
157 
159 {
160  return d->widget;
161 }
162 
164 {
165  if (isWindow())
166  return true;
167 
168  auto fw = floatingWindow();
169  return fw && fw->hasSingleDockWidget();
170 }
171 
173 {
174  const bool alreadyFloating = isFloating();
175 
176  if ((floats && alreadyFloating) || (!floats && !alreadyFloating))
177  return true; // Nothing to do
178 
179  if (!floats && (Config::self().internalFlags() & Config::InternalFlag_DontShowWhenUnfloatingHiddenWindow) && !isVisible()) {
180  // Mimics behaviour of QDockWidget, which you might need during porting.
181  // Not something we suggest though. For KDDW, setFloating(false) means dock, and that implies showing.
182  return false;
183  }
184 
185  if (floats) {
186  d->saveTabIndex();
187  if (isTabbed()) {
188  auto frame = d->frame();
189  if (!frame) {
190  qWarning() << "DockWidget::setFloating: Tabbed but no frame exists"
191  << this;
192  Q_ASSERT(false);
193  return false;
194  }
195 
196  frame->detachTab(this);
197  } else {
198  d->frame()->titleBar()->makeWindow();
199  }
200 
201  auto lastGeo = d->lastPositions().lastFloatingGeometry();
202  if (lastGeo.isValid()) {
203  if (auto fw = floatingWindow())
204  fw->setSuggestedGeometry(lastGeo, SuggestedGeometryHint_PreserveCenter);
205  }
206  return true;
207  } else {
208  d->saveLastFloatingGeometry();
209  return d->restoreToPreviousPosition();
210  }
211 }
212 
214 {
215  return d->toggleAction;
216 }
217 
219 {
220  return d->floatAction;
221 }
222 
224 {
225  return d->name;
226 }
227 
229 {
230  return d->title;
231 }
232 
234 {
235  if (title != d->title) {
236  d->title = title;
237  d->updateTitle();
238  Q_EMIT titleChanged(title);
239  }
240 }
241 
243 {
244  if (Frame *f = d->frame())
245  return f->QWidgetAdapter::geometry();
246 
247  // Means the dock widget isn't visible. Just fallback to its own geometry
248  return QWidgetAdapter::geometry();
249 }
250 
251 DockWidgetBase::Options DockWidgetBase::options() const
252 {
253  return d->options;
254 }
255 
256 DockWidgetBase::LayoutSaverOptions DockWidgetBase::layoutSaverOptions() const
257 {
258  return d->layoutSaverOptions;
259 }
260 
261 void DockWidgetBase::setOptions(Options options)
262 {
263  if ((d->options & Option_NotDockable) != (options & Option_NotDockable)) {
264  qWarning() << Q_FUNC_INFO << "Option_NotDockable not allowed to change. Pass via ctor only.";
265  return;
266  }
267 
268  if (options != d->options) {
269  d->options = options;
270  Q_EMIT optionsChanged(options);
271  if (auto tb = titleBar())
272  tb->updateButtons();
273  }
274 }
275 
277 {
278  if (Frame *frame = d->frame()) {
279  return frame->alwaysShowsTabs() || frame->dockWidgetCount() > 1;
280  } else {
281  if (!isFloating())
282  qWarning() << "DockWidget::isTabbed() Couldn't find any tab widget.";
283  return false;
284  }
285 }
286 
288 {
289  if (Frame *frame = d->frame()) {
290  return frame->currentIndex() == frame->indexOfDockWidget(const_cast<DockWidgetBase *>(this));
291  } else {
292  return true;
293  }
294 }
295 
297 {
298  if (Frame *frame = d->frame())
299  frame->setCurrentDockWidget(this);
300 }
301 
303 {
304  if (Frame *frame = d->frame())
305  return frame->indexOfDockWidget(this);
306 
307  return 0;
308 }
309 
310 void DockWidgetBase::setIcon(const QIcon &icon, IconPlaces places)
311 {
312  if (places & IconPlace::TitleBar)
313  d->titleBarIcon = icon;
314 
315  if (places & IconPlace::TabBar)
316  d->tabBarIcon = icon;
317 
318  if (places & IconPlace::ToggleAction)
319  d->toggleAction->setIcon(icon);
320 
321  Q_EMIT iconChanged();
322 }
323 
325 {
326  if (place == IconPlace::TitleBar)
327  return d->titleBarIcon;
328 
329  if (place == IconPlace::TabBar)
330  return d->tabBarIcon;
331 
332  if (place == IconPlace::ToggleAction)
333  return d->toggleAction->icon();
334 
335  return {};
336 }
337 
339 {
340  d->forceClose();
341 }
342 
343 TitleBar *DockWidgetBase::titleBar() const
344 {
345  if (Frame *f = d->frame())
346  return f->actualTitleBar();
347 
348  return nullptr;
349 }
350 
352 {
353  return d->toggleAction->isChecked();
354 }
355 
357 {
358  return d->affinities;
359 }
360 
362 {
363  if (isWindow() && (d->m_lastPositions.wasFloating() || !d->m_lastPositions.isValid())) {
364  // Create the FloatingWindow already, instead of waiting for the show event.
365  // This reduces flickering on some platforms
366  d->morphIntoFloatingWindow();
367  } else {
369  }
370 }
371 
373 {
374  if (!isOpen())
375  return;
376 
377  setAsCurrentTab();
378 
379  if (auto fw = floatingWindow()) {
380  fw->raise();
381  fw->activateWindow();
382  } else if (Frame *frame = d->frame()) {
383  if (frame->isMDI())
384  frame->raise();
385  }
386 }
387 
389 {
390  return qobject_cast<MainWindowBase *>(widget());
391 }
392 
394 {
395  return d->mainWindow() != nullptr;
396 }
397 
399 {
400  return d->mainWindow();
401 }
402 
404 {
405  auto f = d->frame();
406  return f && f->isFocused() && isCurrentTab();
407 }
408 
410 {
411  setAffinities({ affinity });
412 }
413 
414 void DockWidgetBase::setAffinities(const QStringList &affinityNames)
415 {
416  QStringList affinities = affinityNames;
418 
419  if (d->affinities == affinities)
420  return;
421 
422  if (!d->affinities.isEmpty()) {
423  qWarning() << Q_FUNC_INFO
424  << "Affinity is already set, refusing to change."
425  << "Submit a feature request with a good justification.";
426  return;
427  }
428 
429  d->affinities = affinities;
430 }
431 
433 {
434  if (MainWindowBase *m = mainWindow())
435  m->moveToSideBar(this);
436 }
437 
439 {
440  if (MainWindowBase *m = mainWindow())
441  return m->overlayedDockWidget() == this;
442 
443  return false;
444 }
445 
447 {
448  return DockRegistry::self()->sideBarLocationForDockWidget(this);
449 }
450 
452 {
454 }
455 
457 {
458  return d->m_lastPositions.isValid();
459 }
460 
462 {
463  return d->m_lastOverlayedSize;
464 }
465 
467 {
468  return DockRegistry::self()->dockByName(uniqueName);
469 }
470 
472 {
473  return d->layoutSaverOptions & LayoutSaverOption::Skip;
474 }
475 
477 {
478  if (isOpen() && isFloating()) {
479  window()->setGeometry(geometry);
480  } else {
481  d->m_lastPositions.setLastFloatingGeometry(geometry);
482  }
483 }
484 
485 FloatingWindow *DockWidgetBase::Private::morphIntoFloatingWindow()
486 {
487  if (auto fw = floatingWindow())
488  return fw; // Nothing to do
489 
490  if (q->isWindow()) {
491  QRect geo = m_lastPositions.lastFloatingGeometry();
492  if (geo.isNull()) {
493  geo = q->geometry();
494 
495  if (!q->testAttribute(Qt::WA_PendingMoveEvent)) { // If user already moved it, we don't
496  // interfere
497  const QPoint center = defaultCenterPosForFloating();
498  if (!center.isNull())
499  geo.moveCenter(center);
500  }
501  }
502 
503  auto frame = Config::self().frameworkWidgetFactory()->createFrame();
504  frame->addWidget(q);
505  geo.setSize(geo.size().boundedTo(frame->maxSizeHint()));
506  auto floatingWindow =
507  Config::self().frameworkWidgetFactory()->createFloatingWindow(frame, nullptr, geo);
508  floatingWindow->show();
509 
510  return floatingWindow;
511  } else {
512  return nullptr;
513  }
514 }
515 
516 void DockWidgetBase::Private::maybeMorphIntoFloatingWindow()
517 {
518  if (q->isWindow() && q->isVisible())
519  morphIntoFloatingWindow();
520 }
521 
522 MDILayoutWidget *DockWidgetBase::Private::mdiLayout() const
523 {
524  if (auto mw = mainWindow())
525  return mw->mdiLayoutWidget();
526 
527  return nullptr;
528 }
529 
530 DockWidgetBase::Private *DockWidgetBase::dptr() const
531 {
532  return d;
533 }
534 
535 QPoint DockWidgetBase::Private::defaultCenterPosForFloating()
536 {
537  MainWindowBase::List mainWindows = DockRegistry::self()->mainwindows();
538  // We don't care about multiple mainwindows yet. Or, let's just say that the first one is more main than the others
539  MainWindowBase *mw = mainWindows.isEmpty() ? nullptr : mainWindows.constFirst();
540  if (!mw || !q->isFloating())
541  return {};
542 
543  return mw->geometry().center();
544 }
545 
546 bool DockWidgetBase::Private::eventFilter(QObject *watched, QEvent *event)
547 {
548  const bool isWindowActivate = event->type() == QEvent::WindowActivate;
549  const bool isWindowDeactivate = event->type() == QEvent::WindowDeactivate;
550  if ((isWindowActivate || isWindowDeactivate) && watched == q->window())
551  Q_EMIT q->windowActiveAboutToChange(isWindowActivate);
552 
553  return QObject::eventFilter(watched, event);
554 }
555 
556 void DockWidgetBase::Private::updateTitle()
557 {
558  if (q->isFloating())
559  q->window()->setWindowTitle(title);
560 
561  toggleAction->setText(title);
562 }
563 
564 void DockWidgetBase::Private::toggle(bool enabled)
565 {
566  if (SideBar *sb = sideBar()) {
567  // The widget is in the sidebar, let's toggle its overlayed state
568  sb->toggleOverlay(q);
569  } else {
570  // The most common case. The dock widget is not in the sidebar. just close or open it.
571  if (enabled) {
572  show();
573  } else {
574  q->close();
575  }
576  }
577 }
578 
579 void DockWidgetBase::Private::updateToggleAction()
580 {
581  QScopedValueRollback<bool> recursionGuard(m_updatingToggleAction, true); // Guard against recursiveness
582  m_updatingToggleAction = true;
583  if ((q->isVisible() || frame()) && !toggleAction->isChecked()) {
584  toggleAction->setChecked(true);
585  } else if ((!q->isVisible() && !frame()) && toggleAction->isChecked()) {
586  toggleAction->setChecked(false);
587  }
588 }
589 
590 void DockWidgetBase::Private::updateFloatAction()
591 {
592  QScopedValueRollback<bool> recursionGuard(m_updatingFloatAction, true); // Guard against recursiveness
593 
594  if (q->isFloating()) {
595  floatAction->setEnabled(m_lastPositions.isValid());
596  floatAction->setChecked(true);
597  floatAction->setToolTip(tr("Dock"));
598  } else {
599  floatAction->setEnabled(true);
600  floatAction->setChecked(false);
601  floatAction->setToolTip(tr("Detach"));
602  }
603 }
604 
605 void DockWidgetBase::Private::onDockWidgetShown()
606 {
607  updateToggleAction();
608  updateFloatAction();
609 }
610 
611 void DockWidgetBase::Private::onDockWidgetHidden()
612 {
613  updateToggleAction();
614  updateFloatAction();
615 }
616 
617 void DockWidgetBase::Private::close()
618 {
619  if (!m_processingToggleAction && !q->isOpen()) {
620  return;
621  }
622 
623  // If it's overlayed and we're closing, we need to close the overlay
624  if (SideBar *sb = DockRegistry::self()->sideBarForDockWidget(q)) {
625  auto mainWindow = sb->mainWindow();
626  if (mainWindow->overlayedDockWidget() == q) {
627  mainWindow->clearSideBarOverlay(/* deleteFrame=*/false);
628  }
629  }
630 
631  if (!m_isForceClosing && q->isFloating()
632  && q->isVisible()) { // only user-closing is interesting to save the geometry
633  // We check for isVisible so we don't save geometry if you call close() on an already closed
634  // dock widget
635  m_lastPositions.setLastFloatingGeometry(q->window()->geometry());
636  }
637 
638  saveTabIndex();
639 
640  // Do some cleaning. Widget is hidden, but we must hide the tab containing it.
641  if (Frame *frame = this->frame()) {
642  q->setParent(nullptr);
643  frame->removeWidget(q);
644 
645  if (SideBar *sb = DockRegistry::self()->sideBarForDockWidget(q)) {
646  sb->removeDockWidget(q);
647  }
648  }
649 
650  if (!m_isMovingToSideBar && (options & DockWidgetBase::Option_DeleteOnClose)) {
651  Q_EMIT q->aboutToDeleteOnClose();
652  q->deleteLater();
653  }
654 }
655 
656 bool DockWidgetBase::Private::restoreToPreviousPosition()
657 {
658  if (!m_lastPositions.isValid())
659  return false;
660 
661  Layouting::Item *item = m_lastPositions.lastItem();
662 
663  LayoutWidget *layout = DockRegistry::self()->layoutForItem(item);
664  Q_ASSERT(layout);
665  layout->restorePlaceholder(q, item, m_lastPositions.lastTabIndex());
666  return true;
667 }
668 
669 void DockWidgetBase::Private::maybeRestoreToPreviousPosition()
670 {
671  // This is called when we get a QEvent::Show. Let's see if we have to restore it to a previous position.
672 
673  if (!m_lastPositions.isValid())
674  return;
675 
676  Layouting::Item *layoutItem = m_lastPositions.lastItem();
677  if (!layoutItem)
678  return; // nothing to do, no last position
679 
680  if (m_lastPositions.wasFloating())
681  return; // Nothing to do, it was floating before, now it'll just get visible
682 
683  Frame *frame = this->frame();
684 
685  if (frame && frame->QWidgetAdapter::parentWidget() == DockRegistry::self()->layoutForItem(layoutItem)) {
686  // There's a frame already. Means the DockWidget was hidden instead of closed.
687  // Nothing to do, the dock widget will simply be shown
688  return;
689  }
690 
691  // Now we deal with the case where the DockWidget was close()ed. In this case it doesn't have a parent.
692 
693  if (q->parentWidget()) {
694  // The QEvent::Show is due to it being made floating. Nothing to restore.
695  return;
696  }
697 
698  // Finally, restore it
699  restoreToPreviousPosition();
700 }
701 
702 int DockWidgetBase::Private::currentTabIndex() const
703 {
704  Frame *frame = this->frame();
705  return frame ? frame->indexOfDockWidget(q) : 0;
706 }
707 
708 void DockWidgetBase::Private::saveTabIndex()
709 {
710  m_lastPositions.saveTabIndex(currentTabIndex(), q->isFloating());
711 }
712 
713 void DockWidgetBase::Private::show()
714 {
715  // Only show for now
716  q->show();
717 }
718 
720 {
721 #ifdef KDDOCKWIDGETS_QTWIDGETS
722  // TODO: In v1.4, remove this part and use the signal emitting the arg
723  Q_EMIT parentChanged();
724 #else
725  Q_EMIT parentChanged(this);
726 #endif
727  d->updateToggleAction();
728  d->updateFloatAction();
729 
730  Q_EMIT actualTitleBarChanged();
731 }
732 
733 void DockWidgetBase::onShown(bool spontaneous)
734 {
735  d->onDockWidgetShown();
736  Q_EMIT shown();
737 
738  if (Frame *f = d->frame()) {
739  if (!spontaneous) {
740  f->onDockWidgetShown(this);
741  }
742  }
743 
744  d->maybeRestoreToPreviousPosition();
745 
746  // Transform into a FloatingWindow if this will be a regular floating dock widget.
747  QTimer::singleShot(0, d, &DockWidgetBase::Private::maybeMorphIntoFloatingWindow);
748 }
749 
750 void DockWidgetBase::onHidden(bool spontaneous)
751 {
752  d->onDockWidgetHidden();
753  Q_EMIT hidden();
754 
755  if (Frame *f = d->frame()) {
756  if (!spontaneous) {
757  f->onDockWidgetHidden(this);
758  }
759  }
760 }
761 
763 {
764  if (isOverlayed()) {
765  if (auto frame = d->frame()) {
766  d->m_lastOverlayedSize = frame->QWidgetAdapter::size();
767  } else {
768  qWarning() << Q_FUNC_INFO << "Overlayed dock widget without frame shouldn't happen";
769  }
770  }
771 
772  return QWidgetAdapter::onResize(newSize);
773 }
774 
776 {
777  e->accept(); // By default we accept, means DockWidget closes
778  if (d->widget)
779  qApp->sendEvent(d->widget, e); // Give a chance for the widget to ignore
780 
781  if (e->isAccepted())
782  d->close();
783 }
784 
785 DockWidgetBase *DockWidgetBase::deserialize(const LayoutSaver::DockWidget::Ptr &saved)
786 {
787  auto dr = DockRegistry::self();
788  DockWidgetBase *dw = dr->dockByName(saved->uniqueName, DockRegistry::DockByNameFlag::CreateIfNotFound);
789  if (dw) {
790  if (QWidgetOrQuick *w = dw->widget())
791  w->setVisible(true);
792  dw->setProperty("kddockwidget_was_restored", true);
793 
794  if (dw->affinities() != saved->affinities) {
795  qWarning() << Q_FUNC_INFO << "Affinity name changed from" << dw->affinities()
796  << "; to" << saved->affinities;
797  dw->d->affinities = saved->affinities;
798  }
799  }
800 
801  return dw;
802 }
803 
804 void DockWidgetBase::setUserType(int userType)
805 {
806  d->m_userType = userType;
807 }
808 
810 {
811  return d->m_userType;
812 }
813 
815 {
816  if (MDILayoutWidget *layout = d->mdiLayout())
817  layout->moveDockWidget(this, pos);
818 }
819 
821 {
822  if (MDILayoutWidget *layout = d->mdiLayout())
823  layout->resizeDockWidget(this, size);
824 }
825 
827 {
828 #ifdef KDDOCKWIDGETS_QTQUICK
829  if (Frame *frame = d->frame()) {
830  if (!frame->isMDI())
831  return;
832  frame->setZ(z);
833  }
834 #else
835  Q_UNUSED(z);
836  qWarning() << Q_FUNC_INFO << "Not implemented for QtQuick";
837 #endif
838 }
839 
840 LayoutSaver::DockWidget::Ptr DockWidgetBase::Private::serialize() const
841 {
842  auto ptr = LayoutSaver::DockWidget::dockWidgetForName(q->uniqueName());
843  ptr->affinities = q->affinities();
844 
845  return ptr;
846 }
847 
848 void DockWidgetBase::Private::forceClose()
849 {
850  QScopedValueRollback<bool> rollback(m_isForceClosing, true);
851  close();
852 }
853 
854 DockWidgetBase::Private::Private(const QString &dockName, DockWidgetBase::Options options_,
855  LayoutSaverOptions layoutSaverOptions_, DockWidgetBase *qq)
856 
857  : name(dockName)
858  , title(dockName)
859  , q(qq)
860  , options(options_)
861  , layoutSaverOptions(layoutSaverOptions_)
862  , toggleAction(new QAction(q))
863  , floatAction(new QAction(q))
864 {
865  q->connect(toggleAction, &QAction::toggled, q, [this](bool enabled) {
866  if (!m_updatingToggleAction) { // guard against recursiveness
867  toggleAction->blockSignals(true); // and don't emit spurious toggle. Like when a dock
868  // widget is inserted into a tab widget it might get
869  // hide events, ignore those. The Dock Widget is open.
870  m_processingToggleAction = true;
871  toggle(enabled);
872  toggleAction->blockSignals(false);
873  m_processingToggleAction = false;
874  }
875  });
876 
877  q->connect(floatAction, &QAction::toggled, q, [this](bool checked) {
878  if (!m_updatingFloatAction) { // guard against recursiveness
879  q->setFloating(checked);
880  }
881 
882  Q_EMIT q->isFloatingChanged(checked);
883 
884  // When floating, we remove from the sidebar
885  if (checked && q->isOpen()) {
886  if (SideBar *sb = DockRegistry::self()->sideBarForDockWidget(q)) {
887  sb->mainWindow()->clearSideBarOverlay(/* deleteFrame=*/false);
888  sb->removeDockWidget(q);
889  }
890  }
891  });
892 
893  toggleAction->setCheckable(true);
894  floatAction->setCheckable(true);
895 
896  qApp->installEventFilter(this);
897 }
898 
899 void DockWidgetBase::Private::addPlaceholderItem(Layouting::Item *item)
900 {
901  Q_ASSERT(item);
902  m_lastPositions.addPosition(item);
903 }
904 
905 LastPositions &DockWidgetBase::Private::lastPositions()
906 {
907  return m_lastPositions;
908 }
909 
910 Frame *DockWidgetBase::Private::frame() const
911 {
912  QWidgetOrQuick *p = q->parentWidget();
913  while (p) {
914  if (auto frame = qobject_cast<Frame *>(p))
915  return frame;
916  p = p->parentWidget();
917  }
918  return nullptr;
919 }
920 
921 void DockWidgetBase::Private::saveLastFloatingGeometry()
922 {
923  if (q->isFloating() && q->isVisible()) {
924  // It's getting docked, save last floating position
925  lastPositions().setLastFloatingGeometry(q->window()->geometry());
926  }
927 }
KDDockWidgets::DockWidgetBase::optionsChanged
void optionsChanged(KDDockWidgets::DockWidgetBase::Options)
emitted when the options change
KDDockWidgets::DockWidgetBase::show
Q_INVOKABLE void show()
Equivalent to QWidget::show(), but it's optimized to reduce flickering on some platforms.
Definition: DockWidgetBase.cpp:361
KDDockWidgets::SuggestedGeometryHint_PreserveCenter
@ SuggestedGeometryHint_PreserveCenter
Definition: KDDockWidgets.h:201
DockWidgetBase.h
The DockWidget base-class that's shared between QtWidgets and QtQuick stack.
QRect::setSize
void setSize(const QSize &size)
KDDockWidgets::DockWidgetBase::MDILayoutWidget
friend class MDILayoutWidget
Definition: DockWidgetBase.h:526
KDDockWidgets::DockWidgetBase::addDockWidgetAsTab
Q_INVOKABLE void addDockWidgetAsTab(KDDockWidgets::DockWidgetBase *other, KDDockWidgets::InitialOption initialOption={})
docks other widget into this one. Tabs will be shown if not already.
Definition: DockWidgetBase.cpp:63
QVector::isEmpty
bool isEmpty() const const
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:130
KDDockWidgets::DockWidgetBase::setAffinityName
void setAffinityName(const QString &name)
Definition: DockWidgetBase.cpp:409
KDDockWidgets::DockWidgetBase::isTabbed
bool isTabbed() const
returns if this dock widget is tabbed into another
Definition: DockWidgetBase.cpp:276
KDDockWidgets::DockWidgetBase::mainWindow
MainWindowBase * mainWindow() const
Returns the main window this dock widget is in. nullptr if it's not inside a main window Also returns...
Definition: DockWidgetBase.cpp:398
QEvent::WindowActivate
WindowActivate
KDDockWidgets::DockWidgetBase::setMDISize
void setMDISize(QSize size)
like setMDIPosition(), but for the size.
Definition: DockWidgetBase.cpp:820
KDDockWidgets::DockWidgetBase::affinities
QStringList affinities() const
Returns the affinity name. Empty by default.
Definition: DockWidgetBase.cpp:356
QRect::size
QSize size() const const
KDDockWidgets::DockWidgetBase::LayoutSaverOption::Skip
@ Skip
The dock widget won't participate in save/restore. Currently only available for floating windows.
KDDockWidgets::DockWidgetBase::byName
static DockWidgetBase * byName(const QString &uniqueName)
Returns a dock widget by its name This is the same name you passed to DockWidget CTOR....
Definition: DockWidgetBase.cpp:466
QWidget::sizePolicy
sizePolicy
QRect
KDDockWidgets::DockWidgetBase::setFloating
bool setFloating(bool floats)
setter to make the dock widget float or dock.
Definition: DockWidgetBase.cpp:172
KDDockWidgets::DockWidgetBase::isFocused
bool isFocused
Definition: DockWidgetBase.h:63
QList::removeAll
int removeAll(const T &value)
KDDockWidgets::DockWidgetBase::IconPlace::ToggleAction
@ ToggleAction
KDDockWidgets::InitialOption
Struct describing the preferred dock widget size and visibility when adding it to a layout.
Definition: KDDockWidgets.h:103
KDDockWidgets::DockWidgetBase::sideBarLocation
SideBarLocation sideBarLocation() const
Returns whether this dock widget is in a side bar, and which. SideBarLocation::None is returned if it...
Definition: DockWidgetBase.cpp:446
QTimer::singleShot
singleShot
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:338
QWidget
KDDockWidgets::DockWidgetBase::onResize
bool onResize(QSize newSize) override
Definition: DockWidgetBase.cpp:762
KDDockWidgets::Location
Location
Definition: KDDockWidgets.h:45
KDDockWidgets::DockWidgetBase::iconChanged
void iconChanged()
signal emitted when the icon changed
KDDockWidgets::DockWidgetBase::addDockWidgetToContainingWindow
Q_INVOKABLE void addDockWidgetToContainingWindow(KDDockWidgets::DockWidgetBase *other, KDDockWidgets::Location location, KDDockWidgets::DockWidgetBase *relativeTo=nullptr, KDDockWidgets::InitialOption initialOption={})
docks other widget into the window that contains this one. Equivalent to MainWindow::addDockWidget() ...
Definition: DockWidgetBase.cpp:109
KDDockWidgets::DockWidgetBase::widgetChanged
void widgetChanged(KDDockWidgets::QWidgetOrQuick *)
emitted when the hosted widget changed
KDDockWidgets::DockWidgetBase::uniqueName
QString uniqueName
Definition: DockWidgetBase.h:65
QSize
KDDockWidgets::DockWidgetBase::isInMainWindow
bool isInMainWindow() const
Returns whether this dock widget is docked into a main window (as opposed to floating)
Definition: DockWidgetBase.cpp:393
KDDockWidgets::DockWidgetBase::Option_NotDockable
@ Option_NotDockable
The DockWidget can't be docked, it's always floating.
Definition: DockWidgetBase.h:78
KDDockWidgets::DockWidgetBase::setMDIZ
void setMDIZ(int z)
like setMDIPosition(), but for the Z only implemented for QtQuick
Definition: DockWidgetBase.cpp:826
KDDockWidgets::DockWidgetBase::isOverlayed
bool isOverlayed() const
Returns whether this dock widget is overlayed from the side-bar.
Definition: DockWidgetBase.cpp:438
KDDockWidgets::DockWidgetBase::title
QString title
Definition: DockWidgetBase.h:66
KDDockWidgets::DockWidgetBase::widget
QObject * widget
Definition: DockWidgetBase.h:67
KDDockWidgets::DockWidgetBase::onCloseEvent
void onCloseEvent(QCloseEvent *e) override
Definition: DockWidgetBase.cpp:775
KDDockWidgets::DockWidgetBase::isOpen
Q_INVOKABLE bool isOpen() const
Returns whether this dock widget is open. Equivalent to calling toggleAction().isChecked() or isVisib...
Definition: DockWidgetBase.cpp:351
KDDockWidgets::DockWidgetBase::isFloating
bool isFloating
Definition: DockWidgetBase.h:64
KDDockWidgets::DockWidgetBase::isInSideBar
bool isInSideBar() const
Returns where this dockwidget is in a sidebar Similar to sideBarLocation(), but returns a bool.
Definition: DockWidgetBase.cpp:451
QObject::eventFilter
virtual bool eventFilter(QObject *watched, QEvent *event)
KDDockWidgets::DockWidgetBase::titleChanged
void titleChanged(const QString &title)
signal emitted when the title changed
KDDockWidgets::DockWidgetBase::raise
Q_INVOKABLE void raise()
Brings the dock widget to the front.
Definition: DockWidgetBase.cpp:372
KDDockWidgets::DockWidgetBase::DockWidgetBase
DockWidgetBase(const QString &uniqueName, Options options=KDDockWidgets::DockWidgetBase::Options(), LayoutSaverOptions layoutSaverOptions=KDDockWidgets::DockWidgetBase::LayoutSaverOptions())
constructs a new DockWidget
Definition: DockWidgetBase.cpp:43
KDDockWidgets::DockWidgetBase::setWidget
virtual void setWidget(QWidgetOrQuick *widget)
sets the widget which this dock widget hosts.
Definition: DockWidgetBase.cpp:141
KDDockWidgets::DockWidgetBase::setAsCurrentTab
Q_INVOKABLE void setAsCurrentTab()
Makes this dock widget current in its tab group.
Definition: DockWidgetBase.cpp:296
QCloseEvent
QObject
QVector::constFirst
const T & constFirst() const const
KDDockWidgets::SideBarLocation::None
@ None
QObject::blockSignals
bool blockSignals(bool block)
QAction::toggled
void toggled(bool checked)
KDDockWidgets::DockWidgetBase::skipsRestore
bool skipsRestore() const
Returns whether this widget has the LayoutSaverOption::Skip flag.
Definition: DockWidgetBase.cpp:471
QString
Qt
QEvent::isAccepted
bool isAccepted() const const
KDDockWidgets::Config::InternalFlag_DontShowWhenUnfloatingHiddenWindow
@ InternalFlag_DontShowWhenUnfloatingHiddenWindow
DockWidget::setFloating(false) won't do anything if the window is hidden.
Definition: Config.h:113
QString::isEmpty
bool isEmpty() const const
KDDockWidgets::DockWidgetBase::IconPlace::TitleBar
@ TitleBar
KDDockWidgets::DockWidgetBase::~DockWidgetBase
~DockWidgetBase() override
destructor
Definition: DockWidgetBase.cpp:57
QSize::boundedTo
QSize boundedTo(const QSize &otherSize) const const
KDDockWidgets::DockWidgetBase::isMainWindow
bool isMainWindow() const
Returns whether widget() is a KDDockWidget::MainWindow.
Definition: DockWidgetBase.cpp:388
KDDockWidgets::DockWidgetBase::onHidden
void onHidden(bool spontaneous)
Definition: DockWidgetBase.cpp:750
KDDockWidgets::DockWidgetBase::IconPlace
IconPlace
Definition: DockWidgetBase.h:93
KDDockWidgets::Config::frameworkWidgetFactory
FrameworkWidgetFactory * frameworkWidgetFactory() const
getter for the framework widget factory
Definition: Config.cpp:143
KDDockWidgets::DockWidgetBase::actualTitleBarChanged
void actualTitleBarChanged()
Emitted when the title bar that serves this dock widget changes.
QIcon
KDDockWidgets::DockWidgetBase::userType
int userType() const
Definition: DockWidgetBase.cpp:809
QRect::isNull
bool isNull() const const
KDDockWidgets::DockWidgetBase::Option_DeleteOnClose
@ Option_DeleteOnClose
Deletes the DockWidget when closed.
Definition: DockWidgetBase.h:79
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:209
QAction::setCheckable
void setCheckable(bool)
KDDockWidgets::DockWidgetBase::toggleAction
Q_INVOKABLE QAction * toggleAction() const
Returns the QAction that allows to hide/show the dock widget Useful to put in menus.
Definition: DockWidgetBase.cpp:213
KDDockWidgets::DockWidgetBase::lastOverlayedSize
QSize lastOverlayedSize() const
returns the last size the widget has when overlayed Empty otherwise
Definition: DockWidgetBase.cpp:461
QRect::moveCenter
void moveCenter(const QPoint &position)
QWidget::show
void show()
KDDockWidgets::FrameworkWidgetFactory::createFloatingWindow
virtual FloatingWindow * createFloatingWindow(MainWindowBase *parent=nullptr) const =0
Called internally by the framework to create a FloatingWindow Override to provide your own FloatingWi...
KDDockWidgets::DockWidgetBase::frameGeometry
QRect frameGeometry() const
Returns the size of the dock widget's parent frame.
Definition: DockWidgetBase.cpp:242
Config.h
Application-wide config to tune certain behaviours of the framework.
KDDockWidgets::DockWidgetBase::icon
QIcon icon(IconPlace place=IconPlace::TitleBar) const
Returns the dock widget's titlebar, tabbar, or toggle action icon (depending on the passed place)
Definition: DockWidgetBase.cpp:324
KDDockWidgets::DockWidgetBase::setMDIPosition
void setMDIPosition(QPoint pos)
Sets this dock widgets position to pos within the MDI layout This only applies if the main window is ...
Definition: DockWidgetBase.cpp:814
KDDockWidgets::DockWidgetBase::titleBar
TitleBar * titleBar() const
Returns this dock widget's title bar.
Definition: DockWidgetBase.cpp:343
KDDockWidgets::DockWidgetBase::moveToSideBar
Q_INVOKABLE void moveToSideBar()
Minimizes this dock widget to the MainWindow's side-bar.
Definition: DockWidgetBase.cpp:432
KDDockWidgets::DockWidgetBase::setAffinities
void setAffinities(const QStringList &)
Sets the affinity names. Dock widgets can only dock into dock widgets of the same affinity.
Definition: DockWidgetBase.cpp:414
QEvent
KDDockWidgets::DockWidgetBase::Frame
friend class Frame
Definition: DockWidgetBase.h:527
KDDockWidgets::DockWidgetBase::setTitle
void setTitle(const QString &title)
setter for the dock widget's title
Definition: DockWidgetBase.cpp:233
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::DockWidgetBase::hasPreviousDockedLocation
bool hasPreviousDockedLocation() const
Returns whether this floating dock widget knows its previous docked location Result only makes sense ...
Definition: DockWidgetBase.cpp:456
QAction
KDDockWidgets::DockWidgetBase::hidden
void hidden()
signal emitted when the DockWidget is hidden. As in QEvent::Hide.
KDDockWidgets
Definition: Config.cpp:36
QScopedValueRollback
KDDockWidgets::DockWidgetBase::setFloatingGeometry
void setFloatingGeometry(QRect geo)
If this dock widget is floating, then sets its geometry to geo.
Definition: DockWidgetBase.cpp:476
QWidget::geometry
geometry
KDDockWidgets::DockWidgetBase::setUserType
void setUserType(int userType)
Allows the user to set a type on this dock widget The type is opaque and will not be interpreted by K...
Definition: DockWidgetBase.cpp:804
KDDockWidgets::DockWidgetBase::parentChanged
void parentChanged()
signal emitted when the parent changed
KDDockWidgets::DockWidgetBase::tabIndex
int tabIndex() const
Returns which tab index this dock widget occupies in the tab widget it's contained in.
Definition: DockWidgetBase.cpp:302
KDDockWidgets::MainWindowBase
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
Definition: MainWindowBase.h:56
KDDockWidgets::DockWidgetBase::setIcon
void setIcon(const QIcon &icon, IconPlaces places=IconPlace::All)
Sets an icon to show on title bars and tab bars.
Definition: DockWidgetBase.cpp:310
KDDockWidgets::DockWidgetBase::floatAction
Q_INVOKABLE QAction * floatAction() const
Returns the QAction that allows to dock/undock the dock widget Useful to put in menus.
Definition: DockWidgetBase.cpp:218
QVector
KDDockWidgets::DockWidgetBase::shown
void shown()
signal emitted when the DockWidget is shown. As in QEvent::Show.
KDDockWidgets::DockWidgetBase::layoutSaverOptions
KDDockWidgets::DockWidgetBase::LayoutSaverOptions layoutSaverOptions() const
returns the per-dockwidget options which will affect LayoutSaver These are the options which were pas...
Definition: DockWidgetBase.cpp:256
KDDockWidgets::DockWidgetBase::options
KDDockWidgets::DockWidgetBase::Options options
Definition: DockWidgetBase.h:69
KDDockWidgets::DockWidgetBase::isCurrentTab
bool isCurrentTab() const
Returns true if this dock widget is the current one in the tab widget that contains it....
Definition: DockWidgetBase.cpp:287
QWidget::parentWidget
QWidget * parentWidget() const const
KDDockWidgets::DockWidgetBase::setOptions
void setOptions(Options)
Setter for the options. Only Option_NotClosable is allowed to change after construction....
Definition: DockWidgetBase.cpp:261
KDDockWidgets::DockWidgetBase::IconPlace::TabBar
@ TabBar
Qt::WA_PendingMoveEvent
WA_PendingMoveEvent
KDDockWidgets::DockWidgetBase::onShown
void onShown(bool spontaneous)
Definition: DockWidgetBase.cpp:733
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
KDDockWidgets::DockWidgetBase::onParentChanged
void onParentChanged()
Definition: DockWidgetBase.cpp:719

© 2019-2021 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 Nov 15 2021 00:17:18 for KDDockWidgets API Documentation by doxygen 1.8.20