diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h index ae4152c1dee..48b51ee1ea3 100644 --- a/src/plugins/coreplugin/coreconstants.h +++ b/src/plugins/coreplugin/coreconstants.h @@ -173,6 +173,7 @@ const char G_WINDOW_PANES[] = "QtCreator.Group.Window.Panes"; const char G_WINDOW_VIEWS[] = "QtCreator.Group.Window.Views"; const char G_WINDOW_SPLIT[] = "QtCreator.Group.Window.Split"; const char G_WINDOW_NAVIGATE[] = "QtCreator.Group.Window.Navigate"; +const char G_WINDOW_LIST[] = "QtCreator.Group.Window.List"; const char G_WINDOW_OTHER[] = "QtCreator.Group.Window.Other"; // Help groups (global) diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index f404d78c727..582c1063dcb 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -446,6 +446,7 @@ void MainWindow::registerDefaultContainers() mwindow->appendGroup(Constants::G_WINDOW_PANES); mwindow->appendGroup(Constants::G_WINDOW_SPLIT); mwindow->appendGroup(Constants::G_WINDOW_NAVIGATE); + mwindow->appendGroup(Constants::G_WINDOW_LIST); mwindow->appendGroup(Constants::G_WINDOW_OTHER); // Help Menu @@ -628,6 +629,8 @@ void MainWindow::registerDefaultActions() mtools->addAction(cmd, Constants::G_TOOLS_OPTIONS); connect(m_optionsAction, SIGNAL(triggered()), this, SLOT(showOptionsDialog())); + mwindow->addSeparator(globalContext, Constants::G_WINDOW_LIST); + if (UseMacShortcuts) { // Minimize Action QAction *minimizeAction = new QAction(tr("Minimize"), this); diff --git a/src/plugins/coreplugin/windowsupport.cpp b/src/plugins/coreplugin/windowsupport.cpp index 5dcae690b61..44caf3ac128 100644 --- a/src/plugins/coreplugin/windowsupport.cpp +++ b/src/plugins/coreplugin/windowsupport.cpp @@ -29,19 +29,28 @@ #include "windowsupport.h" +#include "actionmanager/actioncontainer.h" #include "actionmanager/actionmanager.h" #include "coreconstants.h" #include "icore.h" #include +#include #include -#include #include +#include +#include namespace Core { namespace Internal { + +QMenu *WindowList::m_dockMenu = 0; +QList WindowList::m_windows; +QList WindowList::m_windowActions; +QList WindowList::m_windowActionIds; + WindowSupport::WindowSupport(QWidget *window, const Context &context) : QObject(window), m_window(window) @@ -71,6 +80,8 @@ WindowSupport::WindowSupport(QWidget *window, const Context &context) updateFullScreenAction(); ActionManager::registerAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, context); connect(m_toggleFullScreenAction, SIGNAL(triggered()), this, SLOT(toggleFullScreen())); + + WindowList::addWindow(window); } WindowSupport::~WindowSupport() @@ -82,6 +93,7 @@ WindowSupport::~WindowSupport() } ActionManager::unregisterAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN); ICore::removeContextObject(m_contextObject); + WindowList::removeWindow(m_window); } void WindowSupport::setCloseActionEnabled(bool enabled) @@ -101,6 +113,8 @@ bool WindowSupport::eventFilter(QObject *obj, QEvent *event) m_zoomAction->setEnabled(!minimized); } updateFullScreenAction(); + } else if (event->type() == QEvent::WindowActivate) { + WindowList::setActiveWindow(m_window); } return false; } @@ -129,6 +143,74 @@ void WindowSupport::updateFullScreenAction() } } +void WindowList::addWindow(QWidget *window) +{ + if (Utils::HostOsInfo::isMacHost() && !m_dockMenu) { + m_dockMenu = new QMenu; + m_dockMenu->setAsDockMenu(); + } + + m_windows.append(window); + Id id = Id("QtCreator.Window.").withSuffix(m_windows.size()); + m_windowActionIds.append(id); + auto action = new QAction(window->windowTitle(), 0); + m_windowActions.append(action); + connect(action, &QAction::triggered, [action]() { WindowList::activateWindow(action); }); + action->setCheckable(true); + action->setChecked(false); + Command *cmd = ActionManager::registerAction(action, id, + Context(Constants::C_GLOBAL)); + cmd->setAttribute(Command::CA_UpdateText); + ActionManager::actionContainer(Constants::M_WINDOW)->addAction(cmd, Constants::G_WINDOW_LIST); + connect(window, &QWidget::windowTitleChanged, [window]() { WindowList::updateTitle(window); }); + if (m_dockMenu) + m_dockMenu->addAction(action); + if (window->isActiveWindow()) + setActiveWindow(window); +} + +void WindowList::activateWindow(QAction *action) +{ + int index = m_windowActions.indexOf(action); + QTC_ASSERT(index >= 0, return); + QTC_ASSERT(index < m_windows.size(), return); + ICore::raiseWindow(m_windows.at(index)); +} + +void WindowList::updateTitle(QWidget *window) +{ + int index = m_windows.indexOf(window); + QTC_ASSERT(index >= 0, return); + QTC_ASSERT(index < m_windowActions.size(), return); + QString title = window->windowTitle(); + if (title.endsWith(QStringLiteral("- Qt Creator"))) + title.chop(12); + m_windowActions.at(index)->setText(title.trimmed()); +} + +void WindowList::removeWindow(QWidget *window) +{ + // remove window from list, + // remove last action from menu(s) + // and update all action titles, starting with the index where the window was + int index = m_windows.indexOf(window); + QTC_ASSERT(index >= 0, return); + + ActionManager::unregisterAction(m_windowActions.last(), m_windowActionIds.last()); + m_windowActions.removeLast(); + m_windowActionIds.removeLast(); + + m_windows.removeOne(window); + + for (int i = index; i < m_windows.size(); ++i) + updateTitle(m_windows.at(i)); +} + +void WindowList::setActiveWindow(QWidget *window) +{ + for (int i = 0; i < m_windows.size(); ++i) + m_windowActions.at(i)->setChecked(m_windows.at(i) == window); +} } // Internal } // Core diff --git a/src/plugins/coreplugin/windowsupport.h b/src/plugins/coreplugin/windowsupport.h index 2fa4bac9646..b1e479e4a18 100644 --- a/src/plugins/coreplugin/windowsupport.h +++ b/src/plugins/coreplugin/windowsupport.h @@ -36,12 +36,31 @@ QT_BEGIN_NAMESPACE class QAction; +class QMenu; class QWidget; QT_END_NAMESPACE namespace Core { namespace Internal { +class WindowList : public QObject +{ + Q_OBJECT +public: + static void addWindow(QWidget *window); + static void removeWindow(QWidget *window); + static void setActiveWindow(QWidget *window); + +private: + static void activateWindow(QAction *action); + static void updateTitle(QWidget *window); + + static QMenu *m_dockMenu; + static QList m_windows; + static QList m_windowActions; + static QList m_windowActionIds; +}; + class WindowSupport : public QObject { Q_OBJECT