1 /****************************************************************************
2 **
3 ** Copyright (C) 2020 Uwe Kindler
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 or (at your option) any later version.
19 ** The licenses are as published by the Free Software Foundation
20 ** and appearing in the file LICENSE.LGPLv21 included in the packaging
21 ** of this file. Please review the following information to ensure
22 ** the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 3 or (at your option) any later version
28 ** approved by the KDE Free Qt Foundation. The licenses are as published by
29 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
30 ** included in the packaging of this file. Please review the following
31 ** information to ensure the GNU General Public License requirements will
32 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
33 **
34 ****************************************************************************/
35 
36 #include "dockwidget.h"
37 
38 #include "ads_globals.h"
39 #include "dockareawidget.h"
40 #include "dockcomponentsfactory.h"
41 #include "dockcontainerwidget.h"
42 #include "dockmanager.h"
43 #include "docksplitter.h"
44 #include "dockwidgettab.h"
45 #include "floatingdockcontainer.h"
46 
47 #include <QAction>
48 #include <QBoxLayout>
49 #include <QEvent>
50 #include <QLoggingCategory>
51 #include <QPointer>
52 #include <QScrollArea>
53 #include <QSplitter>
54 #include <QStack>
55 #include <QTextStream>
56 #include <QToolBar>
57 #include <QXmlStreamWriter>
58 #include <QWindow>
59 
60 static Q_LOGGING_CATEGORY(adsLog, "qtc.qmldesigner.advanceddockingsystem", QtWarningMsg)
61 
62 namespace ADS
63 {
64     /**
65      * Private data class of DockWidget class (pimpl)
66      */
67     class DockWidgetPrivate
68     {
69     public:
70         DockWidget *q = nullptr;
71         QBoxLayout *m_layout = nullptr;
72         QWidget *m_widget = nullptr;
73         DockWidgetTab *m_tabWidget = nullptr;
74         DockWidget::DockWidgetFeatures m_features = DockWidget::DefaultDockWidgetFeatures;
75         DockManager *m_dockManager = nullptr;
76         DockAreaWidget *m_dockArea = nullptr;
77         QAction *m_toggleViewAction = nullptr;
78         bool m_closed = false;
79         QScrollArea *m_scrollArea = nullptr;
80         QToolBar *m_toolBar = nullptr;
81         Qt::ToolButtonStyle m_toolBarStyleDocked = Qt::ToolButtonIconOnly;
82         Qt::ToolButtonStyle m_toolBarStyleFloating = Qt::ToolButtonTextUnderIcon;
83         QSize m_toolBarIconSizeDocked = QSize(16, 16);
84         QSize m_toolBarIconSizeFloating = QSize(24, 24);
85         bool m_isFloatingTopLevel = false;
86         QList<QAction *> m_titleBarActions;
87         DockWidget::eMinimumSizeHintMode m_minimumSizeHintMode = DockWidget::MinimumSizeHintFromDockWidget;
88 
89         /**
90          * Private data constructor
91          */
92         DockWidgetPrivate(DockWidget *parent);
93 
94         /**
95          * Show dock widget
96          */
97         void showDockWidget();
98 
99         /**
100          * Hide dock widget.
101          */
102         void hideDockWidget();
103 
104         /**
105          * Hides a dock area if all dock widgets in the area are closed.
106          * This function updates the current selected tab and hides the parent
107          * dock area if it is empty
108          */
109         void updateParentDockArea();
110 
111         /**
112          * Setup the top tool bar
113          */
114         void setupToolBar();
115 
116         /**
117          * Setup the main scroll area
118          */
119         void setupScrollArea();
120     }; // class DockWidgetPrivate
121 
DockWidgetPrivate(DockWidget * parent)122     DockWidgetPrivate::DockWidgetPrivate(DockWidget *parent)
123         : q(parent)
124     {}
125 
showDockWidget()126     void DockWidgetPrivate::showDockWidget()
127     {
128         if (!m_dockArea) {
129             FloatingDockContainer *floatingWidget = new FloatingDockContainer(q);
130             floatingWidget->resize(q->size());
131             m_tabWidget->show();
132             floatingWidget->show();
133         } else {
134             m_dockArea->setCurrentDockWidget(q);
135             m_dockArea->toggleView(true);
136             m_tabWidget->show();
137             QSplitter *splitter = internal::findParent<QSplitter *>(m_dockArea);
138             while (splitter && !splitter->isVisible()) {
139                 splitter->show();
140                 splitter = internal::findParent<QSplitter *>(splitter);
141             }
142 
143             DockContainerWidget *container = m_dockArea->dockContainer();
144             if (container->isFloating()) {
145                 FloatingDockContainer *floatingWidget
146                     = internal::findParent<FloatingDockContainer *>(container);
147                 floatingWidget->show();
148             }
149         }
150     }
151 
hideDockWidget()152     void DockWidgetPrivate::hideDockWidget()
153     {
154         m_tabWidget->hide();
155         updateParentDockArea();
156     }
157 
updateParentDockArea()158     void DockWidgetPrivate::updateParentDockArea()
159     {
160         if (!m_dockArea)
161             return;
162 
163         // we don't need to change the current tab if the current DockWidget is not the one being closed
164         if (m_dockArea->currentDockWidget() != q)
165             return;
166 
167         auto nextDockWidget = m_dockArea->nextOpenDockWidget(q);
168         if (nextDockWidget)
169             m_dockArea->setCurrentDockWidget(nextDockWidget);
170         else
171             m_dockArea->hideAreaWithNoVisibleContent();
172     }
173 
setupToolBar()174     void DockWidgetPrivate::setupToolBar()
175     {
176         m_toolBar = new QToolBar(q);
177         m_toolBar->setObjectName("dockWidgetToolBar");
178         m_layout->insertWidget(0, m_toolBar);
179         m_toolBar->setIconSize(QSize(16, 16));
180         m_toolBar->toggleViewAction()->setEnabled(false);
181         m_toolBar->toggleViewAction()->setVisible(false);
182         QObject::connect(q, &DockWidget::topLevelChanged, q, &DockWidget::setToolbarFloatingStyle);
183     }
184 
setupScrollArea()185     void DockWidgetPrivate::setupScrollArea()
186     {
187         m_scrollArea = new QScrollArea(q);
188         m_scrollArea->setObjectName("dockWidgetScrollArea");
189         m_scrollArea->setWidgetResizable(true);
190         m_layout->addWidget(m_scrollArea);
191     }
192 
DockWidget(const QString & uniqueId,QWidget * parent)193     DockWidget::DockWidget(const QString &uniqueId, QWidget *parent)
194         : QFrame(parent)
195         , d(new DockWidgetPrivate(this))
196     {
197         d->m_layout = new QBoxLayout(QBoxLayout::TopToBottom);
198         d->m_layout->setContentsMargins(0, 0, 0, 0);
199         d->m_layout->setSpacing(0);
200         setLayout(d->m_layout);
201         setWindowTitle(uniqueId); // temporarily use unique id as title
202         setObjectName(uniqueId);
203 
204         d->m_tabWidget = componentsFactory()->createDockWidgetTab(this);
205         d->m_toggleViewAction = new QAction(uniqueId, this);
206         d->m_toggleViewAction->setCheckable(true);
207         connect(d->m_toggleViewAction, &QAction::triggered, this, &DockWidget::toggleView);
208         setToolbarFloatingStyle(false);
209 
210         if (DockManager::testConfigFlag(DockManager::FocusHighlighting))
211             setFocusPolicy(Qt::ClickFocus);
212     }
213 
~DockWidget()214     DockWidget::~DockWidget()
215     {
216         qCInfo(adsLog) << Q_FUNC_INFO;
217         delete d;
218     }
219 
setToggleViewActionChecked(bool checked)220     void DockWidget::setToggleViewActionChecked(bool checked)
221     {
222         QAction *action = d->m_toggleViewAction;
223         //action->blockSignals(true);
224         action->setChecked(checked);
225         //action->blockSignals(false);
226     }
227 
setWidget(QWidget * widget,eInsertMode insertMode)228     void DockWidget::setWidget(QWidget *widget, eInsertMode insertMode)
229     {
230         if (d->m_widget)
231             takeWidget();
232 
233         auto scrollAreaWidget = qobject_cast<QAbstractScrollArea *>(widget);
234         if (scrollAreaWidget || ForceNoScrollArea == insertMode) {
235             d->m_layout->addWidget(widget);
236             if (scrollAreaWidget && scrollAreaWidget->viewport())
237                 scrollAreaWidget->viewport()->setProperty("dockWidgetContent", true);
238         } else {
239             d->setupScrollArea();
240             d->m_scrollArea->setWidget(widget);
241         }
242 
243         d->m_widget = widget;
244         d->m_widget->setProperty("dockWidgetContent", true);
245     }
246 
takeWidget()247     QWidget *DockWidget::takeWidget()
248     {
249         QWidget *w = nullptr;
250         if (d->m_scrollArea) {
251             d->m_layout->removeWidget(d->m_scrollArea);
252             w = d->m_scrollArea->takeWidget();
253             delete d->m_scrollArea;
254             d->m_scrollArea = nullptr;
255             d->m_widget = nullptr;
256         } else if (d->m_widget) {
257             d->m_layout->removeWidget(d->m_widget);
258             w = d->m_widget;
259             d->m_widget = nullptr;
260         }
261 
262         if (w)
263             w->setParent(nullptr);
264 
265         return w;
266     }
267 
widget() const268     QWidget *DockWidget::widget() const { return d->m_widget; }
269 
tabWidget() const270     DockWidgetTab *DockWidget::tabWidget() const { return d->m_tabWidget; }
271 
setFeatures(DockWidgetFeatures features)272     void DockWidget::setFeatures(DockWidgetFeatures features)
273     {
274         if (d->m_features == features)
275             return;
276 
277         d->m_features = features;
278         emit featuresChanged(d->m_features);
279         d->m_tabWidget->onDockWidgetFeaturesChanged();
280     }
281 
setFeature(DockWidgetFeature flag,bool on)282     void DockWidget::setFeature(DockWidgetFeature flag, bool on)
283     {
284         auto currentFeatures = features();
285         internal::setFlag(currentFeatures, flag, on);
286         setFeatures(currentFeatures);
287     }
288 
features() const289     DockWidget::DockWidgetFeatures DockWidget::features() const { return d->m_features; }
290 
dockManager() const291     DockManager *DockWidget::dockManager() const { return d->m_dockManager; }
292 
setDockManager(DockManager * dockManager)293     void DockWidget::setDockManager(DockManager *dockManager) { d->m_dockManager = dockManager; }
294 
dockContainer() const295     DockContainerWidget *DockWidget::dockContainer() const
296     {
297         if (d->m_dockArea)
298             return d->m_dockArea->dockContainer();
299         else
300             return nullptr;
301     }
302 
dockAreaWidget() const303     DockAreaWidget *DockWidget::dockAreaWidget() const { return d->m_dockArea; }
304 
isFloating() const305     bool DockWidget::isFloating() const
306     {
307         if (!isInFloatingContainer())
308             return false;
309 
310         return dockContainer()->topLevelDockWidget() == this;
311     }
312 
isInFloatingContainer() const313     bool DockWidget::isInFloatingContainer() const
314     {
315         auto container = dockContainer();
316         if (!container)
317             return false;
318 
319         if (!container->isFloating())
320             return false;
321 
322         return true;
323     }
324 
isClosed() const325     bool DockWidget::isClosed() const { return d->m_closed; }
326 
toggleViewAction() const327     QAction *DockWidget::toggleViewAction() const { return d->m_toggleViewAction; }
328 
setToggleViewActionMode(eToggleViewActionMode mode)329     void DockWidget::setToggleViewActionMode(eToggleViewActionMode mode)
330     {
331         if (ActionModeToggle == mode) {
332             d->m_toggleViewAction->setCheckable(true);
333             d->m_toggleViewAction->setIcon(QIcon());
334         } else {
335             d->m_toggleViewAction->setCheckable(false);
336             d->m_toggleViewAction->setIcon(d->m_tabWidget->icon());
337         }
338     }
339 
setMinimumSizeHintMode(eMinimumSizeHintMode mode)340     void DockWidget::setMinimumSizeHintMode(eMinimumSizeHintMode mode)
341     {
342         d->m_minimumSizeHintMode = mode;
343     }
344 
toggleView(bool open)345     void DockWidget::toggleView(bool open)
346     {
347         // If the toggle view action mode is ActionModeShow, then Open is always
348         // true if the sender is the toggle view action
349         QAction *action = qobject_cast<QAction *>(sender());
350         if (action == d->m_toggleViewAction && !d->m_toggleViewAction->isCheckable())
351             open = true;
352 
353         // If the dock widget state is different, then we really need to toggle
354         // the state. If we are in the right state, then we simply make this
355         // dock widget the current dock widget
356         if (d->m_closed != !open)
357             toggleViewInternal(open);
358         else if (open && d->m_dockArea)
359             d->m_dockArea->setCurrentDockWidget(this);
360     }
361 
toggleViewInternal(bool open)362     void DockWidget::toggleViewInternal(bool open)
363     {
364         const DockContainerWidget *const beforeDockContainerWidget = dockContainer();
365         DockWidget *topLevelDockWidgetBefore = beforeDockContainerWidget
366                                                    ? beforeDockContainerWidget->topLevelDockWidget()
367                                                    : nullptr;
368 
369         if (open)
370             d->showDockWidget();
371         else
372             d->hideDockWidget();
373 
374         d->m_closed = !open;
375         //d->m_toggleViewAction->blockSignals(true);
376         d->m_toggleViewAction->setChecked(open);
377         //d->m_toggleViewAction->blockSignals(false);
378         if (d->m_dockArea)
379             d->m_dockArea->toggleDockWidgetView(this, open);
380 
381         if (open && topLevelDockWidgetBefore)
382             DockWidget::emitTopLevelEventForWidget(topLevelDockWidgetBefore, false);
383 
384         // Here we need to call the dockContainer() function again, because if
385         // this dock widget was unassigned before the call to showDockWidget() then
386         // it has a dock container now
387         const DockContainerWidget *const dockContainerWidget = dockContainer();
388         DockWidget *topLevelDockWidgetAfter = dockContainerWidget
389                                                   ? dockContainerWidget->topLevelDockWidget()
390                                                   : nullptr;
391         DockWidget::emitTopLevelEventForWidget(topLevelDockWidgetAfter, true);
392         FloatingDockContainer *floatingContainer = dockContainerWidget
393                                                        ? dockContainerWidget->floatingWidget()
394                                                        : nullptr;
395         if (floatingContainer)
396             floatingContainer->updateWindowTitle();
397 
398         if (!open)
399             emit closed();
400 
401         emit viewToggled(open);
402     }
403 
setDockArea(DockAreaWidget * dockArea)404     void DockWidget::setDockArea(DockAreaWidget *dockArea)
405     {
406         d->m_dockArea = dockArea;
407         d->m_toggleViewAction->setChecked(dockArea != nullptr && !this->isClosed());
408     }
409 
saveState(QXmlStreamWriter & stream) const410     void DockWidget::saveState(QXmlStreamWriter &stream) const
411     {
412         stream.writeStartElement("widget");
413         stream.writeAttribute("name", objectName());
414         stream.writeAttribute("closed", QVariant::fromValue(d->m_closed).toString());
415         stream.writeEndElement();
416     }
417 
flagAsUnassigned()418     void DockWidget::flagAsUnassigned()
419     {
420         d->m_closed = true;
421         setParent(d->m_dockManager);
422         setVisible(false);
423         setDockArea(nullptr);
424         tabWidget()->setParent(this);
425     }
426 
event(QEvent * event)427     bool DockWidget::event(QEvent *event)
428     {
429         switch (event->type()) {
430         case QEvent::Hide:
431             emit visibilityChanged(false);
432             break;
433 
434         case QEvent::Show:
435             emit visibilityChanged(geometry().right() >= 0 && geometry().bottom() >= 0);
436             break;
437 
438         case QEvent::WindowTitleChange :
439             {
440                 const auto title = windowTitle();
441                 if (d->m_tabWidget) {
442                     d->m_tabWidget->setText(title);
443                 }
444                 if (d->m_toggleViewAction) {
445                     d->m_toggleViewAction->setText(title);
446                 }
447                 if (d->m_dockArea) {
448                     d->m_dockArea->markTitleBarMenuOutdated(); // update tabs menu
449                 }
450                 emit titleChanged(title);
451             }
452             break;
453 
454         default:
455             break;
456         }
457 
458         return Super::event(event);
459     }
460 
461 #ifndef QT_NO_TOOLTIP
setTabToolTip(const QString & text)462     void DockWidget::setTabToolTip(const QString &text)
463     {
464         if (d->m_tabWidget)
465             d->m_tabWidget->setToolTip(text);
466 
467         if (d->m_toggleViewAction)
468             d->m_toggleViewAction->setToolTip(text);
469 
470         if (d->m_dockArea)
471             d->m_dockArea->markTitleBarMenuOutdated(); // update tabs menu
472     }
473 #endif
474 
setIcon(const QIcon & icon)475     void DockWidget::setIcon(const QIcon &icon)
476     {
477         d->m_tabWidget->setIcon(icon);
478         if (!d->m_toggleViewAction->isCheckable())
479             d->m_toggleViewAction->setIcon(icon);
480     }
481 
icon() const482     QIcon DockWidget::icon() const { return d->m_tabWidget->icon(); }
483 
toolBar() const484     QToolBar *DockWidget::toolBar() const { return d->m_toolBar; }
485 
createDefaultToolBar()486     QToolBar *DockWidget::createDefaultToolBar()
487     {
488         if (!d->m_toolBar)
489             d->setupToolBar();
490 
491         return d->m_toolBar;
492     }
493 
setToolBar(QToolBar * toolBar)494     void DockWidget::setToolBar(QToolBar *toolBar)
495     {
496         if (d->m_toolBar)
497             delete d->m_toolBar;
498 
499         d->m_toolBar = toolBar;
500         d->m_layout->insertWidget(0, d->m_toolBar);
501         connect(this, &DockWidget::topLevelChanged, this, &DockWidget::setToolbarFloatingStyle);
502         setToolbarFloatingStyle(isFloating());
503     }
504 
setToolBarStyle(Qt::ToolButtonStyle style,eState state)505     void DockWidget::setToolBarStyle(Qt::ToolButtonStyle style, eState state)
506     {
507         if (StateFloating == state)
508             d->m_toolBarStyleFloating = style;
509         else
510             d->m_toolBarStyleDocked = style;
511 
512         setToolbarFloatingStyle(isFloating());
513     }
514 
toolBarStyle(eState state) const515     Qt::ToolButtonStyle DockWidget::toolBarStyle(eState state) const
516     {
517         if (StateFloating == state)
518             return d->m_toolBarStyleFloating;
519         else
520             return d->m_toolBarStyleDocked;
521     }
522 
setToolBarIconSize(const QSize & iconSize,eState state)523     void DockWidget::setToolBarIconSize(const QSize &iconSize, eState state)
524     {
525         if (StateFloating == state)
526             d->m_toolBarIconSizeFloating = iconSize;
527         else
528             d->m_toolBarIconSizeDocked = iconSize;
529 
530         setToolbarFloatingStyle(isFloating());
531     }
532 
toolBarIconSize(eState state) const533     QSize DockWidget::toolBarIconSize(eState state) const
534     {
535         if (StateFloating == state)
536             return d->m_toolBarIconSizeFloating;
537         else
538             return d->m_toolBarIconSizeDocked;
539     }
540 
setToolbarFloatingStyle(bool floating)541     void DockWidget::setToolbarFloatingStyle(bool floating)
542     {
543         if (!d->m_toolBar)
544             return;
545 
546         auto iconSize = floating ? d->m_toolBarIconSizeFloating : d->m_toolBarIconSizeDocked;
547         if (iconSize != d->m_toolBar->iconSize())
548             d->m_toolBar->setIconSize(iconSize);
549 
550         auto buttonStyle = floating ? d->m_toolBarStyleFloating : d->m_toolBarStyleDocked;
551         if (buttonStyle != d->m_toolBar->toolButtonStyle())
552             d->m_toolBar->setToolButtonStyle(buttonStyle);
553     }
554 
emitTopLevelEventForWidget(DockWidget * topLevelDockWidget,bool floating)555     void DockWidget::emitTopLevelEventForWidget(DockWidget *topLevelDockWidget, bool floating)
556     {
557         if (topLevelDockWidget) {
558             topLevelDockWidget->dockAreaWidget()->updateTitleBarVisibility();
559             topLevelDockWidget->emitTopLevelChanged(floating);
560         }
561     }
562 
emitTopLevelChanged(bool floating)563     void DockWidget::emitTopLevelChanged(bool floating)
564     {
565         if (floating != d->m_isFloatingTopLevel) {
566             d->m_isFloatingTopLevel = floating;
567             emit topLevelChanged(d->m_isFloatingTopLevel);
568         }
569     }
570 
setClosedState(bool closed)571     void DockWidget::setClosedState(bool closed) { d->m_closed = closed; }
572 
minimumSizeHint() const573     QSize DockWidget::minimumSizeHint() const
574     {
575         if (d->m_minimumSizeHintMode == DockWidget::MinimumSizeHintFromDockWidget || !d->m_widget)
576             return QSize(60, 40);
577         else
578             return d->m_widget->minimumSizeHint();
579     }
580 
setFloating()581     void DockWidget::setFloating()
582     {
583         if (isClosed())
584             return;
585 
586         d->m_tabWidget->detachDockWidget();
587     }
588 
deleteDockWidget()589     void DockWidget::deleteDockWidget()
590     {
591         dockManager()->removeDockWidget(this);
592         deleteLater();
593         d->m_closed = true;
594     }
595 
closeDockWidget()596     void DockWidget::closeDockWidget()
597     {
598         closeDockWidgetInternal(true);
599     }
600 
closeDockWidgetInternal(bool forceClose)601     bool DockWidget::closeDockWidgetInternal(bool forceClose)
602     {
603         if (!forceClose)
604             emit closeRequested();
605 
606         if (!forceClose && features().testFlag(DockWidget::CustomCloseHandling))
607             return false;
608 
609         if (features().testFlag(DockWidget::DockWidgetDeleteOnClose)) {
610             // If the dock widget is floating, then we check if we also need to
611             // delete the floating widget
612             if (isFloating()) {
613                 FloatingDockContainer* floatingWidget = internal::findParent<
614                         FloatingDockContainer *>(this);
615                 if (floatingWidget->dockWidgets().count() == 1)
616                     floatingWidget->deleteLater();
617                 else
618                     floatingWidget->hide();
619             }
620             deleteDockWidget();
621             emit closed();
622         } else {
623             toggleView(false);
624         }
625 
626         return true;
627     }
628 
setTitleBarActions(QList<QAction * > actions)629     void DockWidget::setTitleBarActions(QList<QAction *> actions)
630     {
631         d->m_titleBarActions = actions;
632     }
633 
titleBarActions() const634     QList<QAction *> DockWidget::titleBarActions() const
635     {
636         return d->m_titleBarActions;
637     }
638 
showFullScreen()639     void DockWidget::showFullScreen()
640     {
641         if (isFloating())
642             dockContainer()->floatingWidget()->showFullScreen();
643         else
644             Super::showFullScreen();
645     }
646 
showNormal()647     void DockWidget::showNormal()
648     {
649         if (isFloating())
650             dockContainer()->floatingWidget()->showNormal();
651         else
652             Super::showNormal();
653     }
654 
isFullScreen() const655     bool DockWidget::isFullScreen() const
656     {
657         if (isFloating())
658             return dockContainer()->floatingWidget()->isFullScreen();
659         else
660             return Super::isFullScreen();
661     }
662 
setAsCurrentTab()663     void DockWidget::setAsCurrentTab()
664     {
665         if (d->m_dockArea && !isClosed())
666             d->m_dockArea->setCurrentDockWidget(this);
667     }
668 
isTabbed() const669     bool DockWidget::isTabbed() const
670     {
671         return d->m_dockArea && (d->m_dockArea->openDockWidgetsCount() > 1);
672     }
673 
isCurrentTab() const674     bool DockWidget::isCurrentTab() const
675     {
676         return d->m_dockArea && (d->m_dockArea->currentDockWidget() == this);
677     }
678 
raise()679     void DockWidget::raise()
680     {
681         if (isClosed())
682             return;
683 
684         setAsCurrentTab();
685         if (isInFloatingContainer())
686         {
687             auto floatingWindow = window();
688             floatingWindow->raise();
689             floatingWindow->activateWindow();
690         }
691     }
692 
693 } // namespace ADS
694