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 <david.schulz@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Eike Ziller
2024-05-08 14:21:16 +02:00
parent eaefe4bf30
commit 2649a49209
4 changed files with 103 additions and 48 deletions

View File

@@ -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<int>(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

View File

@@ -42,6 +42,8 @@ public:
static EditLocation load(const QByteArray &data);
static EditLocation forEditor(const IEditor *editor, const QByteArray &saveState = {});
QString displayName() const;
QPointer<IDocument> 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<EditLocation> m_navigationHistory;
QMenu *m_backMenu;
QMenu *m_forwardMenu;
QList<EditLocation> m_editorHistory;
int m_currentNavigationHistoryPosition = 0;
};

View File

@@ -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")));

View File

@@ -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);