Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "dockwindow.h"
24 :
25 : #include "kddockwidgets/src/LayoutSaver.h"
26 : #include "kddockwidgets/src/core/DockRegistry.h"
27 : #include "kddockwidgets/src/core/Layout.h"
28 : #include "kddockwidgets/src/core/MainWindow.h"
29 : #include "kddockwidgets/src/qtquick/views/MainWindow.h"
30 : #include "kddockwidgets/src/qtquick/views/DockWidget.h"
31 : #include "kddockwidgets/src/qtquick/views/View.h"
32 : #include "kddockwidgets/src/core/Group.h"
33 : #include "kddockwidgets/src/core/Window_p.h"
34 :
35 : #include "global/async/async.h"
36 :
37 : #include "dockcentralview.h"
38 : #include "dockpageview.h"
39 : #include "dockpanelview.h"
40 : #include "dockstatusbar.h"
41 : #include "docktoolbarview.h"
42 : #include "dockingholderview.h"
43 : #include "dockwindow.h"
44 : #include "topleveltoolbarslayout.h"
45 :
46 : #include "muse_framework_config.h"
47 :
48 : #include "log.h"
49 :
50 : using namespace muse::dock;
51 : using namespace muse::async;
52 :
53 : namespace muse::dock {
54 : static const QList<Location> POSSIBLE_LOCATIONS {
55 : Location::Left,
56 : Location::Right,
57 : Location::Top,
58 : Location::Bottom
59 : };
60 :
61 12 : static KDDockWidgets::Location locationToKLocation(Location location)
62 : {
63 12 : switch (location) {
64 6 : case Location::Left: return KDDockWidgets::Location_OnLeft;
65 3 : case Location::Right: return KDDockWidgets::Location_OnRight;
66 3 : case Location::Top: return KDDockWidgets::Location_OnTop;
67 0 : case Location::Bottom: return KDDockWidgets::Location_OnBottom;
68 0 : case Location::Center: break;
69 0 : case Location::Undefined: break;
70 : }
71 :
72 0 : return KDDockWidgets::Location_None;
73 : }
74 :
75 0 : static void clearRegistry(int ctx)
76 : {
77 0 : TRACEFUNC;
78 :
79 0 : auto* registry = KDDockWidgets::DockRegistry::self(ctx);
80 :
81 0 : for (KDDockWidgets::Core::MainWindow* mw : registry->mainwindows()) {
82 0 : mw->layout()->clearLayout();
83 0 : }
84 :
85 0 : registry->clear();
86 :
87 0 : for (KDDockWidgets::Core::DockWidget* dock : registry->dockwidgets()) {
88 0 : registry->unregisterDockWidget(dock);
89 0 : }
90 :
91 0 : for (KDDockWidgets::Core::Group* group : registry->groups()) {
92 0 : const auto dockWidgets = group->dockWidgets();
93 0 : for (KDDockWidgets::Core::DockWidget* dock : dockWidgets) {
94 0 : group->removeWidget(dock);
95 : }
96 0 : registry->unregisterGroup(group);
97 0 : }
98 0 : }
99 : }
100 :
101 3 : DockWindow::DockWindow(QQuickItem* parent)
102 3 : : QQuickItem(parent), muse::Contextable(muse::iocCtxForQmlObject(this)),
103 3 : m_toolBars(this),
104 9 : m_pages(this)
105 : {
106 6 : }
107 :
108 6 : DockWindow::~DockWindow()
109 : {
110 3 : dockWindowProvider()->deinit();
111 6 : }
112 :
113 3 : void DockWindow::componentComplete()
114 : {
115 4 : TRACEFUNC;
116 :
117 3 : QQuickItem::componentComplete();
118 :
119 3 : static const QString name = "mainWindow";
120 :
121 3 : m_mainWindow = new KDDockWidgets::QtQuick::MainWindow(iocContext()->id, name,
122 : KDDockWidgets::MainWindowOption_None,
123 6 : this);
124 :
125 3 : m_topLevelToolBarsLayout = new TopLevelToolBarsLayout(m_mainWindow, this);
126 :
127 3 : connect(qApp, &QCoreApplication::aboutToQuit, this, &DockWindow::onQuit);
128 3 : connect(this, &QQuickItem::windowChanged, this, &DockWindow::windowPropertyChanged);
129 3 : }
130 :
131 5 : void DockWindow::geometryChange(const QRectF& newGeometry, const QRectF& oldGeometry)
132 : {
133 5 : QQuickItem::geometryChange(newGeometry, oldGeometry);
134 :
135 5 : if (m_currentPage && !qFuzzyCompare(newGeometry.width(), oldGeometry.width())) {
136 2 : polish();
137 : }
138 5 : }
139 :
140 3 : void DockWindow::updatePolish()
141 : {
142 3 : QQuickItem::updatePolish();
143 :
144 3 : if (m_topLevelToolBarsLayout) {
145 3 : m_topLevelToolBarsLayout->relayout();
146 : }
147 3 : }
148 :
149 0 : void DockWindow::onQuit()
150 : {
151 0 : TRACEFUNC;
152 :
153 0 : IF_ASSERT_FAILED(m_currentPage) {
154 0 : return;
155 : }
156 :
157 0 : savePageState(m_currentPage->objectName());
158 0 : m_reloadCurrentPageAllowed = false;
159 :
160 0 : clearRegistry(iocContext()->id);
161 :
162 0 : saveWindowGeometry();
163 0 : }
164 :
165 3 : QString DockWindow::currentPageUri() const
166 : {
167 3 : return m_currentPage ? m_currentPage->uri() : QString();
168 : }
169 :
170 3 : QQmlListProperty<muse::dock::DockToolBarView> DockWindow::toolBarsProperty()
171 : {
172 3 : return m_toolBars.property();
173 : }
174 :
175 3 : QQmlListProperty<muse::dock::DockPageView> DockWindow::pagesProperty()
176 : {
177 3 : return m_pages.property();
178 : }
179 :
180 0 : QQuickWindow* DockWindow::windowProperty() const
181 : {
182 0 : return window();
183 : }
184 :
185 0 : void DockWindow::init()
186 : {
187 0 : clearRegistry(iocContext()->id);
188 0 : restoreGeometry();
189 :
190 0 : dockWindowProvider()->init(this);
191 :
192 0 : uiState()->windowGeometryChanged().onNotify(this, [this]() {
193 0 : reloadCurrentPage();
194 0 : });
195 :
196 0 : workspaceManager()->currentWorkspaceAboutToBeChanged().onNotify(this, [this]() {
197 0 : if (const DockPageView* page = currentPage()) {
198 0 : savePageState(page->objectName());
199 : }
200 0 : });
201 0 : }
202 :
203 3 : void DockWindow::loadPage(const QString& uri, const QVariantMap& params)
204 : {
205 4 : TRACEFUNC;
206 :
207 3 : if (currentPageUri() == uri) {
208 0 : if (m_currentPage) {
209 0 : m_currentPage->setParams(params);
210 : }
211 0 : return;
212 : }
213 :
214 3 : const bool isFirstOpening = (m_currentPage == nullptr);
215 :
216 3 : if (!isFirstOpening) {
217 0 : const QString pageName = m_currentPage->objectName();
218 0 : uiState()->pageState(pageName).notification.disconnect(this);
219 0 : savePageState(pageName);
220 0 : clearRegistry(iocContext()->id);
221 0 : m_currentPage->setVisible(false);
222 0 : m_currentPage->deinit();
223 0 : }
224 :
225 3 : bool ok = doLoadPage(uri, params);
226 3 : if (!ok) {
227 0 : return;
228 : }
229 :
230 3 : if (checkLayoutIsCorrupted()) {
231 0 : LOGE() << "Layout is corrupted, restoring default";
232 0 : restoreDefaultLayout();
233 : }
234 :
235 3 : auto notifyAboutPageLoaded = [this, &uri]() {
236 3 : emit currentPageUriChanged(uri);
237 3 : emit pageLoaded();
238 3 : notifyAboutDocksOpenStatus();
239 6 : };
240 :
241 3 : if (isFirstOpening) {
242 3 : async::Async::call(this, [this, notifyAboutPageLoaded]() {
243 3 : if (!m_hasGeometryBeenRestored
244 3 : || (m_mainWindow->window()->isFullScreen())) {
245 : //! NOTE: show window as maximized if no geometry has been restored
246 : //! or if the user had closed app in FullScreen mode
247 : // m_mainWindow->window()->->showMaximized(); // todo kddock
248 : }
249 :
250 3 : notifyAboutPageLoaded();
251 3 : });
252 : } else {
253 0 : notifyAboutPageLoaded();
254 : }
255 3 : }
256 :
257 0 : void DockWindow::openPage(const QString& uri)
258 : {
259 0 : interactive()->open(uri.toStdString());
260 0 : }
261 :
262 0 : bool DockWindow::isDockOpen(const QString& dockName) const
263 : {
264 0 : return m_currentPage && m_currentPage->isDockOpen(dockName);
265 : }
266 :
267 0 : void DockWindow::toggleDock(const QString& dockName)
268 : {
269 0 : if (m_currentPage) {
270 0 : m_currentPage->toggleDock(dockName);
271 0 : m_docksOpenStatusChanged.send({ dockName });
272 : }
273 0 : }
274 :
275 0 : void DockWindow::setDockOpen(const QString& dockName, bool open)
276 : {
277 0 : if (m_currentPage) {
278 0 : m_currentPage->setDockOpen(dockName, open);
279 0 : m_docksOpenStatusChanged.send({ dockName });
280 : }
281 0 : }
282 :
283 0 : Channel<QStringList> DockWindow::docksOpenStatusChanged() const
284 : {
285 0 : return m_docksOpenStatusChanged;
286 : }
287 :
288 0 : bool DockWindow::isDockFloating(const QString& dockName) const
289 : {
290 0 : return m_currentPage && m_currentPage->isDockFloating(dockName);
291 : }
292 :
293 0 : void DockWindow::toggleDockFloating(const QString& dockName)
294 : {
295 0 : if (m_currentPage) {
296 0 : m_currentPage->toggleDockFloating(dockName);
297 : }
298 0 : }
299 :
300 6 : DockPageView* DockWindow::currentPage() const
301 : {
302 6 : return m_currentPage;
303 : }
304 :
305 0 : QQuickItem& DockWindow::asItem() const
306 : {
307 0 : return *m_mainWindow;
308 : }
309 :
310 0 : void DockWindow::restoreDefaultLayout()
311 : {
312 0 : TRACEFUNC;
313 :
314 : //! HACK: notify about upcoming change of current URI
315 : //! so that all subscribers of this channel finish their work.
316 : //! For example, our popups and tooltips will close.
317 0 : interactive()->currentUriAboutToBeChanged().notify();
318 :
319 0 : if (m_currentPage) {
320 0 : for (DockBase* dock : m_currentPage->allDocks()) {
321 0 : dock->resetToDefault();
322 0 : }
323 : }
324 :
325 0 : m_reloadCurrentPageAllowed = false;
326 0 : for (const DockPageView* page : m_pages.list()) {
327 0 : uiState()->setPageState(page->objectName(), QByteArray());
328 0 : }
329 :
330 0 : uiState()->setWindowGeometry(QByteArray());
331 0 : m_reloadCurrentPageAllowed = true;
332 :
333 0 : reloadCurrentPage();
334 0 : }
335 :
336 3 : void DockWindow::loadPageContent(const DockPageView* page)
337 : {
338 4 : TRACEFUNC;
339 :
340 3 : addDock(page->centralDock());
341 :
342 3 : loadPanels(page);
343 3 : loadToolBars(page);
344 :
345 3 : if (page->statusBar()) {
346 0 : addDock(page->statusBar(), Location::Bottom);
347 : }
348 :
349 3 : loadTopLevelToolBars(page);
350 3 : }
351 :
352 3 : void DockWindow::loadTopLevelToolBars(const DockPageView* page)
353 : {
354 4 : TRACEFUNC;
355 :
356 3 : QList<DockToolBarView*> allToolBars = m_toolBars.list();
357 3 : allToolBars << page->mainToolBars();
358 :
359 3 : DockToolBarView* prevToolBar = nullptr;
360 :
361 9 : for (DockToolBarView* toolBar : allToolBars) {
362 6 : auto location = prevToolBar ? Location::Right : Location::Top;
363 6 : addDock(toolBar, location, prevToolBar);
364 6 : prevToolBar = toolBar;
365 : }
366 3 : }
367 :
368 3 : void DockWindow::loadToolBars(const DockPageView* page)
369 : {
370 4 : TRACEFUNC;
371 :
372 3 : for (DockToolBarView* toolBar : page->toolBars()) {
373 0 : addDock(toolBar, toolBar->location());
374 3 : }
375 :
376 15 : for (Location location : POSSIBLE_LOCATIONS) {
377 12 : if (auto holder = page->holder(DockType::ToolBar, location)) {
378 0 : addDock(holder, location);
379 : }
380 : }
381 3 : }
382 :
383 3 : void DockWindow::loadPanels(const DockPageView* page)
384 : {
385 4 : TRACEFUNC;
386 :
387 6 : for (DockPanelView* panel : page->panels()) {
388 3 : if (DockPanelView* destinationPanel = page->findPanelForTab(panel)) {
389 0 : addPanelAsTab(panel, destinationPanel);
390 0 : continue;
391 : }
392 :
393 3 : const Location location = panel->location();
394 3 : const bool isSideLocation = location == Location::Left || location == Location::Right;
395 3 : addDock(panel, location, isSideLocation ? page->centralDock() : nullptr);
396 3 : }
397 :
398 15 : for (Location location : POSSIBLE_LOCATIONS) {
399 12 : if (auto holder = page->holder(DockType::Panel, location)) {
400 0 : addDock(holder, location);
401 : }
402 : }
403 3 : }
404 :
405 12 : void DockWindow::addDock(DockBase* dock, Location location, const DockBase* relativeTo)
406 : {
407 13 : TRACEFUNC;
408 :
409 12 : registerDock(dock);
410 :
411 24 : auto* dockWidgetView = qobject_cast<KDDockWidgets::QtQuick::DockWidget*>(
412 12 : KDDockWidgets::QtQuick::asQQuickItem(dock->dockWidget()));
413 :
414 12 : KDDockWidgets::QtQuick::DockWidget* relativeDockWidgetView = nullptr;
415 12 : if (relativeTo) {
416 6 : relativeDockWidgetView = qobject_cast<KDDockWidgets::QtQuick::DockWidget*>(
417 6 : KDDockWidgets::QtQuick::asQQuickItem(relativeTo->dockWidget()));
418 : }
419 :
420 12 : auto visibilityOption = dock->defaultVisibility() ? KDDockWidgets::InitialVisibilityOption::StartVisible
421 12 : : KDDockWidgets::InitialVisibilityOption::StartHidden;
422 :
423 12 : KDDockWidgets::InitialOption options(visibilityOption, dock->preferredSize());
424 :
425 12 : m_mainWindow->addDockWidget(dockWidgetView, locationToKLocation(location), relativeDockWidgetView, options);
426 12 : }
427 :
428 0 : void DockWindow::addPanelAsTab(DockPanelView* panel, DockPanelView* destinationPanel)
429 : {
430 0 : registerDock(panel);
431 :
432 0 : if (panel->defaultVisibility()) {
433 0 : destinationPanel->addPanelAsTab(panel);
434 0 : destinationPanel->setCurrentTabIndex(0);
435 : }
436 0 : }
437 :
438 12 : void DockWindow::registerDock(DockBase* dock)
439 : {
440 13 : TRACEFUNC;
441 :
442 12 : IF_ASSERT_FAILED(dock) {
443 0 : return;
444 : }
445 :
446 12 : auto* registry = KDDockWidgets::DockRegistry::self(iocContext()->id);
447 12 : auto* dockWidget = dock->dockWidget();
448 :
449 12 : if (!registry->containsDockWidget(dockWidget->uniqueName())) {
450 0 : registry->registerDockWidget(dockWidget);
451 : }
452 12 : }
453 :
454 0 : void DockWindow::handleUnknownDock(const DockPageView* page, DockBase* unknownDock)
455 : {
456 0 : DockPanelView* unknownPanel = dynamic_cast<DockPanelView*>(unknownDock);
457 0 : if (!unknownPanel) {
458 0 : addDock(unknownDock, unknownDock->location(), page->centralDock());
459 0 : return;
460 : }
461 :
462 0 : if (DockPanelView* destinationPanel = page->findPanelForTab(unknownPanel)) {
463 0 : addPanelAsTab(unknownPanel, destinationPanel);
464 0 : return;
465 : }
466 :
467 0 : DockingHolderView* holder = page->holder(DockType::Panel, unknownPanel->location());
468 0 : IF_ASSERT_FAILED(holder) {
469 0 : addDock(unknownDock, unknownDock->location(), page->centralDock());
470 0 : return;
471 : }
472 :
473 0 : registerDock(unknownPanel);
474 :
475 0 : holder->open(); // init the group...
476 :
477 0 : auto* holderDockWidgetView = qobject_cast<KDDockWidgets::QtQuick::DockWidget*>(
478 0 : KDDockWidgets::QtQuick::asQQuickItem(holder->dockWidget()));
479 0 : if (holderDockWidgetView) {
480 0 : KDDockWidgets::Core::Group* group = holderDockWidgetView->group();
481 0 : if (group) {
482 0 : group->addTab(unknownPanel->dockWidget());
483 : }
484 : }
485 :
486 0 : holder->close();
487 :
488 0 : if (!unknownPanel->isVisible()) {
489 0 : unknownPanel->close();
490 : }
491 : }
492 :
493 3 : DockPageView* DockWindow::pageByUri(const QString& uri) const
494 : {
495 3 : for (DockPageView* page : m_pages.list()) {
496 3 : if (page->uri() == uri) {
497 3 : return page;
498 : }
499 3 : }
500 :
501 0 : return nullptr;
502 : }
503 :
504 3 : bool DockWindow::doLoadPage(const QString& uri, const QVariantMap& params)
505 : {
506 3 : DockPageView* newPage = pageByUri(uri);
507 3 : IF_ASSERT_FAILED(newPage) {
508 0 : return false;
509 : }
510 :
511 3 : newPage->setVisible(true);
512 :
513 3 : loadPageContent(newPage);
514 3 : restorePageState(newPage);
515 3 : initDocks(newPage);
516 :
517 3 : newPage->setParams(params);
518 :
519 3 : m_currentPage = newPage;
520 :
521 3 : connect(m_currentPage, &DockPageView::layoutRequested,
522 3 : this, &DockWindow::forceLayout, Qt::UniqueConnection);
523 :
524 3 : return true;
525 : }
526 :
527 0 : void DockWindow::saveWindowGeometry()
528 : {
529 : /// NOTE: The state of all dock widgets is also saved here,
530 : /// since the library does not provide the ability to save
531 : /// and restore only the application geometry.
532 0 : uiState()->setWindowGeometry(windowState());
533 0 : }
534 :
535 0 : void DockWindow::restoreGeometry()
536 : {
537 0 : TRACEFUNC;
538 :
539 0 : if (uiState()->windowGeometry().isEmpty()) {
540 0 : return;
541 : }
542 :
543 0 : if (restoreLayout(uiState()->windowGeometry())) {
544 0 : m_hasGeometryBeenRestored = true;
545 : } else {
546 0 : LOGE() << "Could not restore the window geometry!";
547 : }
548 0 : }
549 :
550 0 : void DockWindow::savePageState(const QString& pageName)
551 : {
552 0 : TRACEFUNC;
553 :
554 0 : m_reloadCurrentPageAllowed = false;
555 0 : uiState()->setPageState(pageName, windowState());
556 0 : m_reloadCurrentPageAllowed = true;
557 0 : }
558 :
559 3 : void DockWindow::restorePageState(const DockPageView* page)
560 : {
561 4 : TRACEFUNC;
562 :
563 3 : const QString& pageName = page->objectName();
564 :
565 3 : ValNt<QByteArray> pageStateValNt = uiState()->pageState(pageName);
566 3 : const bool layoutIsEmpty = pageStateValNt.val.isEmpty();
567 :
568 3 : QSet<DockBase*> unknownDocks;
569 3 : if (!layoutIsEmpty) {
570 0 : for (DockBase* dock : page->allDocks()) {
571 0 : const KDDockWidgets::Core::DockWidget* dockWidget = dock->dockWidget();
572 0 : if (!pageStateValNt.val.contains(dockWidget->uniqueName().toLocal8Bit())) {
573 0 : unknownDocks.insert(dock);
574 : }
575 0 : }
576 : }
577 :
578 : /// NOTE: Do not restore geometry
579 3 : bool ok = restoreLayout(pageStateValNt.val, true /*restoreRelativeToMainWindow*/);
580 3 : if (!ok) {
581 0 : LOGE() << "Could not restore the state of " << pageName << "!";
582 : }
583 :
584 3 : if (!layoutIsEmpty) {
585 0 : for (DockBase* dock : unknownDocks) {
586 0 : handleUnknownDock(page, dock);
587 : }
588 : }
589 :
590 3 : if (!pageStateValNt.notification.isConnected()) {
591 3 : pageStateValNt.notification.onNotify(this, [this, pageName]() {
592 0 : bool isCurrentPage = m_currentPage && (m_currentPage->objectName() == pageName);
593 0 : if (isCurrentPage) {
594 0 : reloadCurrentPage();
595 : }
596 0 : });
597 : }
598 3 : }
599 :
600 3 : bool DockWindow::restoreLayout(const QByteArray& layout, bool restoreRelativeToMainWindow)
601 : {
602 3 : if (layout.isEmpty()) {
603 3 : return true;
604 : }
605 :
606 0 : TRACEFUNC;
607 :
608 0 : auto option = restoreRelativeToMainWindow ? KDDockWidgets::RestoreOption_RelativeToMainWindow
609 : : KDDockWidgets::RestoreOption_None;
610 :
611 0 : KDDockWidgets::LayoutSaver layoutSaver(iocContext()->id, option);
612 0 : return layoutSaver.restoreLayout(layout);
613 0 : }
614 :
615 3 : bool DockWindow::checkLayoutIsCorrupted() const
616 : {
617 4 : TRACEFUNC;
618 :
619 12 : for (const DockBase* dock : m_currentPage->allDocks()) {
620 9 : if (!dock) {
621 0 : continue;
622 : }
623 :
624 9 : if (!dock->floatable() && dock->floating()) {
625 0 : return true;
626 : }
627 3 : }
628 :
629 3 : return false;
630 3 : }
631 :
632 0 : void DockWindow::forceLayout()
633 : {
634 0 : m_mainWindow->layoutEqually();
635 0 : }
636 :
637 0 : QByteArray DockWindow::windowState() const
638 : {
639 0 : TRACEFUNC;
640 :
641 0 : KDDockWidgets::LayoutSaver layoutSaver(iocContext()->id, KDDockWidgets::RestoreOption_None);
642 0 : return layoutSaver.serializeLayout();
643 0 : }
644 :
645 0 : void DockWindow::reloadCurrentPage()
646 : {
647 0 : if (!m_reloadCurrentPageAllowed) {
648 0 : return;
649 : }
650 :
651 0 : TRACEFUNC;
652 :
653 0 : clearRegistry(iocContext()->id);
654 :
655 0 : for (DockBase* dock : m_currentPage->allDocks()) {
656 0 : dock->deinit();
657 0 : }
658 :
659 0 : QString currentPageUriBackup = currentPageUri();
660 :
661 : /// NOTE: for reset geometry
662 0 : m_currentPage = nullptr;
663 :
664 0 : if (doLoadPage(currentPageUriBackup)) {
665 0 : notifyAboutDocksOpenStatus();
666 : }
667 0 : }
668 :
669 3 : void DockWindow::initDocks(DockPageView* page)
670 : {
671 4 : TRACEFUNC;
672 :
673 : //! before init we should correct toolbars sizes
674 3 : m_topLevelToolBarsLayout->adjustContentForAvailableSpace(page);
675 :
676 6 : for (DockToolBarView* toolbar : m_toolBars.list()) {
677 3 : toolbar->setParentItem(this);
678 3 : toolbar->init();
679 3 : }
680 :
681 3 : if (page) {
682 3 : page->setParentItem(this);
683 3 : page->init();
684 : }
685 :
686 3 : m_topLevelToolBarsLayout->setUpPageConnections(page);
687 3 : m_topLevelToolBarsLayout->scheduleRelayout();
688 3 : }
689 :
690 3 : void DockWindow::notifyAboutDocksOpenStatus()
691 : {
692 3 : const DockPageView* page = currentPage();
693 :
694 3 : IF_ASSERT_FAILED(page) {
695 0 : return;
696 : }
697 :
698 3 : QStringList dockNames;
699 :
700 6 : for (DockToolBarView* toolBar : page->mainToolBars()) {
701 3 : dockNames << toolBar->objectName();
702 3 : }
703 :
704 3 : for (DockToolBarView* toolBar : page->toolBars()) {
705 0 : dockNames << toolBar->objectName();
706 3 : }
707 :
708 6 : for (DockPanelView* panel : page->panels()) {
709 3 : dockNames << panel->objectName();
710 3 : }
711 :
712 3 : if (page->statusBar()) {
713 0 : dockNames << page->statusBar()->objectName();
714 : }
715 :
716 3 : m_docksOpenStatusChanged.send(dockNames);
717 3 : }
718 :
719 12 : QList<DockToolBarView*> DockWindow::topLevelToolBars(const DockPageView* page) const
720 : {
721 12 : QList<DockToolBarView*> toolBars = m_toolBars.list();
722 :
723 12 : if (page) {
724 12 : toolBars << page->mainToolBars();
725 : }
726 :
727 12 : return toolBars;
728 0 : }
|