From f16d0c4d65be56694adc8fe8ebf1ae83ddbab426 Mon Sep 17 00:00:00 2001 From: mae <qt-info@nokia.com> Date: Fri, 17 Jul 2009 18:08:59 +0200 Subject: [PATCH] imlemented per-view edit location navigation --- .../editormanager/editormanager.cpp | 171 +++++------------- .../coreplugin/editormanager/editormanager.h | 8 +- .../coreplugin/editormanager/editorview.cpp | 141 +++++++++++++-- .../coreplugin/editormanager/editorview.h | 25 +++ src/plugins/help/helpplugin.cpp | 4 +- src/plugins/texteditor/basetexteditor.cpp | 2 +- 6 files changed, 209 insertions(+), 142 deletions(-) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 73943eb29ba..0f387d1ac4d 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -132,13 +132,13 @@ EditorManagerPlaceHolder* EditorManagerPlaceHolder::current() // ---------------- EditorManager namespace Core { + +//struct EditorHistoryItem { +// IFile *file; +// QPointer<Internal::EditorView> view; +//}; + struct EditorManagerPrivate { - struct EditLocation { - QPointer<IEditor> editor; - QString fileName; - QString kind; - QVariant state; - }; explicit EditorManagerPrivate(ICore *core, QWidget *parent); ~EditorManagerPrivate(); Internal::EditorView *m_view; @@ -168,12 +168,7 @@ struct EditorManagerPrivate { QAction *m_gotoOtherSplitAction; QList<IEditor *> m_editorHistory; - QList<EditLocation *> m_navigationHistory; - void clearNavigationHistory() { - qDeleteAll(m_navigationHistory); - m_navigationHistory.clear(); - } - int currentNavigationHistoryPosition; + Internal::OpenEditorsWindow *m_windowPopup; Core::BaseView *m_openEditorsView; Internal::EditorClosingCoreListener *m_coreListener; @@ -203,10 +198,9 @@ EditorManagerPrivate::EditorManagerPrivate(ICore *core, QWidget *parent) : m_closeOtherEditorsAction(new QAction(EditorManager::tr("Close Others"), parent)), m_gotoNextDocHistoryAction(new QAction(EditorManager::tr("Next Document in History"), parent)), m_gotoPreviousDocHistoryAction(new QAction(EditorManager::tr("Previous Document in History"), parent)), - m_goBackAction(new QAction(EditorManager::tr("Go Back"), parent)), - m_goForwardAction(new QAction(EditorManager::tr("Go Forward"), parent)), + m_goBackAction(new QAction(QIcon(QLatin1String(":/help/images/previous.png")), EditorManager::tr("Go Back"), parent)), + m_goForwardAction(new QAction(QIcon(QLatin1String(":/help/images/next.png")), EditorManager::tr("Go Forward"), parent)), m_openInExternalEditorAction(new QAction(EditorManager::tr("Open in External Editor"), parent)), - currentNavigationHistoryPosition(0), m_windowPopup(0), m_coreListener(0), m_reloadBehavior(IFile::AskForReload) @@ -216,7 +210,7 @@ EditorManagerPrivate::EditorManagerPrivate(ICore *core, QWidget *parent) : EditorManagerPrivate::~EditorManagerPrivate() { - clearNavigationHistory(); +// clearNavigationHistory(); } EditorManager *EditorManager::m_instance = 0; @@ -553,6 +547,16 @@ QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) cons return found; } +QList<IEditor *> EditorManager::editorsForFile(IFile *file) const +{ + QList<IEditor *> found; + foreach (IEditor *editor, openedEditors()) { + if (editor->file() == file) + found << editor; + } + return found; +} + IEditor *EditorManager::currentEditor() const { return m_d->m_currentEditor; @@ -647,7 +651,7 @@ bool EditorManager::closeAllEditors(bool askAboutModifiedEditors) { m_d->m_editorModel->removeAllRestoredEditors(); if (closeEditors(openedEditors(), askAboutModifiedEditors)) { - m_d->clearNavigationHistory(); +// m_d->clearNavigationHistory(); return true; } return false; @@ -851,12 +855,10 @@ Core::IEditor *EditorManager::activateEditor(const QModelIndex &index, Internal: if (editor) { return activateEditor(view, editor, flags); } - if (view) - setCurrentView(m_d->m_splitter->findView(view)); QString fileName = index.data(Qt::UserRole + 1).toString(); QByteArray kind = index.data(Qt::UserRole + 2).toByteArray(); - return openEditor(fileName, kind, flags); + return openEditor(view, fileName, kind, flags); } Core::IEditor *EditorManager::placeEditor(Core::Internal::EditorView *view, Core::IEditor *editor) @@ -914,6 +916,13 @@ Core::IEditor *EditorManager::activateEditor(Core::Internal::EditorView *view, C return editor; } +Core::IEditor *EditorManager::activateEditor(Core::Internal::EditorView *view, Core::IFile *file, OpenEditorFlags flags) +{ + QList<IEditor*> editors = editorsForFile(file); + Q_ASSERT(!editors.isEmpty()); + return activateEditor(view, editors.first(), flags); +} + /* For something that has a 'QStringList mimeTypes' (IEditorFactory * or IExternalEditor), find the one best matching the mimetype passed in. * Recurse over the parent classes of the mimetype to find them. */ @@ -1118,6 +1127,12 @@ static QString formatFileFilters(const Core::ICore *core, QString *selectedFilte IEditor *EditorManager::openEditor(const QString &fileName, const QString &editorKind, EditorManager::OpenEditorFlags flags) +{ + return openEditor(0, fileName, editorKind, flags); +} + +IEditor *EditorManager::openEditor(Core::Internal::EditorView *view, const QString &fileName, + const QString &editorKind, EditorManager::OpenEditorFlags flags) { if (debugEditorManager) qDebug() << Q_FUNC_INFO << fileName << editorKind; @@ -1142,7 +1157,7 @@ IEditor *EditorManager::openEditor(const QString &fileName, const QString &edito restoreEditorState(editor); QApplication::restoreOverrideCursor(); - return activateEditor(editor, flags); + return activateEditor(view, editor, flags); } bool EditorManager::openExternalEditor(const QString &fileName, const QString &editorKind) @@ -1476,8 +1491,9 @@ void EditorManager::updateActions() m_d->m_gotoNextDocHistoryAction->setEnabled(m_d->m_editorHistory.count() > 0); m_d->m_gotoPreviousDocHistoryAction->setEnabled(m_d->m_editorHistory.count() > 0); - m_d->m_goBackAction->setEnabled(m_d->currentNavigationHistoryPosition > 0); - m_d->m_goForwardAction->setEnabled(m_d->currentNavigationHistoryPosition < m_d->m_navigationHistory.size()-1); + EditorView *view = currentEditorView(); + m_d->m_goBackAction->setEnabled(view->canGoBack()); + m_d->m_goForwardAction->setEnabled(view->canGoForward()); bool hasSplitter = m_d->m_splitter->isSplitter(); m_d->m_removeCurrentSplitAction->setEnabled(hasSplitter); @@ -1497,121 +1513,28 @@ OpenEditorsModel *EditorManager::openedEditorsModel() const return m_d->m_editorModel; } - QList<IEditor*> EditorManager::editorHistory() const { return m_d->m_editorHistory; } -void EditorManager::addCurrentPositionToNavigationHistory(const QByteArray &saveState, bool compress) +void EditorManager::addCurrentPositionToNavigationHistory(IEditor *editor, const QByteArray &saveState) { - IEditor *editor = currentEditor(); - if (!editor) - return; - if (!editor->file()) - return; - - QString fileName = editor->file()->fileName(); - QByteArray state; - if (saveState.isNull()) { - state = editor->saveState(); - } else { - state = saveState; - } - // cut existing - int firstIndexToRemove; - if (compress && m_d->currentNavigationHistoryPosition > 0) { - EditorManagerPrivate::EditLocation *previousLocation = - m_d->m_navigationHistory.at(m_d->currentNavigationHistoryPosition-1); - if ((previousLocation->editor && editor == previousLocation->editor) - || (!fileName.isEmpty() && previousLocation->fileName == fileName)) { - firstIndexToRemove = m_d->currentNavigationHistoryPosition-1; - } else { - firstIndexToRemove = m_d->currentNavigationHistoryPosition; - } - } else { - firstIndexToRemove = m_d->currentNavigationHistoryPosition; - } - if (firstIndexToRemove >= 0) { - for (int i = m_d->m_navigationHistory.size()-1; i >= firstIndexToRemove; --i) { - delete m_d->m_navigationHistory.takeLast(); - } - } - while (m_d->m_navigationHistory.size() >= 30) { - delete m_d->m_navigationHistory.takeFirst(); - } - EditorManagerPrivate::EditLocation *location = new EditorManagerPrivate::EditLocation; - location->editor = editor; - location->fileName = editor->file()->fileName(); - location->kind = editor->kind(); - location->state = QVariant(state); - m_d->m_navigationHistory.append(location); - m_d->currentNavigationHistoryPosition = m_d->m_navigationHistory.size(); + currentView()->view()->addCurrentPositionToNavigationHistory(editor, saveState); updateActions(); } -void EditorManager::updateCurrentPositionInNavigationHistory() -{ - if (!m_d->m_currentEditor || !m_d->m_currentEditor->file()) - return; - - EditorManagerPrivate::EditLocation *location; - if (m_d->currentNavigationHistoryPosition < m_d->m_navigationHistory.size()) { - location = m_d->m_navigationHistory[m_d->currentNavigationHistoryPosition]; - } else { - location = new EditorManagerPrivate::EditLocation; - m_d->m_navigationHistory.append(location); - } - location->editor = m_d->m_currentEditor; - location->fileName = m_d->m_currentEditor->file()->fileName(); - location->kind = m_d->m_currentEditor->kind(); - location->state = QVariant(m_d->m_currentEditor->saveState()); -} - void EditorManager::goBackInNavigationHistory() { - updateCurrentPositionInNavigationHistory(); - while (m_d->currentNavigationHistoryPosition > 0) { - --m_d->currentNavigationHistoryPosition; - EditorManagerPrivate::EditLocation *location = m_d->m_navigationHistory.at(m_d->currentNavigationHistoryPosition); - IEditor *editor; - if (location->editor) { - editor = location->editor; - activateEditor(location->editor, IgnoreNavigationHistory); - } else { - editor = openEditor(location->fileName, location->kind, IgnoreNavigationHistory); - if (!editor) { - delete m_d->m_navigationHistory.takeAt(m_d->currentNavigationHistoryPosition); - continue; - } - } - editor->restoreState(location->state.toByteArray()); - updateActions(); - ensureEditorManagerVisible(); - return; - } + currentView()->view()->goBackInNavigationHistory(); + updateActions(); + ensureEditorManagerVisible(); + return; } void EditorManager::goForwardInNavigationHistory() { - updateCurrentPositionInNavigationHistory(); - if (m_d->currentNavigationHistoryPosition >= m_d->m_navigationHistory.size()-1) - return; - ++m_d->currentNavigationHistoryPosition; - EditorManagerPrivate::EditLocation *location = m_d->m_navigationHistory.at(m_d->currentNavigationHistoryPosition); - IEditor *editor; - if (location->editor) { - editor = location->editor; - activateEditor(location->editor, IgnoreNavigationHistory); - } else { - editor = openEditor(location->fileName, location->kind, IgnoreNavigationHistory); - if (!editor) { - //TODO - qDebug() << Q_FUNC_INFO << "can't open file" << location->fileName; - return; - } - } - editor->restoreState(location->state.toByteArray()); + currentView()->view()->goForwardInNavigationHistory(); updateActions(); ensureEditorManagerVisible(); } @@ -2006,7 +1929,7 @@ void EditorManager::gotoOtherSplit() view = m_d->m_splitter->findFirstView(); if (view) { if (IEditor *editor = view->editor()) { - setCurrentEditor(editor); + setCurrentEditor(editor, true); editor->widget()->setFocus(); } else { setCurrentView(view); diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h index 8bb8d0439af..1da33f80aa1 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -122,6 +122,7 @@ public: const QString &contents = QString()); bool hasEditor(const QString &fileName) const; QList<IEditor *> editorsForFileName(const QString &filename) const; + QList<IEditor *> editorsForFile(IFile *file) const; IEditor *currentEditor() const; IEditor *activateEditor(IEditor *editor, OpenEditorFlags flags = 0); @@ -136,7 +137,7 @@ public: QList<IEditor*> editorsForFiles(QList<IFile*> files) const; //QList<EditorGroup *> editorGroups() const; QList<IEditor*> editorHistory() const; - void addCurrentPositionToNavigationHistory(const QByteArray &saveState = QByteArray(), bool compress = false); + void addCurrentPositionToNavigationHistory(IEditor *editor = 0, const QByteArray &saveState = QByteArray()); bool saveEditor(IEditor *editor); @@ -238,6 +239,10 @@ private: void setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory = false); void setCurrentView(Core::Internal::SplitterOrView *view); IEditor *activateEditor(Core::Internal::EditorView *view, Core::IEditor *editor, OpenEditorFlags flags = 0); + IEditor *activateEditor(Core::Internal::EditorView *view, Core::IFile*file, OpenEditorFlags flags = 0); + IEditor *openEditor(Core::Internal::EditorView *view, const QString &fileName, + const QString &editorKind = QString(), + OpenEditorFlags flags = 0); Core::Internal::SplitterOrView *currentView() const; void closeEditor(Core::IEditor *editor); void closeDuplicate(Core::IEditor *editor); @@ -246,7 +251,6 @@ private: Core::Internal::EditorView *currentEditorView(); IEditor *pickUnusedEditor() const; - void updateCurrentPositionInNavigationHistory(); static EditorManager *m_instance; EditorManagerPrivate *m_d; diff --git a/src/plugins/coreplugin/editormanager/editorview.cpp b/src/plugins/coreplugin/editormanager/editorview.cpp index 4d952fd18e4..fab27321e5e 100644 --- a/src/plugins/coreplugin/editormanager/editorview.cpp +++ b/src/plugins/coreplugin/editormanager/editorview.cpp @@ -78,7 +78,8 @@ EditorView::EditorView(OpenEditorsModel *model, QWidget *parent) : m_infoWidget(new QFrame(this)), m_editorForInfoWidget(0), m_statusHLine(new QFrame(this)), - m_statusWidget(new QFrame(this)) + m_statusWidget(new QFrame(this)), + m_currentNavigationHistoryPosition(0) { QVBoxLayout *tl = new QVBoxLayout(this); tl->setSpacing(0); @@ -412,6 +413,119 @@ void EditorView::listContextMenu(QPoint pos) } } +void EditorView::addCurrentPositionToNavigationHistory(IEditor *editor, const QByteArray &saveState) +{ + if (editor && editor != currentEditor()) { + qDebug() << Q_FUNC_INFO << "this should not happen!"; + return; + } + if (!editor) + editor = currentEditor(); + if (!editor) + return; + IFile *file = editor->file(); + + if (!file) + return; + + QString fileName = file->fileName(); + QByteArray state; + if (saveState.isNull()) { + state = editor->saveState(); + } else { + state = saveState; + } + + EditLocation *location = new EditLocation; + location->file = file; + location->fileName = file->fileName(); + location->kind = editor->kind(); + location->state = QVariant(state); + m_currentNavigationHistoryPosition = qMin(m_currentNavigationHistoryPosition, m_navigationHistory.size()); // paranoia + m_navigationHistory.insert(m_currentNavigationHistoryPosition, location); + ++m_currentNavigationHistoryPosition; + + while (m_navigationHistory.size() >= 30) { + if (m_currentNavigationHistoryPosition > 15) { + delete m_navigationHistory.takeFirst(); + --m_currentNavigationHistoryPosition; + } else { + delete m_navigationHistory.takeLast(); + } + } +} + +void EditorView::copyNavigationHistoryFrom(EditorView* other) +{ + m_currentNavigationHistoryPosition = other->m_currentNavigationHistoryPosition; + m_navigationHistory = other->m_navigationHistory; +} + +void EditorView::updateCurrentPositionInNavigationHistory() +{ + IEditor *editor = currentEditor(); + if (!editor || !editor->file()) + return; + + IFile *file = editor->file(); + EditLocation *location; + if (m_currentNavigationHistoryPosition < m_navigationHistory.size()) { + location = m_navigationHistory[m_currentNavigationHistoryPosition]; + } else { + location = new EditLocation; + m_navigationHistory.append(location); + } + location->file = file; + location->fileName = file->fileName(); + location->kind = editor->kind(); + location->state = QVariant(editor->saveState()); +} + +void EditorView::goBackInNavigationHistory() +{ + EditorManager *em = CoreImpl::instance()->editorManager(); + updateCurrentPositionInNavigationHistory(); + while (m_currentNavigationHistoryPosition > 0) { + --m_currentNavigationHistoryPosition; + EditLocation *location = m_navigationHistory.at(m_currentNavigationHistoryPosition); + IEditor *editor; + if (location->file) { + editor = em->activateEditor(this, location->file, EditorManager::IgnoreNavigationHistory); + } else { + editor = em->openEditor(this, location->fileName, location->kind, EditorManager::IgnoreNavigationHistory); + if (!editor) { + delete m_navigationHistory.takeAt(m_currentNavigationHistoryPosition); + continue; + } + } + editor->restoreState(location->state.toByteArray()); + break; + } +} + +void EditorView::goForwardInNavigationHistory() +{ + EditorManager *em = CoreImpl::instance()->editorManager(); + updateCurrentPositionInNavigationHistory(); + if (m_currentNavigationHistoryPosition >= m_navigationHistory.size()-1) + return; + ++m_currentNavigationHistoryPosition; + EditLocation *location = m_navigationHistory.at(m_currentNavigationHistoryPosition); + IEditor *editor; + if (location->file) { + editor = em->activateEditor(this, location->file, EditorManager::IgnoreNavigationHistory); + } else { + editor = em->openEditor(this, location->fileName, location->kind, EditorManager::IgnoreNavigationHistory); + if (!editor) { + //TODO + qDebug() << Q_FUNC_INFO << "can't open file" << location->fileName; + return; + } + } + editor->restoreState(location->state.toByteArray()); +} + + SplitterOrView::SplitterOrView(OpenEditorsModel *model) { Q_ASSERT(model); @@ -641,36 +755,37 @@ void SplitterOrView::split(Qt::Orientation orientation) Core::IEditor *e = m_view->currentEditor(); SplitterOrView *view = 0; + SplitterOrView *otherView = 0; if (e) { m_view->removeEditor(e); - m_splitter->addWidget(new SplitterOrView(e)); -#if 1 + m_splitter->addWidget((view = new SplitterOrView(e))); if (e->duplicateSupported()) { Core::IEditor *duplicate = em->duplicateEditor(e); - m_splitter->addWidget(new SplitterOrView(duplicate)); + m_splitter->addWidget((otherView = new SplitterOrView(duplicate))); } else { - m_splitter->addWidget(new SplitterOrView()); + m_splitter->addWidget((otherView = new SplitterOrView())); } -#else - m_splitter->addWidget((view = new SplitterOrView())); -#endif } else { - m_splitter->addWidget(new SplitterOrView()); + m_splitter->addWidget((otherView = new SplitterOrView())); m_splitter->addWidget((view = new SplitterOrView())); } m_layout->setCurrentWidget(m_splitter); + view->view()->copyNavigationHistoryFrom(m_view); + otherView->view()->copyNavigationHistoryFrom(m_view); + if (m_view && !m_isRoot) { em->emptyView(m_view); delete m_view; m_view = 0; } - em->setCurrentView(view); if (e) - em->activateEditor(e); + em->activateEditor(view->view(), e); + else + em->setCurrentView(view); } void SplitterOrView::unsplitAll() @@ -715,6 +830,7 @@ void SplitterOrView::unsplit() EditorView *childView = childSplitterOrView->view(); Q_ASSERT(childView); if (m_view) { + m_view->copyNavigationHistoryFrom(childView); if (IEditor *e = childView->currentEditor()) { childView->removeEditor(e); m_view->addEditor(e); @@ -779,8 +895,7 @@ void SplitterOrView::restoreState(const QByteArray &state) QByteArray kind; QByteArray editorState; stream >> fileName >> kind >> editorState; - em->setCurrentView(this); - IEditor *e = em->openEditor(fileName, kind, Core::EditorManager::IgnoreNavigationHistory + IEditor *e = em->openEditor(view(), fileName, kind, Core::EditorManager::IgnoreNavigationHistory | Core::EditorManager::NoActivate); if (!e) { diff --git a/src/plugins/coreplugin/editormanager/editorview.h b/src/plugins/coreplugin/editormanager/editorview.h index 996ec8df944..343c4e073f9 100644 --- a/src/plugins/coreplugin/editormanager/editorview.h +++ b/src/plugins/coreplugin/editormanager/editorview.h @@ -38,8 +38,10 @@ #include <QtGui/QAction> #include <QtGui/QSplitter> #include <QtGui/QStackedLayout> +#include <QtCore/QPointer> #include <coreplugin/icontext.h> +#include <coreplugin/ifile.h> #include <QtCore/QMap> #include <QtGui/QSortFilterProxyModel> @@ -58,6 +60,12 @@ class OpenEditorsModel; namespace Internal { + struct EditLocation { + QPointer<IFile> file; + QString fileName; + QString kind; + QVariant state; + }; class EditorView : public QWidget { @@ -122,6 +130,23 @@ private: QToolButton *m_statusWidgetButton; QList<IEditor *> m_editors; QMap<QWidget *, IEditor *> m_widgetEditorMap; + + QList<EditLocation *> m_navigationHistory; + void clearNavigationHistory() { + qDeleteAll(m_navigationHistory); + m_navigationHistory.clear(); + } + int m_currentNavigationHistoryPosition; + void updateCurrentPositionInNavigationHistory(); + +public: + inline bool canGoForward() const { return m_currentNavigationHistoryPosition < m_navigationHistory.size()-1; } + inline bool canGoBack() const { return m_currentNavigationHistoryPosition > 0; } + void goBackInNavigationHistory(); + void goForwardInNavigationHistory(); + void addCurrentPositionToNavigationHistory(IEditor *editor = 0, const QByteArray &saveState = QByteArray()); + + void copyNavigationHistoryFrom(EditorView* other); }; class SplitterOrView : public QWidget diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp index 295e59fae29..c48c7fe02c2 100644 --- a/src/plugins/help/helpplugin.cpp +++ b/src/plugins/help/helpplugin.cpp @@ -213,13 +213,13 @@ bool HelpPlugin::initialize(const QStringList &arguments, QString *error) QAction *previousAction = new QAction(QIcon(QLatin1String(":/help/images/previous.png")), - tr("Previous"), this); + tr("Previous Page"), this); cmd = am->registerAction(previousAction, QLatin1String("Help.Previous"), modecontext); cmd->setDefaultKeySequence(QKeySequence::Back); QAction *nextAction = - new QAction(QIcon(QLatin1String(":/help/images/next.png")), tr("Next"), + new QAction(QIcon(QLatin1String(":/help/images/next.png")), tr("Next Page"), this); cmd = am->registerAction(nextAction, QLatin1String("Help.Next"), modecontext); cmd->setDefaultKeySequence(QKeySequence::Forward); diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index c53d617d7af..bf736aa962f 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -2601,7 +2601,7 @@ void BaseTextEditor::updateCurrentLineHighlight() void BaseTextEditor::slotCursorPositionChanged() { if (!d->m_contentsChanged && d->m_lastCursorChangeWasInteresting) { - Core::EditorManager::instance()->addCurrentPositionToNavigationHistory(d->m_tempNavigationState); + Core::EditorManager::instance()->addCurrentPositionToNavigationHistory(editableInterface(), d->m_tempNavigationState); d->m_lastCursorChangeWasInteresting = false; } else if (d->m_contentsChanged) { saveCurrentCursorPositionForNavigation(); -- GitLab