dockareawidget.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  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. #include "dockareawidget.h"
  36. #include "dockareatabbar.h"
  37. #include "dockareatitlebar.h"
  38. #include "dockcomponentsfactory.h"
  39. #include "dockcontainerwidget.h"
  40. #include "dockmanager.h"
  41. #include "dockoverlay.h"
  42. #include "docksplitter.h"
  43. #include "dockwidget.h"
  44. #include "dockwidgettab.h"
  45. #include "floatingdockcontainer.h"
  46. #include <QList>
  47. #include <QLoggingCategory>
  48. #include <QMenu>
  49. #include <QPushButton>
  50. #include <QScrollArea>
  51. #include <QScrollBar>
  52. #include <QSplitter>
  53. #include <QStackedLayout>
  54. #include <QStyle>
  55. #include <QVector>
  56. #include <QWheelEvent>
  57. #include <QXmlStreamWriter>
  58. #include <iostream>
  59. static Q_LOGGING_CATEGORY(adsLog, "qtc.qmldesigner.advanceddockingsystem", QtDebugMsg)
  60. namespace ADS
  61. {
  62. static const char *const INDEX_PROPERTY = "index";
  63. static const char *const ACTION_PROPERTY = "action";
  64. /**
  65. * Internal dock area layout mimics stack layout but only inserts the current
  66. * widget into the internal QLayout object.
  67. * \warning Only the current widget has a parent. All other widgets
  68. * do not have a parent. That means, a widget that is in this layout may
  69. * return nullptr for its parent() function if it is not the current widget.
  70. */
  71. class DockAreaLayout
  72. {
  73. private:
  74. QBoxLayout *m_parentLayout;
  75. QList<QWidget *> m_widgets;
  76. int m_currentIndex = -1;
  77. QWidget *m_currentWidget = nullptr;
  78. public:
  79. /**
  80. * Creates an instance with the given parent layout
  81. */
  82. DockAreaLayout(QBoxLayout *parentLayout)
  83. : m_parentLayout(parentLayout)
  84. {}
  85. /**
  86. * Returns the number of widgets in this layout
  87. */
  88. int count() const { return m_widgets.count(); }
  89. /**
  90. * Inserts the widget at the given index position into the internal widget
  91. * list
  92. */
  93. void insertWidget(int index, QWidget *widget)
  94. {
  95. widget->setParent(nullptr);
  96. if (index < 0) {
  97. index = m_widgets.count();
  98. }
  99. m_widgets.insert(index, widget);
  100. if (m_currentIndex < 0) {
  101. setCurrentIndex(index);
  102. } else {
  103. if (index <= m_currentIndex) {
  104. ++m_currentIndex;
  105. }
  106. }
  107. }
  108. /**
  109. * Removes the given widget from the layout
  110. */
  111. void removeWidget(QWidget *widget)
  112. {
  113. if (currentWidget() == widget) {
  114. auto layoutItem = m_parentLayout->takeAt(1);
  115. if (layoutItem) {
  116. layoutItem->widget()->setParent(nullptr);
  117. }
  118. m_currentWidget = nullptr;
  119. m_currentIndex = -1;
  120. }
  121. m_widgets.removeOne(widget);
  122. }
  123. /**
  124. * Returns the current selected widget
  125. */
  126. QWidget *currentWidget() const { return m_currentWidget; }
  127. /**
  128. * Activates the widget with the give index.
  129. */
  130. void setCurrentIndex(int index)
  131. {
  132. QWidget *prev = currentWidget();
  133. QWidget *next = widget(index);
  134. if (!next || (next == prev && !m_currentWidget)) {
  135. return;
  136. }
  137. bool reenableUpdates = false;
  138. QWidget *parent = m_parentLayout->parentWidget();
  139. if (parent && parent->updatesEnabled()) {
  140. reenableUpdates = true;
  141. parent->setUpdatesEnabled(false);
  142. }
  143. // TODO
  144. auto layoutItem = m_parentLayout->takeAt(1);
  145. if (layoutItem) {
  146. layoutItem->widget()->setParent(nullptr);
  147. }
  148. m_parentLayout->addWidget(next);
  149. if (prev) {
  150. prev->hide();
  151. }
  152. m_currentIndex = index;
  153. m_currentWidget = next;
  154. if (reenableUpdates) {
  155. parent->setUpdatesEnabled(true);
  156. }
  157. }
  158. /**
  159. * Returns the index of the current active widget
  160. */
  161. int currentIndex() const { return m_currentIndex; }
  162. /**
  163. * Returns true if there are no widgets in the layout
  164. */
  165. bool isEmpty() const { return m_widgets.empty(); }
  166. /**
  167. * Returns the index of the given widget
  168. */
  169. int indexOf(QWidget *widget) const { return m_widgets.indexOf(widget); }
  170. /**
  171. * Returns the widget for the given index
  172. */
  173. QWidget *widget(int index) const
  174. {
  175. return (index < m_widgets.size()) ? m_widgets.at(index) : nullptr;
  176. }
  177. /**
  178. * Returns the geometry of the current active widget
  179. */
  180. QRect geometry() const { return m_widgets.empty() ? QRect() : currentWidget()->geometry(); }
  181. };
  182. /**
  183. * Private data class of DockAreaWidget class (pimpl)
  184. */
  185. struct DockAreaWidgetPrivate
  186. {
  187. DockAreaWidget *q = nullptr;
  188. QBoxLayout *m_layout = nullptr;
  189. DockAreaLayout *m_contentsLayout = nullptr;
  190. DockAreaTitleBar *m_titleBar = nullptr;
  191. DockManager *m_dockManager = nullptr;
  192. bool m_updateTitleBarButtons = false;
  193. DockWidgetAreas m_allowedAreas = AllDockAreas;
  194. /**
  195. * Private data constructor
  196. */
  197. DockAreaWidgetPrivate(DockAreaWidget *parent);
  198. /**
  199. * Creates the layout for top area with tabs and close button
  200. */
  201. void createTitleBar();
  202. /**
  203. * Returns the dock widget with the given index
  204. */
  205. DockWidget *dockWidgetAt(int index)
  206. {
  207. return qobject_cast<DockWidget *>(m_contentsLayout->widget(index));
  208. }
  209. /**
  210. * Convenience function to ease title widget access by index
  211. */
  212. DockWidgetTab *tabWidgetAt(int index) { return dockWidgetAt(index)->tabWidget(); }
  213. /**
  214. * Returns the tab action of the given dock widget
  215. */
  216. QAction *dockWidgetTabAction(DockWidget *dockWidget) const
  217. {
  218. return qvariant_cast<QAction *>(dockWidget->property(ACTION_PROPERTY));
  219. }
  220. /**
  221. * Returns the index of the given dock widget
  222. */
  223. int dockWidgetIndex(DockWidget *dockWidget) const
  224. {
  225. return dockWidget->property(INDEX_PROPERTY).toInt();
  226. }
  227. /**
  228. * Convenience function for tabbar access
  229. */
  230. DockAreaTabBar *tabBar() const { return m_titleBar->tabBar(); }
  231. /**
  232. * Udpates the enable state of the close and detach button
  233. */
  234. void updateTitleBarButtonStates();
  235. };
  236. // struct DockAreaWidgetPrivate
  237. DockAreaWidgetPrivate::DockAreaWidgetPrivate(DockAreaWidget *parent)
  238. : q(parent)
  239. {}
  240. void DockAreaWidgetPrivate::createTitleBar()
  241. {
  242. m_titleBar = componentsFactory()->createDockAreaTitleBar(q);
  243. m_layout->addWidget(m_titleBar);
  244. QObject::connect(tabBar(),
  245. &DockAreaTabBar::tabCloseRequested,
  246. q,
  247. &DockAreaWidget::onTabCloseRequested);
  248. QObject::connect(m_titleBar,
  249. &DockAreaTitleBar::tabBarClicked,
  250. q,
  251. &DockAreaWidget::setCurrentIndex);
  252. QObject::connect(tabBar(), &DockAreaTabBar::tabMoved, q, &DockAreaWidget::reorderDockWidget);
  253. }
  254. void DockAreaWidgetPrivate::updateTitleBarButtonStates()
  255. {
  256. if (q->isHidden()) {
  257. m_updateTitleBarButtons = true;
  258. return;
  259. }
  260. m_titleBar->button(TitleBarButtonClose)
  261. ->setEnabled(q->features().testFlag(DockWidget::DockWidgetClosable));
  262. m_titleBar->button(TitleBarButtonUndock)
  263. ->setEnabled(q->features().testFlag(DockWidget::DockWidgetFloatable));
  264. m_titleBar->updateDockWidgetActionsButtons();
  265. m_updateTitleBarButtons = false;
  266. }
  267. DockAreaWidget::DockAreaWidget(DockManager *dockManager, DockContainerWidget *parent)
  268. : QFrame(parent)
  269. , d(new DockAreaWidgetPrivate(this))
  270. {
  271. d->m_dockManager = dockManager;
  272. d->m_layout = new QBoxLayout(QBoxLayout::TopToBottom);
  273. d->m_layout->setContentsMargins(0, 0, 0, 0);
  274. d->m_layout->setSpacing(0);
  275. setLayout(d->m_layout);
  276. d->createTitleBar();
  277. d->m_contentsLayout = new DockAreaLayout(d->m_layout);
  278. if (d->m_dockManager) {
  279. emit d->m_dockManager->dockAreaCreated(this);
  280. }
  281. }
  282. DockAreaWidget::~DockAreaWidget()
  283. {
  284. qCInfo(adsLog) << Q_FUNC_INFO;
  285. delete d->m_contentsLayout;
  286. delete d;
  287. }
  288. DockManager *DockAreaWidget::dockManager() const { return d->m_dockManager; }
  289. DockContainerWidget *DockAreaWidget::dockContainer() const
  290. {
  291. return internal::findParent<DockContainerWidget *>(this);
  292. }
  293. void DockAreaWidget::addDockWidget(DockWidget *dockWidget)
  294. {
  295. insertDockWidget(d->m_contentsLayout->count(), dockWidget);
  296. }
  297. void DockAreaWidget::insertDockWidget(int index, DockWidget *dockWidget, bool activate)
  298. {
  299. d->m_contentsLayout->insertWidget(index, dockWidget);
  300. dockWidget->tabWidget()->setDockAreaWidget(this);
  301. auto tabWidget = dockWidget->tabWidget();
  302. // Inserting the tab will change the current index which in turn will
  303. // make the tab widget visible in the slot
  304. d->tabBar()->blockSignals(true);
  305. d->tabBar()->insertTab(index, tabWidget);
  306. d->tabBar()->blockSignals(false);
  307. tabWidget->setVisible(!dockWidget->isClosed());
  308. dockWidget->setProperty(INDEX_PROPERTY, index);
  309. if (activate) {
  310. setCurrentIndex(index);
  311. }
  312. dockWidget->setDockArea(this);
  313. d->updateTitleBarButtonStates();
  314. }
  315. void DockAreaWidget::removeDockWidget(DockWidget *dockWidget)
  316. {
  317. qCInfo(adsLog) << Q_FUNC_INFO;
  318. auto nextOpen = nextOpenDockWidget(dockWidget);
  319. d->m_contentsLayout->removeWidget(dockWidget);
  320. auto tabWidget = dockWidget->tabWidget();
  321. tabWidget->hide();
  322. d->tabBar()->removeTab(tabWidget);
  323. DockContainerWidget *dockContainerWidget = dockContainer();
  324. if (nextOpen) {
  325. setCurrentDockWidget(nextOpen);
  326. } else if (d->m_contentsLayout->isEmpty() && dockContainerWidget->dockAreaCount() > 1) {
  327. qCInfo(adsLog) << "Dock Area empty";
  328. dockContainerWidget->removeDockArea(this);
  329. this->deleteLater();
  330. } else {
  331. // if contents layout is not empty but there are no more open dock
  332. // widgets, then we need to hide the dock area because it does not
  333. // contain any visible content
  334. hideAreaWithNoVisibleContent();
  335. }
  336. d->updateTitleBarButtonStates();
  337. updateTitleBarVisibility();
  338. auto topLevelDockWidget = dockContainerWidget->topLevelDockWidget();
  339. if (topLevelDockWidget) {
  340. topLevelDockWidget->emitTopLevelChanged(true);
  341. }
  342. #if (ADS_DEBUG_LEVEL > 0)
  343. dockContainerWidget->dumpLayout();
  344. #endif
  345. }
  346. void DockAreaWidget::hideAreaWithNoVisibleContent()
  347. {
  348. this->toggleView(false);
  349. // Hide empty parent splitters
  350. auto splitter = internal::findParent<DockSplitter *>(this);
  351. internal::hideEmptyParentSplitters(splitter);
  352. //Hide empty floating widget
  353. DockContainerWidget *container = this->dockContainer();
  354. if (!container->isFloating()) {
  355. return;
  356. }
  357. updateTitleBarVisibility();
  358. auto topLevelWidget = container->topLevelDockWidget();
  359. auto floatingWidget = container->floatingWidget();
  360. if (topLevelWidget) {
  361. floatingWidget->updateWindowTitle();
  362. DockWidget::emitTopLevelEventForWidget(topLevelWidget, true);
  363. } else if (container->openedDockAreas().isEmpty()) {
  364. floatingWidget->hide();
  365. }
  366. }
  367. void DockAreaWidget::onTabCloseRequested(int index)
  368. {
  369. qCInfo(adsLog) << Q_FUNC_INFO << "index" << index;
  370. auto *currentDockWidget = dockWidget(index);
  371. if (currentDockWidget->features().testFlag(DockWidget::DockWidgetDeleteOnClose)) {
  372. currentDockWidget->closeDockWidgetInternal();
  373. } else {
  374. currentDockWidget->toggleView(false);
  375. }
  376. }
  377. DockWidget *DockAreaWidget::currentDockWidget() const
  378. {
  379. int currentIdx = currentIndex();
  380. if (currentIdx < 0) {
  381. return nullptr;
  382. }
  383. return dockWidget(currentIdx);
  384. }
  385. void DockAreaWidget::setCurrentDockWidget(DockWidget *dockWidget)
  386. {
  387. if (dockManager()->isRestoringState()) {
  388. return;
  389. }
  390. internalSetCurrentDockWidget(dockWidget);
  391. }
  392. void DockAreaWidget::internalSetCurrentDockWidget(DockWidget *dockWidget)
  393. {
  394. int index = indexOf(dockWidget);
  395. if (index < 0) {
  396. return;
  397. }
  398. setCurrentIndex(index);
  399. }
  400. void DockAreaWidget::setCurrentIndex(int index)
  401. {
  402. auto currentTabBar = d->tabBar();
  403. if (index < 0 || index > (currentTabBar->count() - 1)) {
  404. qWarning() << Q_FUNC_INFO << "Invalid index" << index;
  405. return;
  406. }
  407. auto cw = d->m_contentsLayout->currentWidget();
  408. auto nw = d->m_contentsLayout->widget(index);
  409. if (cw == nw && !nw->isHidden()) {
  410. return;
  411. }
  412. emit currentChanging(index);
  413. currentTabBar->setCurrentIndex(index);
  414. d->m_contentsLayout->setCurrentIndex(index);
  415. d->m_contentsLayout->currentWidget()->show();
  416. emit currentChanged(index);
  417. }
  418. int DockAreaWidget::currentIndex() const { return d->m_contentsLayout->currentIndex(); }
  419. QRect DockAreaWidget::titleBarGeometry() const { return d->m_titleBar->geometry(); }
  420. QRect DockAreaWidget::contentAreaGeometry() const { return d->m_contentsLayout->geometry(); }
  421. int DockAreaWidget::indexOf(DockWidget *dockWidget)
  422. {
  423. return d->m_contentsLayout->indexOf(dockWidget);
  424. }
  425. QList<DockWidget *> DockAreaWidget::dockWidgets() const
  426. {
  427. QList<DockWidget *> dockWidgetList;
  428. for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
  429. dockWidgetList.append(dockWidget(i));
  430. }
  431. return dockWidgetList;
  432. }
  433. int DockAreaWidget::openDockWidgetsCount() const
  434. {
  435. int count = 0;
  436. for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
  437. if (!dockWidget(i)->isClosed()) {
  438. ++count;
  439. }
  440. }
  441. return count;
  442. }
  443. QList<DockWidget *> DockAreaWidget::openedDockWidgets() const
  444. {
  445. QList<DockWidget *> dockWidgetList;
  446. for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
  447. DockWidget *currentDockWidget = dockWidget(i);
  448. if (!currentDockWidget->isClosed()) {
  449. dockWidgetList.append(dockWidget(i));
  450. }
  451. }
  452. return dockWidgetList;
  453. }
  454. int DockAreaWidget::indexOfFirstOpenDockWidget() const
  455. {
  456. for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
  457. if (!dockWidget(i)->isClosed()) {
  458. return i;
  459. }
  460. }
  461. return -1;
  462. }
  463. int DockAreaWidget::dockWidgetsCount() const { return d->m_contentsLayout->count(); }
  464. DockWidget *DockAreaWidget::dockWidget(int index) const
  465. {
  466. return qobject_cast<DockWidget *>(d->m_contentsLayout->widget(index));
  467. }
  468. void DockAreaWidget::reorderDockWidget(int fromIndex, int toIndex)
  469. {
  470. qCInfo(adsLog) << Q_FUNC_INFO;
  471. if (fromIndex >= d->m_contentsLayout->count() || fromIndex < 0
  472. || toIndex >= d->m_contentsLayout->count() || toIndex < 0 || fromIndex == toIndex) {
  473. qCInfo(adsLog) << "Invalid index for tab movement" << fromIndex << toIndex;
  474. return;
  475. }
  476. auto widget = d->m_contentsLayout->widget(fromIndex);
  477. d->m_contentsLayout->removeWidget(widget);
  478. d->m_contentsLayout->insertWidget(toIndex, widget);
  479. setCurrentIndex(toIndex);
  480. }
  481. void DockAreaWidget::toggleDockWidgetView(DockWidget *dockWidget, bool open)
  482. {
  483. Q_UNUSED(dockWidget)
  484. Q_UNUSED(open)
  485. updateTitleBarVisibility();
  486. }
  487. void DockAreaWidget::updateTitleBarVisibility()
  488. {
  489. DockContainerWidget *container = dockContainer();
  490. if (!container) {
  491. return;
  492. }
  493. if (DockManager::configFlags().testFlag(DockManager::AlwaysShowTabs)) {
  494. return;
  495. }
  496. if (d->m_titleBar) {
  497. d->m_titleBar->setVisible(!container->isFloating() || !container->hasTopLevelDockWidget());
  498. }
  499. }
  500. void DockAreaWidget::markTitleBarMenuOutdated()
  501. {
  502. if (d->m_titleBar) {
  503. d->m_titleBar->markTabsMenuOutdated();
  504. }
  505. }
  506. void DockAreaWidget::saveState(QXmlStreamWriter &stream) const
  507. {
  508. stream.writeStartElement("area");
  509. stream.writeAttribute("tabs", QString::number(d->m_contentsLayout->count()));
  510. auto localDockWidget = currentDockWidget();
  511. QString name = localDockWidget ? localDockWidget->objectName() : "";
  512. stream.writeAttribute("current", name);
  513. qCInfo(adsLog) << Q_FUNC_INFO << "TabCount: " << d->m_contentsLayout->count()
  514. << " Current: " << name;
  515. for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
  516. dockWidget(i)->saveState(stream);
  517. }
  518. stream.writeEndElement();
  519. }
  520. DockWidget *DockAreaWidget::nextOpenDockWidget(DockWidget *dockWidget) const
  521. {
  522. auto openDockWidgets = openedDockWidgets();
  523. if (openDockWidgets.count() > 1
  524. || (openDockWidgets.count() == 1 && openDockWidgets[0] != dockWidget)) {
  525. DockWidget *nextDockWidget;
  526. if (openDockWidgets.last() == dockWidget) {
  527. nextDockWidget = openDockWidgets[openDockWidgets.count() - 2];
  528. } else {
  529. int nextIndex = openDockWidgets.indexOf(dockWidget) + 1;
  530. nextDockWidget = openDockWidgets[nextIndex];
  531. }
  532. return nextDockWidget;
  533. } else {
  534. return nullptr;
  535. }
  536. }
  537. DockWidget::DockWidgetFeatures DockAreaWidget::features(eBitwiseOperator mode) const
  538. {
  539. if (BitwiseAnd == mode) {
  540. DockWidget::DockWidgetFeatures features(DockWidget::AllDockWidgetFeatures);
  541. for (const auto dockWidget : dockWidgets()) {
  542. features &= dockWidget->features();
  543. }
  544. return features;
  545. } else {
  546. DockWidget::DockWidgetFeatures features(DockWidget::NoDockWidgetFeatures);
  547. for (const auto dockWidget : dockWidgets()) {
  548. features |= dockWidget->features();
  549. }
  550. return features;
  551. }
  552. }
  553. void DockAreaWidget::toggleView(bool open)
  554. {
  555. setVisible(open);
  556. emit viewToggled(open);
  557. }
  558. void DockAreaWidget::setVisible(bool visible)
  559. {
  560. Super::setVisible(visible);
  561. if (d->m_updateTitleBarButtons) {
  562. d->updateTitleBarButtonStates();
  563. }
  564. }
  565. void DockAreaWidget::setAllowedAreas(DockWidgetAreas areas)
  566. {
  567. d->m_allowedAreas = areas;
  568. }
  569. DockWidgetAreas DockAreaWidget::allowedAreas() const
  570. {
  571. return d->m_allowedAreas;
  572. }
  573. QAbstractButton *DockAreaWidget::titleBarButton(eTitleBarButton which) const
  574. {
  575. return d->m_titleBar->button(which);
  576. }
  577. void DockAreaWidget::closeArea()
  578. {
  579. // If there is only one single dock widget and this widget has the
  580. // DeleteOnClose feature, then we delete the dock widget now
  581. auto openDockWidgets = openedDockWidgets();
  582. if (openDockWidgets.count() == 1
  583. && openDockWidgets[0]->features().testFlag(DockWidget::DockWidgetDeleteOnClose)) {
  584. openDockWidgets[0]->closeDockWidgetInternal();
  585. } else {
  586. for (auto dockWidget : openedDockWidgets()) {
  587. dockWidget->toggleView(false);
  588. }
  589. }
  590. }
  591. void DockAreaWidget::closeOtherAreas() { dockContainer()->closeOtherAreas(this); }
  592. DockAreaTitleBar *DockAreaWidget::titleBar() const { return d->m_titleBar; }
  593. } // namespace ADS