diff --git a/src/plugins/coreplugin/editormanager/editorview.cpp b/src/plugins/coreplugin/editormanager/editorview.cpp index 46974f49fc6..a086270ffd5 100644 --- a/src/plugins/coreplugin/editormanager/editorview.cpp +++ b/src/plugins/coreplugin/editormanager/editorview.cpp @@ -39,14 +39,16 @@ namespace Core::Internal { // EditorView -EditorView::EditorView(SplitterOrView *parentSplitterOrView, QWidget *parent) : - QWidget(parent), - m_parentSplitterOrView(parentSplitterOrView), - m_toolBar(new EditorToolBar(this)), - m_container(new QStackedWidget(this)), - m_infoBarDisplay(new InfoBarDisplay(this)), - m_statusHLine(Layouting::createHr(this)), - m_statusWidget(new QFrame(this)) +EditorView::EditorView(SplitterOrView *parentSplitterOrView, QWidget *parent) + : QWidget(parent) + , m_parentSplitterOrView(parentSplitterOrView) + , m_toolBar(new EditorToolBar(this)) + , m_container(new QStackedWidget(this)) + , m_infoBarDisplay(new InfoBarDisplay(this)) + , m_statusHLine(Layouting::createHr(this)) + , m_statusWidget(new QFrame(this)) + , m_backMenu(new QMenu(this)) + , m_forwardMenu(new QMenu(this)) { auto tl = new QVBoxLayout(this); tl->setSpacing(0); @@ -67,6 +69,8 @@ EditorView::EditorView(SplitterOrView *parentSplitterOrView, QWidget *parent) : connect(m_toolBar, &EditorToolBar::splitNewWindowClicked, this, &EditorView::splitNewWindow); connect(m_toolBar, &EditorToolBar::closeSplitClicked, this, &EditorView::closeSplit); m_toolBar->setMenuProvider([this](QMenu *menu) { fillListContextMenu(menu); }); + m_toolBar->setGoBackMenu(m_backMenu); + m_toolBar->setGoForwardMenu(m_forwardMenu); tl->addWidget(m_toolBar); } @@ -509,6 +513,35 @@ void EditorView::cutForwardNavigationHistory() void EditorView::updateNavigatorActions() { + static const int MAX_ITEMS = 20; + FilePath last; + m_backMenu->clear(); + int count = 0; + for (int i = m_currentNavigationHistoryPosition - 1; i >= 0; i--) { + const EditLocation &loc = m_navigationHistory.at(i); + if (loc.filePath != last) { + m_backMenu->addAction(loc.displayName(), this, [this, i] { goToNavigationHistory(i); }); + last = loc.filePath; + ++count; + if (count >= MAX_ITEMS) + break; + } + } + last = {}; + m_forwardMenu->clear(); + count = 0; + for (int i = m_currentNavigationHistoryPosition + 1; i < m_navigationHistory.size(); i++) { + const EditLocation &loc = m_navigationHistory.at(i); + if (loc.filePath != last) { + m_forwardMenu->addAction(loc.displayName(), this, [this, i] { + goToNavigationHistory(i); + }); + last = loc.filePath; + ++count; + if (count >= MAX_ITEMS) + break; + } + } m_toolBar->setCanGoBack(canGoBack()); m_toolBar->setCanGoForward(canGoForward()); } @@ -544,31 +577,45 @@ static bool fileNameWasRemoved(const FilePath &filePath) return !filePath.isEmpty() && !filePath.exists(); } +bool EditorView::openEditorFromNavigationHistory(int index) +{ + EditLocation location = m_navigationHistory.at(index); + IEditor *editor = nullptr; + if (location.document) { + editor = EditorManagerPrivate::activateEditorForDocument( + this, location.document, EditorManager::IgnoreNavigationHistory); + } + if (!editor) { + if (fileNameWasRemoved(location.filePath)) + return false; + editor = EditorManagerPrivate::openEditor( + this, location.filePath, location.id, EditorManager::IgnoreNavigationHistory); + if (!editor) + return false; + } + editor->restoreState(location.state); + return true; +} + +void EditorView::goToNavigationHistory(int index) +{ + if (index >= m_navigationHistory.size()) + return; + updateCurrentPositionInNavigationHistory(); + if (!openEditorFromNavigationHistory(index)) + m_navigationHistory.removeAt(index); + m_currentNavigationHistoryPosition = index; + updateNavigatorActions(); +} + void EditorView::goBackInNavigationHistory() { updateCurrentPositionInNavigationHistory(); while (m_currentNavigationHistoryPosition > 0) { --m_currentNavigationHistoryPosition; - EditLocation location = m_navigationHistory.at(m_currentNavigationHistoryPosition); - IEditor *editor = nullptr; - if (location.document) { - editor = EditorManagerPrivate::activateEditorForDocument(this, location.document, - EditorManager::IgnoreNavigationHistory); - } - if (!editor) { - if (fileNameWasRemoved(location.filePath)) { - m_navigationHistory.removeAt(m_currentNavigationHistoryPosition); - continue; - } - editor = EditorManagerPrivate::openEditor(this, location.filePath, location.id, - EditorManager::IgnoreNavigationHistory); - if (!editor) { - m_navigationHistory.removeAt(m_currentNavigationHistoryPosition); - continue; - } - } - editor->restoreState(location.state); - break; + if (openEditorFromNavigationHistory(m_currentNavigationHistoryPosition)) + break; + m_navigationHistory.removeAt(m_currentNavigationHistoryPosition); } updateNavigatorActions(); } @@ -580,26 +627,9 @@ void EditorView::goForwardInNavigationHistory() return; ++m_currentNavigationHistoryPosition; while (m_currentNavigationHistoryPosition < m_navigationHistory.size()) { - IEditor *editor = nullptr; - EditLocation location = m_navigationHistory.at(m_currentNavigationHistoryPosition); - if (location.document) { - editor = EditorManagerPrivate::activateEditorForDocument(this, location.document, - EditorManager::IgnoreNavigationHistory); - } - if (!editor) { - if (fileNameWasRemoved(location.filePath)) { - m_navigationHistory.removeAt(m_currentNavigationHistoryPosition); - continue; - } - editor = EditorManagerPrivate::openEditor(this, location.filePath, location.id, - EditorManager::IgnoreNavigationHistory); - if (!editor) { - m_navigationHistory.removeAt(m_currentNavigationHistoryPosition); - continue; - } - } - editor->restoreState(location.state); - break; + if (openEditorFromNavigationHistory(m_currentNavigationHistoryPosition)) + break; + m_navigationHistory.removeAt(m_currentNavigationHistoryPosition); } if (m_currentNavigationHistoryPosition >= m_navigationHistory.size()) m_currentNavigationHistoryPosition = qMax(m_navigationHistory.size() - 1, 0); @@ -1024,4 +1054,11 @@ EditLocation EditLocation::forEditor(const IEditor *editor, const QByteArray &sa return location; } +QString EditLocation::displayName() const +{ + if (document) + return document->displayName(); + return filePath.fileName(); +} + } // Core::Internal diff --git a/src/plugins/coreplugin/editormanager/editorview.h b/src/plugins/coreplugin/editormanager/editorview.h index 6694559792c..28db4f533c5 100644 --- a/src/plugins/coreplugin/editormanager/editorview.h +++ b/src/plugins/coreplugin/editormanager/editorview.h @@ -42,6 +42,8 @@ public: static EditLocation load(const QByteArray &data); static EditLocation forEditor(const IEditor *editor, const QByteArray &saveState = {}); + QString displayName() const; + QPointer document; Utils::FilePath filePath; Utils::Id id; @@ -125,6 +127,8 @@ private: void checkProjectLoaded(IEditor *editor); void updateCurrentPositionInNavigationHistory(); + bool openEditorFromNavigationHistory(int index); + void goToNavigationHistory(int index); SplitterOrView *m_parentSplitterOrView; EditorToolBar *m_toolBar; @@ -141,6 +145,8 @@ private: QLabel *m_emptyViewLabel; QList m_navigationHistory; + QMenu *m_backMenu; + QMenu *m_forwardMenu; QList m_editorHistory; int m_currentNavigationHistoryPosition = 0; }; diff --git a/src/plugins/coreplugin/editortoolbar.cpp b/src/plugins/coreplugin/editortoolbar.cpp index ee4d912d85c..d55ee7d6947 100644 --- a/src/plugins/coreplugin/editortoolbar.cpp +++ b/src/plugins/coreplugin/editortoolbar.cpp @@ -347,6 +347,16 @@ void EditorToolBar::setCanGoForward(bool canGoForward) d->m_goForwardAction->setEnabled(canGoForward); } +void EditorToolBar::setGoBackMenu(QMenu *menu) +{ + d->m_backButton->setMenu(menu); +} + +void EditorToolBar::setGoForwardMenu(QMenu *menu) +{ + d->m_forwardButton->setMenu(menu); +} + void EditorToolBar::updateActionShortcuts() { d->m_closeEditorButton->setToolTip(ActionManager::command(Constants::CLOSE)->stringWithAppendedShortcut(Tr::tr("Close Document"))); diff --git a/src/plugins/coreplugin/editortoolbar.h b/src/plugins/coreplugin/editortoolbar.h index a2aa089da7c..2e882227312 100644 --- a/src/plugins/coreplugin/editortoolbar.h +++ b/src/plugins/coreplugin/editortoolbar.h @@ -56,6 +56,8 @@ public: void setNavigationVisible(bool isVisible); void setCanGoBack(bool canGoBack); void setCanGoForward(bool canGoForward); + void setGoBackMenu(QMenu *menu); + void setGoForwardMenu(QMenu *menu); void removeToolbarForEditor(IEditor *editor); void setCloseSplitEnabled(bool enable); void setCloseSplitIcon(const QIcon &icon);