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