From 2649a49209d3a8f6d8b88f0246c121bb3c01cdeb Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 8 May 2024 14:21:16 +0200 Subject: [PATCH] Editors: Add menus for back/forward buttons Add menus to the back and forward buttons in the editor tool bar, that show history the history. Limited to one entry per consecutive same file path, because we currently don't have the means to visually distinguish multiple locations in the same file. Fixes: QTCREATORBUG-347 Change-Id: I69c5cfaf4c12ec8b59f98eb692c799babca0458a Reviewed-by: David Schulz Reviewed-by: --- .../coreplugin/editormanager/editorview.cpp | 133 +++++++++++------- .../coreplugin/editormanager/editorview.h | 6 + src/plugins/coreplugin/editortoolbar.cpp | 10 ++ src/plugins/coreplugin/editortoolbar.h | 2 + 4 files changed, 103 insertions(+), 48 deletions(-) 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);