// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "designmodewidget.h" #include #include "qmldesignerplugin.h" #include "crumblebar.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Core; using namespace QmlDesigner; enum { debug = false }; static void hideToolButtons(QList &buttons) { for (QToolButton *button : buttons) button->hide(); } static void ensureMinimumSize(QWidget *widget) { if (widget->minimumSize().isEmpty()) widget->setMinimumSize(widget->minimumSize().expandedTo(QSize(60, 60))); } static ADS::DockWidget *createDockWidget(QWidget *widget, const QString &uniqueId, const QString &title, ADS::DockWidget::eMinimumSizeHintMode minimumSizeHintMode) { ADS::DockWidget *dockWidget = new ADS::DockWidget(uniqueId); dockWidget->setWidget(widget, ADS::DockWidget::ForceNoScrollArea); dockWidget->setWindowTitle(title); dockWidget->setMinimumSizeHintMode(minimumSizeHintMode); widget->setObjectName(uniqueId); // Set unique id as object name return dockWidget; } namespace QmlDesigner { namespace Internal { class ItemLibrarySideBarItem : public Core::SideBarItem { public: explicit ItemLibrarySideBarItem(QWidget *widget, const QString &id); ~ItemLibrarySideBarItem() override; QList createToolBarWidgets() override; }; ItemLibrarySideBarItem::ItemLibrarySideBarItem(QWidget *widget, const QString &id) : Core::SideBarItem(widget, id) {} ItemLibrarySideBarItem::~ItemLibrarySideBarItem() = default; QList ItemLibrarySideBarItem::createToolBarWidgets() { return qobject_cast(widget())->createToolBarWidgets(); } // ---------- DesignModeWidget DesignModeWidget::DesignModeWidget() : m_toolBar(new Core::EditorToolBar(this)) , m_crumbleBar(new CrumbleBar(this)) { setAcceptDrops(true); IContext::attach(this, Context(Constants::qmlDesignerContextId, Constants::qtQuickToolsMenuContextId), [this](const IContext::HelpCallback &callback) { contextHelp(callback); }); } DesignModeWidget::~DesignModeWidget() { for (QPointer widget : std::as_const(m_viewWidgets)) { if (widget) widget.clear(); } delete m_dockManager; } void DesignModeWidget::readSettings() // readPerspectives { return; } void DesignModeWidget::saveSettings() // savePerspectives { return; } void DesignModeWidget::enableWidgets() { if (debug) qDebug() << Q_FUNC_INFO; viewManager().enableWidgets(); m_isDisabled = false; } void DesignModeWidget::disableWidgets() { if (debug) qDebug() << Q_FUNC_INFO; viewManager().disableWidgets(); m_isDisabled = true; } static void addSpacerToToolBar(QToolBar *toolBar) { QWidget* empty = new QWidget(); empty->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); toolBar->addWidget(empty); } void DesignModeWidget::setup() { auto settings = Core::ICore::settings(QSettings::UserScope); ADS::DockManager::setConfigFlags(ADS::DockManager::DefaultNonOpaqueConfig); ADS::DockManager::setConfigFlag(ADS::DockManager::FocusHighlighting, true); ADS::DockManager::setConfigFlag(ADS::DockManager::DockAreaHasCloseButton, false); ADS::DockManager::setConfigFlag(ADS::DockManager::DockAreaHasUndockButton, false); ADS::DockManager::setConfigFlag(ADS::DockManager::DockAreaHasTabsMenuButton, false); ADS::DockManager::setConfigFlag(ADS::DockManager::OpaqueSplitterResize, true); ADS::DockManager::setConfigFlag(ADS::DockManager::AllTabsHaveCloseButton, false); ADS::DockManager::setConfigFlag(ADS::DockManager::RetainTabSizeWhenCloseButtonHidden, true); //ADS::DockManager::setAutoHideConfigFlags(ADS::DockManager::DefaultAutoHideConfig); auto designerSettings = DesignerSettings(); if (designerSettings.value(DesignerSettingsKey::ENABLE_DOCKWIDGET_CONTENT_MIN_SIZE).toBool()) m_minimumSizeHintMode = ADS::DockWidget::MinimumSizeHintFromContentMinimumSize; m_dockManager = new ADS::DockManager(this); m_dockManager->setSettings(settings); m_dockManager->setWorkspacePresetsPath( Core::ICore::resourcePath("qmldesigner/workspacePresets/").toUrlishString()); QString sheet = Utils::FileUtils::fetchQrc(":/qmldesigner/dockwidgets.css"); m_dockManager->setStyleSheet(Theme::replaceCssColors(sheet)); connect(ProjectExplorer::ProjectManager::instance(), &ProjectExplorer::ProjectManager::projectFinishedParsing, m_dockManager, [this]() { this->m_dockManager->setMcusProject(QmlProjectManager::QmlProject::isMCUs()); }); // Setup icons const QString closeUnicode = Theme::getIconUnicode(Theme::Icon::close_small); const QString maximizeUnicode = Theme::getIconUnicode(Theme::Icon::maxBar_small); const QString normalUnicode = Theme::getIconUnicode(Theme::Icon::normalBar_small); const QString fontName = "qtds_propertyIconFont.ttf"; const QSize size = QSize(28, 28); auto tabCloseIconNormal = Utils::StyleHelper::IconFontHelper( closeUnicode, Theme::getColor(Theme::DSdockWidgetTitleBar), size, QIcon::Normal, QIcon::Off); auto tabCloseIconActive = Utils::StyleHelper::IconFontHelper( closeUnicode, Theme::getColor(Theme::DSdockWidgetTitleBar), size, QIcon::Active, QIcon::Off); auto tabCloseIconFocus = Utils::StyleHelper::IconFontHelper( closeUnicode, Theme::getColor(Theme::DSdockWidgetTitleBar), size, QIcon::Selected, QIcon::Off); const QIcon tabsCloseIcon = Utils::StyleHelper::getIconFromIconFont(fontName, {tabCloseIconNormal, tabCloseIconActive, tabCloseIconFocus}); ADS::DockManager::iconProvider().registerCustomIcon(ADS::TabCloseIcon, tabsCloseIcon); auto floatingWidgetCloseIconNormal = Utils::StyleHelper::IconFontHelper( closeUnicode, Theme::getColor(Theme::DStitleBarText), QSize(17, 17), QIcon::Normal, QIcon::Off); const QIcon floatingWidgetCloseIcon = Utils::StyleHelper::getIconFromIconFont( fontName, {floatingWidgetCloseIconNormal}); ADS::DockManager::iconProvider().registerCustomIcon(ADS::FloatingWidgetCloseIcon, floatingWidgetCloseIcon); auto floatingWidgetMaxIconNormal = Utils::StyleHelper::IconFontHelper(maximizeUnicode, Theme::getColor( Theme::DStitleBarText), QSize(17, 17), QIcon::Normal, QIcon::Off); const QIcon floatingWidgetMaxIcon = Utils::StyleHelper::getIconFromIconFont( fontName, {floatingWidgetMaxIconNormal}); ADS::DockManager::iconProvider().registerCustomIcon(ADS::FloatingWidgetMaximizeIcon, floatingWidgetMaxIcon); auto floatingWidgetNormalIconNormal = Utils::StyleHelper::IconFontHelper( normalUnicode, Theme::getColor(Theme::DStitleBarText), QSize(17, 17), QIcon::Normal, QIcon::Off); const QIcon floatingWidgetNormalIcon = Utils::StyleHelper::getIconFromIconFont( fontName, {floatingWidgetNormalIconNormal}); ADS::DockManager::iconProvider().registerCustomIcon(ADS::FloatingWidgetNormalIcon, floatingWidgetNormalIcon); // Create a DockWidget for each QWidget and add them to the DockManager const Core::Context designContext(Core::Constants::C_DESIGN_MODE); static const Utils::Id actionToggle("QmlDesigner.Toggle"); // First get all navigation views QList factories = Core::INavigationWidgetFactory::allNavigationFactories(); QList viewCommands; const QList navigationViewIds = {"Projects", "File System", "Open Documents"}; for (Core::INavigationWidgetFactory *factory : factories) { Core::NavigationView navigationView = {nullptr, {}}; if (!navigationViewIds.contains(factory->id())) continue; navigationView = factory->createWidget(); if (!navigationView.widget) continue; hideToolButtons(navigationView.dockToolBarWidgets); navigationView.widget->setWindowTitle(factory->displayName()); QString idString = factory->id().toSetting().toString(); const QString title = idString; const QString uniqueId = idString.remove(" "); // title without whitespaces // Apply stylesheet to QWidget QString sheet = Utils::FileUtils::fetchQrc(":/qmldesigner/stylesheet.css"); sheet += "QLabel { background-color: creatorTheme.DSsectionHeadBackground; }"; navigationView.widget->setStyleSheet(Theme::replaceCssColors(sheet)); ensureMinimumSize(navigationView.widget); auto dockWidget = createDockWidget(navigationView.widget, uniqueId, title, m_minimumSizeHintMode); m_dockManager->addDockWidget(ADS::NoDockWidgetArea, dockWidget); // Create menu action auto command = Core::ActionManager::registerAction(dockWidget->toggleViewAction(), actionToggle.withSuffix(uniqueId).withSuffix("Widget"), designContext); command->setAttribute(Core::Command::CA_Hide); viewCommands.append(command); } viewManager().initializeWidgetInfos(); // Afterwards get all the other widgets for (const auto &view : viewManager().views()) { if (!view->hasWidget()) continue; auto widgetInfo = view->widgetInfo(); ensureMinimumSize(widgetInfo.widget); auto dockWidget = createDockWidget(widgetInfo.widget, widgetInfo.uniqueId, widgetInfo.tabName, m_minimumSizeHintMode); m_dockManager->addDockWidget(ADS::NoDockWidgetArea, dockWidget); // Add to view widgets m_viewWidgets.append(widgetInfo.widget); // Create menu action auto viewAction = view->action(); viewAction->setText(widgetInfo.tabName); dockWidget->setToggleViewAction(viewAction); auto command = Core::ActionManager::registerAction(viewAction, actionToggle.withSuffix(widgetInfo.uniqueId).withSuffix("Widget"), designContext); command->setAttribute(Core::Command::CA_Hide); viewCommands.append(command); } // PropertyEditor Unified action if (auto propertyEditorAction = viewManager().propertyEditorUnifiedAction()) { auto command = Core::ActionManager::registerAction(propertyEditorAction, actionToggle.withSuffix( "Property Editor Global"), designContext); command->setAttribute(Core::Command::CA_Hide); viewCommands.append(command); } // Finally the output pane { const QString uniqueId = "OutputPane"; auto outputPanePlaceholder = new Core::OutputPanePlaceHolder(Core::Constants::MODE_DESIGN); ensureMinimumSize(outputPanePlaceholder); m_outputPaneDockWidget = createDockWidget(outputPanePlaceholder, uniqueId, tr("Output"), m_minimumSizeHintMode); m_dockManager->addDockWidget(ADS::NoDockWidgetArea, m_outputPaneDockWidget); // Create menu action auto command = Core::ActionManager::registerAction(m_outputPaneDockWidget->toggleViewAction(), actionToggle.withSuffix("OutputPaneWidget"), designContext); command->setAttribute(Core::Command::CA_Hide); viewCommands.append(command); connect(outputPanePlaceholder, &Core::OutputPanePlaceHolder::visibilityChangeRequested, m_outputPaneDockWidget, &ADS::DockWidget::toggleView); } std::sort(viewCommands.begin(), viewCommands.end(), [](Core::Command *first, Core::Command *second) { return first->description() < second->description(); }); // Setup Actions and Menus Core::ActionContainer *mview = Core::ActionManager::actionContainer(Core::Constants::M_VIEW); // View > Views Core::ActionContainer *mviews = Core::ActionManager::createMenu(Core::Constants::M_VIEW_VIEWS); connect(mviews->menu(), &QMenu::aboutToShow, this, &DesignModeWidget::aboutToShowViews); mviews->menu()->addSeparator(); // View > Workspaces Core::ActionContainer *mworkspaces = Core::ActionManager::createMenu( QmlDesigner::Constants::M_VIEW_WORKSPACES); mview->addMenu(mworkspaces, Core::Constants::G_VIEW_VIEWS); mworkspaces->menu()->setTitle(tr("&Workspaces")); mworkspaces->setOnAllDisabledBehavior(Core::ActionContainer::Show); // Connect opening of the 'workspaces' menu with creation of the workspaces menu connect(mworkspaces->menu(), &QMenu::aboutToShow, this, &DesignModeWidget::aboutToShowWorkspaces); // Initially disable menus mworkspaces->menu()->setEnabled(false); // Enable/disable menus when mode is different to MODE_DESIGN connect(Core::ModeManager::instance(), &Core::ModeManager::currentModeChanged, this, [mworkspaces](Utils::Id mode, Utils::Id) { if (mode == Core::Constants::MODE_DESIGN) { mworkspaces->menu()->setEnabled(true); } else { mworkspaces->menu()->setEnabled(false); } }); for (Core::Command *command : viewCommands) mviews->addAction(command); // Create toolbars if (!ToolBar::isVisible()) { auto toolBar = new QToolBar(); toolBar->addAction(viewManager().componentViewAction()); toolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); DesignerActionToolBar *designerToolBar = QmlDesignerPlugin::instance() ->viewManager() .designerActionManager() .createToolBar(m_toolBar); designerToolBar->layout()->addWidget(toolBar); m_toolBar->addCenterToolBar(designerToolBar); m_toolBar->setMinimumWidth(320); m_toolBar->setToolbarCreationFlags(Core::EditorToolBar::FlagsStandalone); m_toolBar->setNavigationVisible(true); connect(m_toolBar, &Core::EditorToolBar::goForwardClicked, this, &DesignModeWidget::toolBarOnGoForwardClicked); connect(m_toolBar, &Core::EditorToolBar::goBackClicked, this, &DesignModeWidget::toolBarOnGoBackClicked); QToolBar* toolBarWrapper = new QToolBar(); toolBarWrapper->addWidget(m_toolBar); toolBarWrapper->addWidget(createCrumbleBarFrame()); toolBarWrapper->setMovable(false); addToolBar(Qt::TopToolBarArea, toolBarWrapper); addSpacerToToolBar(toolBar); const QIcon gaIcon = Utils::StyleHelper::getIconFromIconFont( fontName, Theme::getIconUnicode(Theme::Icon::annotationBubble), 36, 36, Theme::getColor(Theme::IconsBaseColor)); toolBar->addAction(gaIcon, tr("Edit global annotation for current file."), [&](){ ModelNode node = currentDesignDocument()->rewriterView()->rootModelNode(); if (node.isValid()) { m_globalAnnotationEditor.setModelNode(node); m_globalAnnotationEditor.showWidget(); } }); } if (currentDesignDocument()) setupNavigatorHistory(currentDesignDocument()->textEditor()); m_dockManager->initialize(); if (style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, this)) Utils::GlobalTransientSupport::support(m_dockManager); // Hide all floating widgets if the initial mode isn't design mode if (Core::ModeManager::instance()->currentModeId() != Core::Constants::MODE_DESIGN) { for (auto &floatingWidget : m_dockManager->floatingWidgets()) floatingWidget->hide(); } connect(Core::ModeManager::instance(), &Core::ModeManager::currentModeChanged, this, [this](Utils::Id mode, Utils::Id previousMode) { if (mode == Core::Constants::MODE_DESIGN) { m_dockManager->aboutToShow(); m_dockManager->reloadActiveWorkspace(); m_dockManager->setModeChangeState(false); } if (previousMode == Core::Constants::MODE_DESIGN && mode != Core::Constants::MODE_DESIGN) { m_dockManager->save(); m_dockManager->setModeChangeState(true); for (auto &floatingWidget : m_dockManager->floatingWidgets()) floatingWidget->hide(); } }); viewManager().enableWidgets(); readSettings(); show(); } static bool isMcuDisabledView(const QString viewId) { static const QStringList mcuDisabledViews = { "Editor3D", "MaterialBrowser", "EffectComposer", }; return mcuDisabledViews.contains(viewId); } void DesignModeWidget::aboutToShowViews() { for (const WidgetInfo &widgetInfo : viewManager().widgetInfos()) { QString id = widgetInfo.uniqueId; ADS::DockWidget *dockWidget = m_dockManager->findDockWidget(id); if (!dockWidget) continue; QAction *action = dockWidget->toggleViewAction(); if (!action) continue; bool isMcuProject = currentDesignDocument() && currentDesignDocument()->isQtForMCUsProject(); if (isMcuProject && isMcuDisabledView(id) && action->isEnabled()) { action->setChecked(false); action->setEnabled(false); } else if (!isMcuProject && !action->isEnabled()) { action->setEnabled(true); } } } void DesignModeWidget::aboutToShowWorkspaces() { Core::ActionContainer *aci = Core::ActionManager::actionContainer( QmlDesigner::Constants::M_VIEW_WORKSPACES); QMenu *menu = aci->menu(); menu->clear(); auto *ag = new QActionGroup(menu); connect(ag, &QActionGroup::triggered, this, [this](QAction *action) { m_dockManager->openWorkspace(action->data().toString()); }); QAction *action = menu->addAction(tr("Manage...")); connect(action, &QAction::triggered, m_dockManager, &ADS::DockManager::showWorkspaceMananger); QAction *lockWorkspace = menu->addAction(tr("Lock Workspaces")); lockWorkspace->setCheckable(true); lockWorkspace->setChecked(m_dockManager->isWorkspaceLocked()); connect(lockWorkspace, &QAction::triggered, this, [this](bool checked) { m_dockManager->lockWorkspace(checked); }); QAction *resetWorkspace = menu->addAction(tr("Reset Active")); connect(resetWorkspace, &QAction::triggered, this, [this] { if (m_dockManager->resetWorkspacePreset(m_dockManager->activeWorkspace()->fileName())) m_dockManager->reloadActiveWorkspace(); }); menu->addSeparator(); auto workspaces = m_dockManager->workspaces(); for (const auto &workspace : std::as_const(workspaces)) { QAction *action = ag->addAction(workspace.name()); action->setData(workspace.fileName()); action->setCheckable(true); if (workspace == *m_dockManager->activeWorkspace()) action->setChecked(true); if (currentDesignDocument() && currentDesignDocument()->isQtForMCUsProject()) action->setEnabled(workspace.isMcusEnabled()); } menu->addActions(ag->actions()); } void DesignModeWidget::showExtraWidget(WidgetInfo widgetInfo) { ensureMinimumSize(widgetInfo.widget); ADS::DockWidget *dockWidget = m_dockManager->findDockWidget(widgetInfo.uniqueId); bool justCreated = false; if (!dockWidget) { dockWidget = createDockWidget(widgetInfo.widget, widgetInfo.uniqueId, widgetInfo.tabName, m_minimumSizeHintMode); if (dockWidget->tabWidget()) { connect(dockWidget->tabWidget(), &ADS::DockWidgetTab::closeRequested, this, [widgetInfo, this]() { viewManager().removeExtraView(widgetInfo); }); } justCreated = true; } if (justCreated) { ADS::DockWidget *parentDockWidget = m_dockManager->findDockWidget(widgetInfo.parentId); if (parentDockWidget) { auto parentArea = parentDockWidget->dockAreaWidget(); m_dockManager->addDockWidgetTabToArea(dockWidget, parentArea); parentArea->setDockAreaFlag(ADS::DockAreaWidget::HideSingleWidgetTitleBar, true); } else { m_dockManager->addDockWidget(ADS::NoDockWidgetArea, dockWidget); dockWidget->setFloating(); } } else { dockWidget->toggleView(true); } dockWidget->setFeature(ADS::DockWidget::DockWidgetAlwaysCloseAndDelete, false); if (auto dockArea = dockWidget->dockAreaWidget()) dockArea->setDockAreaFlag(ADS::DockAreaWidget::HideSingleWidgetTitleBar, true); if (auto tabWidget = dockWidget->tabWidget(); tabWidget && tabWidget->dockAreaWidget()) { tabWidget->dockAreaWidget()->setDockAreaFlag(ADS::DockAreaWidget::HideSingleWidgetTitleBar, true); } if (m_dockManager->isWorkspaceLocked()) { dockWidget->setFeature(ADS::DockWidget::DockWidgetMovable, false); dockWidget->setFeature(ADS::DockWidget::DockWidgetFloatable, false); } } void DesignModeWidget::closeExtraWidget(WidgetInfo widgetInfo) { ADS::DockWidget *dockWidget = m_dockManager->findDockWidget(widgetInfo.uniqueId); if (dockWidget) dockWidget->closeDockWidget(); } void DesignModeWidget::removeExtraWidget(WidgetInfo widgetInfo) { ADS::DockWidget *dockWidget = m_dockManager->findDockWidget(widgetInfo.uniqueId); if (!dockWidget) return; m_dockManager->removeDockWidget(dockWidget); } void DesignModeWidget::hideSingleWidgetTitleBars(const QString &uniqueId) { auto dockWidget = dockManager()->findDockWidget(uniqueId); if (!dockWidget) return; if (auto dockArea = dockWidget->dockAreaWidget()) { dockArea->setDockAreaFlag(ADS::DockAreaWidget::HideSingleWidgetTitleBar, false); dockArea->setDockAreaFlag(ADS::DockAreaWidget::HideSingleWidgetTitleBar, true); } if (auto tabWidget = dockWidget->tabWidget(); tabWidget && tabWidget->dockAreaWidget()) { auto dockArea = tabWidget->dockAreaWidget(); dockArea->setDockAreaFlag(ADS::DockAreaWidget::HideSingleWidgetTitleBar, false); dockArea->setDockAreaFlag(ADS::DockAreaWidget::HideSingleWidgetTitleBar, true); } } void DesignModeWidget::toolBarOnGoBackClicked() { if (m_navigatorHistoryCounter > 0) { --m_navigatorHistoryCounter; m_keepNavigatorHistory = true; Core::EditorManager::openEditor(Utils::FilePath::fromString( m_navigatorHistory.at(m_navigatorHistoryCounter)), Utils::Id(), Core::EditorManager::DoNotMakeVisible); m_keepNavigatorHistory = false; } } void DesignModeWidget::toolBarOnGoForwardClicked() { if (m_navigatorHistoryCounter < (m_navigatorHistory.size() - 1)) { ++m_navigatorHistoryCounter; m_keepNavigatorHistory = true; Core::EditorManager::openEditor(Utils::FilePath::fromString( m_navigatorHistory.at(m_navigatorHistoryCounter)), Utils::Id(), Core::EditorManager::DoNotMakeVisible); m_keepNavigatorHistory = false; } } bool DesignModeWidget::canGoForward() { return m_canGoForward; } bool DesignModeWidget::canGoBack() { return m_canGoBack; } ADS::DockManager *DesignModeWidget::dockManager() const { return m_dockManager; } GlobalAnnotationEditor &DesignModeWidget::globalAnnotationEditor() { return m_globalAnnotationEditor; } void DesignModeWidget::setMinimumSizeHintFromContentMinimumSize(bool value) { // This is the default mode ADS::DockWidget::eMinimumSizeHintMode newMode = ADS::DockWidget::MinimumSizeHintFromDockWidget; if (value) newMode = ADS::DockWidget::MinimumSizeHintFromContentMinimumSize; if (newMode == m_minimumSizeHintMode) return; m_minimumSizeHintMode = newMode; if (!m_dockManager) return; const auto &dockWidgets = m_dockManager->dockWidgetsMap(); for (auto dockWidget : dockWidgets) dockWidget->setMinimumSizeHintMode(m_minimumSizeHintMode); const auto &dockContainers = m_dockManager->dockContainers(); // This still needs to be updated manually to show changes immediately after option was toggled for (auto dockContainer : dockContainers) dockContainer->layout()->update(); } bool DesignModeWidget::isInitialized() const { return m_initStatus == Initialized; } void DesignModeWidget::dragEnterEvent(QDragEnterEvent *event) { event->accept(); event->setDropAction(Qt::IgnoreAction); } DesignDocument *DesignModeWidget::currentDesignDocument() const { return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument(); } ViewManager &DesignModeWidget::viewManager() { return QmlDesignerPlugin::instance()->viewManager(); } void DesignModeWidget::setupNavigatorHistory(Core::IEditor *editor) { if (!m_keepNavigatorHistory) addNavigatorHistoryEntry(editor->document()->filePath()); m_canGoBack = m_navigatorHistoryCounter > 0; m_canGoForward = m_navigatorHistoryCounter < (m_navigatorHistory.size() - 1); m_toolBar->setCanGoBack(m_canGoBack); m_toolBar->setCanGoForward(m_canGoForward); if (!ToolBar::isVisible()) m_toolBar->setCurrentEditor(editor); emit navigationHistoryChanged(); } void DesignModeWidget::addNavigatorHistoryEntry(const Utils::FilePath &fileName) { if (m_navigatorHistoryCounter > 0) m_navigatorHistory.insert(m_navigatorHistoryCounter + 1, fileName.toUrlishString()); else m_navigatorHistory.append(fileName.toUrlishString()); ++m_navigatorHistoryCounter; } QWidget *DesignModeWidget::createCrumbleBarFrame() { auto frame = new Utils::StyledBar(this); frame->setSingleRow(false); auto layout = new QHBoxLayout(frame); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); layout->addWidget(m_crumbleBar->crumblePath()); return frame; } CrumbleBar *DesignModeWidget::crumbleBar() const { return m_crumbleBar; } void DesignModeWidget::showDockWidget(const QString &objectName, bool focus) { auto dockWidget = m_dockManager->findDockWidget(objectName); if (dockWidget) { dockWidget->toggleView(true); if (focus) dockWidget->setFocus(); } } void DesignModeWidget::contextHelp(const Core::IContext::HelpCallback &callback) const { if (currentDesignDocument()) currentDesignDocument()->contextHelp(callback); else callback({}); } void DesignModeWidget::initialize() { if (m_initStatus == NotInitialized) { m_initStatus = Initializing; setup(); emit initialized(); } m_initStatus = Initialized; } } // namespace Internal } // namespace Designer