diff --git a/src/plugins/coreplugin/fancytabwidget.cpp b/src/plugins/coreplugin/fancytabwidget.cpp index de14c8ca6d7..5a10a2d7f17 100644 --- a/src/plugins/coreplugin/fancytabwidget.cpp +++ b/src/plugins/coreplugin/fancytabwidget.cpp @@ -212,11 +212,10 @@ void FancyTabBar::mousePressEvent(QMouseEvent *event) continue; const QRect rect = tabRect(visibleIndex); if (rect.contains(event->pos())) { - if (isTabEnabled(index)) { + if (isTabEnabled(index) && event->button() == Qt::LeftButton) { if (m_tabs.at(index)->hasMenu - && ((!m_iconsOnly && rect.right() - event->pos().x() <= kMenuButtonWidth) - || event->button() == Qt::RightButton)) { - // menu arrow clicked or right-click + && (!m_iconsOnly && rect.right() - event->pos().x() <= kMenuButtonWidth)) { + // menu arrow clicked emit menuTriggered(index, event); } else { if (index != m_currentIndex) { @@ -226,11 +225,16 @@ void FancyTabBar::mousePressEvent(QMouseEvent *event) emit currentChanged(m_currentIndex); } } + } else if (event->button() == Qt::RightButton) { + emit menuTriggered(index, event); } - break; + return; } ++visibleIndex; } + // not in a mode button + if (event->button() == Qt::RightButton) + emit menuTriggered(-1, event); } static void paintSelectedTabBackground(QPainter *painter, const QRect &spanRect) @@ -457,7 +461,7 @@ public: setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); } - void mousePressEvent(QMouseEvent *ev) override { emit clicked(ev->button(), ev->modifiers()); } + void mousePressEvent(QMouseEvent *ev) override { emit clicked(ev); } void paintEvent(QPaintEvent *event) override { @@ -475,7 +479,7 @@ public: } signals: - void clicked(Qt::MouseButton button, Qt::KeyboardModifiers modifiers); + void clicked(QMouseEvent *ev); }; ////// @@ -490,7 +494,12 @@ FancyTabWidget::FancyTabWidget(QWidget *parent) auto bar = new StyledBar; auto fancyButton = new FancyColorButton; - connect(fancyButton, &FancyColorButton::clicked, this, &FancyTabWidget::topAreaClicked); + connect(fancyButton, &FancyColorButton::clicked, this, [this](QMouseEvent *event) { + if (event->button() == Qt::RightButton) + emit menuTriggered(-1, event); + else + emit topAreaClicked(event); + }); m_modesStack = new QStackedLayout; m_modesStack->addWidget(new QWidget(this)); @@ -499,6 +508,7 @@ FancyTabWidget::FancyTabWidget(QWidget *parent) QVBoxLayout *vlayout; + // clang-format off using namespace Layouting; Row { fancyButton, noMargin }.attachTo(bar); Row { @@ -507,10 +517,9 @@ FancyTabWidget::FancyTabWidget(QWidget *parent) Column { bar, m_tabBar, - st, Widget { bindTo(&m_cornerWidgetContainer), - Column { st, spacing(0), noMargin }, + Column { spacing(0), noMargin }, }, spacing(0), noMargin, }, @@ -518,6 +527,7 @@ FancyTabWidget::FancyTabWidget(QWidget *parent) Column { bindTo(&vlayout), m_modesStack, m_statusBar, spacing(0) }, spacing(1), noMargin, }.attachTo(this); + // clang-format on m_selectionWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); diff --git a/src/plugins/coreplugin/fancytabwidget.h b/src/plugins/coreplugin/fancytabwidget.h index e436e4ef01f..30de90b8f74 100644 --- a/src/plugins/coreplugin/fancytabwidget.h +++ b/src/plugins/coreplugin/fancytabwidget.h @@ -156,7 +156,7 @@ signals: void currentAboutToShow(int index); void currentChanged(int index); void menuTriggered(int index, QMouseEvent *event); - void topAreaClicked(Qt::MouseButton button, Qt::KeyboardModifiers modifiers); + void topAreaClicked(QMouseEvent *event); public slots: void setCurrentIndex(int index); diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 0daacbdfa8f..9d951b50eaf 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -79,6 +79,7 @@ #include #include #include +#include #include #include #include @@ -96,6 +97,8 @@ #include #endif +Q_LOGGING_CATEGORY(coreLog, "qtc.core", QtWarningMsg) + /*! \namespace Core \inmodule QtCreator @@ -1373,8 +1376,8 @@ void ICorePrivate::init() QApplication::setStyle(new ManhattanStyle(baseName)); m_modeManager = new ModeManager(m_modeStack); - connect(m_modeStack, &FancyTabWidget::topAreaClicked, this, [](Qt::MouseButton, Qt::KeyboardModifiers modifiers) { - if (modifiers & Qt::ShiftModifier) { + connect(m_modeStack, &FancyTabWidget::topAreaClicked, this, [](QMouseEvent *event) { + if (event->modifiers() & Qt::ShiftModifier) { QColor color = QColorDialog::getColor(StyleHelper::requestedBaseColor(), ICore::dialogParent()); if (color.isValid()) StyleHelper::setBaseColor(color); @@ -2412,6 +2415,10 @@ void ICorePrivate::updateContext() uniquecontexts.add(id); } + if (coreLog().isDebugEnabled()) { + qCDebug(coreLog) << "context changed:" + << Utils::transform>(uniquecontexts, &Id::toString); + } ActionManager::setContext(uniquecontexts); emit m_core->contextChanged(uniquecontexts); } diff --git a/src/plugins/coreplugin/imode.cpp b/src/plugins/coreplugin/imode.cpp index 29da730bfba..dca3a602ea8 100644 --- a/src/plugins/coreplugin/imode.cpp +++ b/src/plugins/coreplugin/imode.cpp @@ -21,7 +21,7 @@ class IModePrivate public: QString m_displayName; QIcon m_icon; - QMenu *m_menu = nullptr; + std::function m_menuFunction; Utils::FancyMainWindow *m_mainWindow = nullptr; int m_priority = -1; Utils::Id m_id; @@ -110,15 +110,6 @@ public: This property holds the ID of the mode. */ -/*! - \property IMode::menu - - This property holds the mode's menu. - - By default, a mode does not have a menu. When you set a menu, it is not - owned by the mode unless you set the parent explicitly. -*/ - /*! Creates an IMode with an optional \a parent. @@ -194,9 +185,15 @@ void IMode::setId(Utils::Id id) m_d->m_isVisible.readSettings(); } -void IMode::setMenu(QMenu *menu) +/*! + Sets a \a menuFunction that is used to add the mode specific items + to the mode's context menu. This is called every time the context + menu is requested with a new QMenu instance. + The menu is destroyed after the it closes. +*/ +void IMode::setMenu(std::function menuFunction) { - m_d->m_menu = menu; + m_d->m_menuFunction = menuFunction; } void IMode::setContext(const Context &context) @@ -232,9 +229,25 @@ bool IMode::isVisible() const return m_d->m_isVisible.value(); } -QMenu *IMode::menu() const +/*! + Returns if the mode provides mode specific context menu items. + + \sa setMenu() +*/ +bool IMode::hasMenu() const { - return m_d->m_menu; + return bool(m_d->m_menuFunction); +} + +/*! + Adds the mode specific items to the \a menu, if any. + + \sa setMenu() +*/ +void IMode::addToMenu(QMenu *menu) const +{ + if (m_d->m_menuFunction) + m_d->m_menuFunction(menu); } Context IMode::context() const diff --git a/src/plugins/coreplugin/imode.h b/src/plugins/coreplugin/imode.h index 35ae82f0fc4..ccd00d85558 100644 --- a/src/plugins/coreplugin/imode.h +++ b/src/plugins/coreplugin/imode.h @@ -10,6 +10,7 @@ #include #include +#include #include namespace Utils { @@ -29,7 +30,6 @@ class CORE_EXPORT IMode : public QObject Q_PROPERTY(QIcon icon READ icon WRITE setIcon) Q_PROPERTY(int priority READ priority WRITE setPriority) Q_PROPERTY(Utils::Id id READ id WRITE setId) - Q_PROPERTY(QMenu *menu READ menu WRITE setMenu) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledStateChanged) public: @@ -42,7 +42,8 @@ public: Utils::Id id() const; bool isEnabled() const; bool isVisible() const; - QMenu *menu() const; + bool hasMenu() const; + void addToMenu(QMenu *menu) const; Context context() const; QWidget *widget() const; @@ -52,7 +53,7 @@ public: void setIcon(const QIcon &icon); void setPriority(int priority); void setId(Utils::Id id); - void setMenu(QMenu *menu); + void setMenu(std::function menuFunction); void setContext(const Context &context); void setWidget(QWidget *widget); diff --git a/src/plugins/coreplugin/modemanager.cpp b/src/plugins/coreplugin/modemanager.cpp index 43258c7a05f..3aadb0356aa 100644 --- a/src/plugins/coreplugin/modemanager.cpp +++ b/src/plugins/coreplugin/modemanager.cpp @@ -104,8 +104,34 @@ static int indexOf(Id id) void ModeManagerPrivate::showMenu(int index, QMouseEvent *event) { - QTC_ASSERT(m_modes.at(index)->menu(), return); - m_modes.at(index)->menu()->popup(event->globalPosition().toPoint()); + if (index < 0) { + ActionContainer *viewContainer = ActionManager::actionContainer( + Constants::M_VIEW_MODESTYLES); + QTC_ASSERT(viewContainer, return); + QMenu *viewMenu = viewContainer->menu(); + QTC_ASSERT(viewMenu, return); + QList actions = viewMenu->actions(); + if (actions.isEmpty()) + return; + auto menu = new QMenu(m_actionBar); + menu->setAttribute(Qt::WA_DeleteOnClose); + for (QAction *a : actions) + menu->addAction(a); + menu->popup(event->globalPosition().toPoint()); + return; + } + IMode *mode = m_modes.value(index); + QTC_ASSERT(mode, return); + auto menu = new QMenu(m_actionBar); + menu->setAttribute(Qt::WA_DeleteOnClose); + mode->addToMenu(menu); + menu->addSeparator(); + menu->addAction(Tr::tr("Hide"), mode, [mode] { mode->setVisible(false); }); + menu->addSeparator(); + menu->addAction(m_setModeSelectorStyleIconsAndTextAction); + menu->addAction(m_setModeSelectorStyleIconsOnlyAction); + menu->addAction(m_setModeSelectorStyleHiddenAction); + menu->popup(event->globalPosition().toPoint()); } ModeManager::ModeManager(Internal::FancyTabWidget *modeStack) @@ -277,8 +303,7 @@ void ModeManagerPrivate::appendMode(IMode *mode) { const int index = m_modeCommands.count(); - m_modeStack->insertTab(index, mode->widget(), mode->icon(), mode->displayName(), - mode->menu() != nullptr); + m_modeStack->insertTab(index, mode->widget(), mode->icon(), mode->displayName(), mode->hasMenu()); m_modeStack->setTabEnabled(index, mode->isEnabled()); m_modeStack->setTabVisible(index, mode->isVisible()); diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index c1f4b14028d..ff16ff6d3b4 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -192,15 +192,7 @@ DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent) m_perspectiveMenu = new QMenu; connect(m_perspectiveMenu, &QMenu::aboutToShow, this, [this] { m_perspectiveMenu->clear(); - for (Perspective *perspective : std::as_const(m_perspectives)) { - m_perspectiveMenu->addAction(perspective->d->m_name, perspective, [perspective] { - if (auto subPerspective = Perspective::findPerspective( - perspective->d->m_lastActiveSubPerspectiveId)) - subPerspective->select(); - else - perspective->select(); - }); - } + DebuggerMainWindow::addPerspectiveMenu(m_perspectiveMenu); }); auto viewButton = new QToolButton; @@ -511,9 +503,19 @@ void DebuggerMainWindow::addSubPerspectiveSwitcher(QWidget *widget) d->m_subPerspectiveSwitcherLayout->addWidget(widget); } -QMenu *DebuggerMainWindow::perspectiveMenu() +void DebuggerMainWindow::addPerspectiveMenu(QMenu *menu) { - return theMainWindow ? theMainWindow->d->m_perspectiveMenu : nullptr; + if (!theMainWindow) + return; + for (Perspective *perspective : std::as_const(theMainWindow->d->m_perspectives)) { + menu->addAction(perspective->d->m_name, perspective, [perspective] { + if (auto subPerspective = Perspective::findPerspective( + perspective->d->m_lastActiveSubPerspectiveId)) + subPerspective->select(); + else + perspective->select(); + }); + } } DebuggerMainWindow *DebuggerMainWindow::instance() diff --git a/src/plugins/debugger/debuggermainwindow.h b/src/plugins/debugger/debuggermainwindow.h index e92e342397f..e6b837c36e4 100644 --- a/src/plugins/debugger/debuggermainwindow.h +++ b/src/plugins/debugger/debuggermainwindow.h @@ -142,7 +142,7 @@ public: static QWidget *centralWidgetStack(); void addSubPerspectiveSwitcher(QWidget *widget); - static QMenu *perspectiveMenu(); + static void addPerspectiveMenu(QMenu *menu); static Perspective *currentPerspective(); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 71b4f4051bb..10f2dabb6a6 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -497,7 +497,7 @@ public: setWidget(splitter); setMainWindow(mainWindow); - setMenu(DebuggerMainWindow::perspectiveMenu()); + setMenu(&DebuggerMainWindow::addPerspectiveMenu); } ~DebugMode() { delete widget(); }