diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 73943eb29ba5e27705315f48e75dd19460167bd8..e3f8f164ad5ca63eebbf6554b1bf3d56c84f5601 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -132,13 +132,9 @@ EditorManagerPlaceHolder* EditorManagerPlaceHolder::current() // ---------------- EditorManager namespace Core { + + struct EditorManagerPrivate { - struct EditLocation { - QPointer<IEditor> editor; - QString fileName; - QString kind; - QVariant state; - }; explicit EditorManagerPrivate(ICore *core, QWidget *parent); ~EditorManagerPrivate(); Internal::EditorView *m_view; @@ -167,13 +163,6 @@ struct EditorManagerPrivate { QAction *m_removeAllSplitsAction; 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; @@ -201,12 +190,11 @@ EditorManagerPrivate::EditorManagerPrivate(ICore *core, QWidget *parent) : m_closeCurrentEditorAction(new QAction(EditorManager::tr("Close"), parent)), m_closeAllEditorsAction(new QAction(EditorManager::tr("Close All"), 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_gotoNextDocHistoryAction(new QAction(EditorManager::tr("Next Open Document in History"), parent)), + m_gotoPreviousDocHistoryAction(new QAction(EditorManager::tr("Previous Open Document in History"), 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 +204,7 @@ EditorManagerPrivate::EditorManagerPrivate(ICore *core, QWidget *parent) : EditorManagerPrivate::~EditorManagerPrivate() { - clearNavigationHistory(); +// clearNavigationHistory(); } EditorManager *EditorManager::m_instance = 0; @@ -461,15 +449,6 @@ QString EditorManager::defaultExternalEditor() const #endif } -void EditorManager::updateEditorHistory() -{ - IEditor *editor = currentEditor(); - if (!editor) - return; - m_d->m_editorHistory.removeAll(editor); - m_d->m_editorHistory.prepend(editor); -} - void EditorManager::removeEditor(IEditor *editor) { bool isDuplicate = m_d->m_editorModel->isDuplicate(editor); @@ -477,9 +456,7 @@ void EditorManager::removeEditor(IEditor *editor) if (!isDuplicate) { m_d->m_core->fileManager()->removeFile(editor->file()); } - m_d->m_editorHistory.removeAll(editor); m_d->m_core->removeContextObject(editor); - } void EditorManager::handleContextChange(Core::IContext *context) @@ -508,9 +485,9 @@ void EditorManager::setCurrentEditor(IEditor *editor, bool ignoreNavigationHisto if (editor) { if (SplitterOrView *splitterOrView = m_d->m_splitter->findView(editor)) splitterOrView->view()->setCurrentEditor(editor); + m_d->m_view->updateEditorHistory(editor); // the global view should have a complete history } updateActions(); - updateEditorHistory(); emit currentEditorChanged(editor); } @@ -539,6 +516,8 @@ Core::Internal::SplitterOrView *EditorManager::currentView() const view = m_d->m_currentEditor? m_d->m_splitter->findView(m_d->m_currentEditor): m_d->m_splitter->findFirstView(); + if (!view) + return m_d->m_splitter; return view; } @@ -553,6 +532,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; @@ -612,7 +601,6 @@ void EditorManager::closeView(Core::Internal::EditorView *view) else setCurrentView(newCurrent); } - updateEditorHistory(); } QList<IEditor*> @@ -647,7 +635,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; @@ -836,7 +824,7 @@ void EditorManager::closeDuplicate(Core::IEditor *editor) Core::IEditor *EditorManager::pickUnusedEditor() const { - foreach (IEditor *editor, m_d->m_editorHistory) { + foreach (IEditor *editor, openedEditors()) { SplitterOrView *view = m_d->m_splitter->findView(editor); if (!view || view->editor() != editor) return editor; @@ -844,24 +832,25 @@ Core::IEditor *EditorManager::pickUnusedEditor() const return 0; } - Core::IEditor *EditorManager::activateEditor(const QModelIndex &index, Internal::EditorView *view, OpenEditorFlags flags) { IEditor *editor = index.data(Qt::UserRole).value<IEditor*>(); 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) { - Q_ASSERT(view && editor) ; + Q_ASSERT(view && editor); + + if (view->currentEditor() && view->currentEditor()->file() == editor->file()) + editor = view->currentEditor(); + if (!view->hasEditor(editor)) { bool duplicateSupported = editor->duplicateSupported(); if (SplitterOrView *sourceView = m_d->m_splitter->findView(editor)) { @@ -914,6 +903,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. */ @@ -1034,10 +1030,6 @@ void EditorManager::addEditor(IEditor *editor, bool isDuplicate) m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName()); } } - - m_d->m_editorHistory.removeAll(editor); - m_d->m_editorHistory.prepend(editor); - emit editorOpened(editor); } @@ -1118,6 +1110,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; @@ -1127,7 +1125,7 @@ IEditor *EditorManager::openEditor(const QString &fileName, const QString &edito const QList<IEditor *> editors = editorsForFileName(fileName); if (!editors.isEmpty()) { - return activateEditor(editors.first(), flags); + return activateEditor(view, editors.first(), flags); } QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); IEditor *editor = createEditor(editorKind, fileName); @@ -1142,7 +1140,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) @@ -1407,7 +1405,8 @@ void EditorManager::gotoNextDocHistory() if (dialog->isVisible()) { dialog->selectNextEditor(); } else { - dialog->setEditors(m_d->m_editorHistory, m_d->m_currentEditor, m_d->m_editorModel); + EditorView *view = currentView()->view(); + dialog->setEditors(m_d->m_view, view, m_d->m_editorModel); dialog->selectNextEditor(); showWindowPopup(); } @@ -1419,7 +1418,8 @@ void EditorManager::gotoPreviousDocHistory() if (dialog->isVisible()) { dialog->selectPreviousEditor(); } else { - dialog->setEditors(m_d->m_editorHistory, m_d->m_currentEditor, m_d->m_editorModel); + EditorView *view = currentView()->view(); + dialog->setEditors(m_d->m_view, view, m_d->m_editorModel); dialog->selectPreviousEditor(); showWindowPopup(); } @@ -1474,10 +1474,11 @@ void EditorManager::updateActions() m_d->m_closeOtherEditorsAction->setEnabled(openedCount > 1); m_d->m_closeOtherEditorsAction->setText((openedCount > 1 ? tr("Close All Except %1").arg(quotedName) : tr("Close Others"))); - 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); + m_d->m_gotoNextDocHistoryAction->setEnabled(m_d->m_editorModel->rowCount() != 0); + m_d->m_gotoPreviousDocHistoryAction->setEnabled(m_d->m_editorModel->rowCount() != 0); + 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 +1498,23 @@ 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(); } @@ -1951,7 +1854,6 @@ void EditorManager::split(Qt::Orientation orientation) : m_d->m_splitter->findFirstView(); if (view && !view->splitter()) { view->split(orientation); - updateEditorHistory(); } updateActions(); } @@ -2006,7 +1908,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 8bb8d0439afbd750c7d342ecca7569b471909fb1..c5e45da9ad031fb871e56a9e50c8212befbc1632 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -36,6 +36,7 @@ #include <QtGui/QWidget> #include <QtCore/QList> +#include <QtCore/QPointer> QT_BEGIN_NAMESPACE class QSettings; @@ -72,6 +73,8 @@ class SplitterOrView; class EditorClosingCoreListener; class OpenEditorsViewFactory; + + } // namespace Internal class CORE_EXPORT EditorManagerPlaceHolder : public QWidget @@ -122,21 +125,22 @@ 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); + IEditor *activateEditor(const QModelIndex &index, Internal::EditorView *view = 0, OpenEditorFlags = 0); + IEditor *activateEditor(Core::Internal::EditorView *view, Core::IFile*file, OpenEditorFlags flags = 0); QList<IEditor*> openedEditors() const; OpenEditorsModel *openedEditorsModel() const; - IEditor *activateEditor(const QModelIndex &index, Internal::EditorView *view = 0, OpenEditorFlags = 0); void closeEditor(const QModelIndex &index); void closeOtherEditors(IEditor *editor); 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); @@ -209,7 +213,6 @@ private slots: void gotoNextDocHistory(); void gotoPreviousDocHistory(); void handleContextChange(Core::IContext *context); - void updateEditorHistory(); void updateActions(); void revertToSaved(); void makeCurrentEditorWritable(); @@ -238,7 +241,11 @@ 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 *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); void closeView(Core::Internal::EditorView *view); @@ -246,7 +253,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 4d952fd18e4ad15bd005f238c9e799a225b4222c..9e31dc2ec0cec80f7a8995e29807f6f382f9d85a 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); @@ -322,6 +323,7 @@ void EditorView::setCurrentEditor(IEditor *editor) m_editorList->setCurrentIndex(m_model->indexOf(editor).row()); updateEditorStatus(editor); updateToolBar(editor); + updateEditorHistory(editor); // FIXME: this keeps the editor hidden if switching from A to B and back if (editor != m_editorForInfoWidget) { @@ -408,10 +410,155 @@ void EditorView::listContextMenu(QPoint pos) QMenu menu; menu.addAction(tr("Copy full path to clipboard")); if (menu.exec(m_editorList->mapToGlobal(pos))) { - QApplication::clipboard()->setText(fileName); + QApplication::clipboard()->setText(QDir::toNativeSeparators(fileName)); } } +void EditorView::updateEditorHistory(IEditor *editor) +{ + if (!editor) + return; + IFile *file = editor->file(); + + if (!file) + return; + + QString fileName = file->fileName(); + QByteArray state = editor->saveState(); + + EditLocation location; + location.file = file; + location.fileName = file->fileName(); + location.kind = editor->kind(); + location.state = QVariant(state); + + for(int i = 0; i < m_editorHistory.size(); ++i) { + if (m_editorHistory.at(i).file == 0 + || m_editorHistory.at(i).file == file + ){ + m_editorHistory.removeAt(i--); + continue; + } + } + m_editorHistory.prepend(location); +} + +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; + 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) { + m_navigationHistory.takeFirst(); + --m_currentNavigationHistoryPosition; + } else { + m_navigationHistory.takeLast(); + } + } +} + +void EditorView::copyNavigationHistoryFrom(EditorView* other) +{ + if (!other) + return; + m_currentNavigationHistoryPosition = other->m_currentNavigationHistoryPosition; + m_navigationHistory = other->m_navigationHistory; + m_editorHistory = other->m_editorHistory; +} + +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 { + m_navigationHistory.append(EditLocation()); + location = &m_navigationHistory[m_navigationHistory.size()-1]; + } + 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) { + m_navigationHistory.removeAt(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 +788,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 +863,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 +928,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 996ec8df944346c4584d9f3d9bda798e7a2da944..35ddcb6ad82c3148ab9d6d323b953457754b2399 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; + QList<EditLocation> m_editorHistory; + 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()); + inline QList<EditLocation> editorHistory() const { return m_editorHistory; } + + void copyNavigationHistoryFrom(EditorView* other); + void updateEditorHistory(IEditor *editor); }; class SplitterOrView : public QWidget diff --git a/src/plugins/coreplugin/editormanager/openeditorsmodel.cpp b/src/plugins/coreplugin/editormanager/openeditorsmodel.cpp index 82bad267ba1d94328ed6a6842f3250eda2b36b2d..601900b288bd9705676759e7fb1c63dabab24f4c 100644 --- a/src/plugins/coreplugin/editormanager/openeditorsmodel.cpp +++ b/src/plugins/coreplugin/editormanager/openeditorsmodel.cpp @@ -281,6 +281,14 @@ QModelIndex OpenEditorsModel::indexOf(IEditor *editor) const return createIndex(idx, 0); } +QString OpenEditorsModel::displayNameForFile(IFile *file) const +{ + for (int i = 0; i < m_editors.count(); ++i) + if (m_editors.at(i).editor && m_editors.at(i).editor->file() == file) + return m_editors.at(i).editor->displayName(); + return QString(); +} + void OpenEditorsModel::itemChanged() { emitDataChanged(qobject_cast<IEditor*>(sender())); diff --git a/src/plugins/coreplugin/editormanager/openeditorsmodel.h b/src/plugins/coreplugin/editormanager/openeditorsmodel.h index 9172f2e29ee040f244912bae5ece5aa2163ab5ab..deaf14c953af025eebb6032d3c4d510c8be0f0dd 100644 --- a/src/plugins/coreplugin/editormanager/openeditorsmodel.h +++ b/src/plugins/coreplugin/editormanager/openeditorsmodel.h @@ -37,6 +37,7 @@ namespace Core { class IEditor; +class IFile; class CORE_EXPORT OpenEditorsModel : public QAbstractItemModel { @@ -81,6 +82,8 @@ public: void makeOriginal(IEditor *duplicate); QModelIndex indexOf(IEditor *editor) const; + QString displayNameForFile(IFile *file) const; + private slots: void itemChanged(); diff --git a/src/plugins/coreplugin/editormanager/openeditorswindow.cpp b/src/plugins/coreplugin/editormanager/openeditorswindow.cpp index 2684ca09755bc51149cd224e1ca447ac49a2e081..4db7b369af8e41b8f3ef40946bb65678c13704db 100644 --- a/src/plugins/coreplugin/editormanager/openeditorswindow.cpp +++ b/src/plugins/coreplugin/editormanager/openeditorswindow.cpp @@ -34,7 +34,8 @@ #include <QtGui/QHeaderView> -Q_DECLARE_METATYPE(Core::IEditor *) +Q_DECLARE_METATYPE(Core::Internal::EditorView*) +Q_DECLARE_METATYPE(Core::IFile *) using namespace Core; using namespace Core::Internal; @@ -188,41 +189,68 @@ void OpenEditorsWindow::centerOnItem(int selectedIndex) } } -void OpenEditorsWindow::setEditors(const QList<IEditor *>&editors, IEditor *current, OpenEditorsModel *model) +void OpenEditorsWindow::setEditors(EditorView *mainView, EditorView *view, OpenEditorsModel *model) { static const QIcon lockedIcon(QLatin1String(":/core/images/locked.png")); static const QIcon emptyIcon(QLatin1String(":/core/images/empty14.png")); m_editorList->clear(); + bool first = true; - QList<IEditor *> doneList; - QList<IFile *>doneFileList; - foreach (IEditor *editor, editors) { - if (doneList.contains(editor)) + QSet<IFile*> filesDone; + foreach (const EditLocation &hi, view->editorHistory()) { + if (hi.file == 0 || filesDone.contains(hi.file)) continue; - doneList += editor; - if (!editor->widget()->isVisible() && doneFileList.contains(editor->file())) - continue; - doneFileList += editor->file(); + filesDone.insert(hi.file.data()); QTreeWidgetItem *item = new QTreeWidgetItem(); - QString title = editor->displayName(); - if (editor->file()->isModified()) + QString title = model->displayNameForFile(hi.file); + if (hi.file && hi.file->isModified()) title += tr("*"); - item->setIcon(0, editor->file()->isReadOnly() ? lockedIcon : emptyIcon); + item->setIcon(0, hi.file->isReadOnly() ? lockedIcon : emptyIcon); item->setText(0, title); - item->setToolTip(0, editor->file()->fileName()); - item->setData(0, Qt::UserRole, QVariant::fromValue(editor)); + item->setToolTip(0, hi.file->fileName()); + item->setData(0, Qt::UserRole, QVariant::fromValue(hi.file.data())); + item->setData(0, Qt::UserRole+1, QVariant::fromValue(view)); item->setTextAlignment(0, Qt::AlignLeft); m_editorList->addTopLevelItem(item); - if (editor == current) + if (first){ m_editorList->setCurrentItem(item); - + first = false; + } } + // add missing editors from the main view + if (mainView != view) { + foreach (const EditLocation &hi, mainView->editorHistory()) { + if (hi.file == 0 || filesDone.contains(hi.file)) + continue; + filesDone.insert(hi.file.data()); + + QTreeWidgetItem *item = new QTreeWidgetItem(); + + QString title = model->displayNameForFile(hi.file); + if (hi.file && hi.file->isModified()) + title += tr("*"); + item->setIcon(0, hi.file->isReadOnly() ? lockedIcon : emptyIcon); + item->setText(0, title); + item->setToolTip(0, hi.file->fileName()); + item->setData(0, Qt::UserRole, QVariant::fromValue(hi.file.data())); + item->setData(0, Qt::UserRole+1, QVariant::fromValue(view)); + item->setTextAlignment(0, Qt::AlignLeft); + + m_editorList->addTopLevelItem(item); + + if (first){ + m_editorList->setCurrentItem(item); + first = false; + } + } +} + // add purely restored editors which are not initialised yet foreach (OpenEditorsModel::Entry entry, model->entries()) { if (entry.editor) @@ -232,7 +260,7 @@ void OpenEditorsWindow::setEditors(const QList<IEditor *>&editors, IEditor *curr item->setIcon(0, emptyIcon); item->setText(0, title); item->setToolTip(0, entry.fileName()); - item->setData(0, Qt::UserRole+1, QVariant::fromValue(entry.kind())); + item->setData(0, Qt::UserRole+2, QVariant::fromValue(entry.kind())); item->setTextAlignment(0, Qt::AlignLeft); m_editorList->addTopLevelItem(item); @@ -244,10 +272,12 @@ void OpenEditorsWindow::selectEditor(QTreeWidgetItem *item) { if (!item) return; - if (IEditor *editor = item->data(0, Qt::UserRole).value<IEditor*>()) - EditorManager::instance()->activateEditor(editor); - else - EditorManager::instance()->openEditor(item->toolTip(0), item->data(0, Qt::UserRole+1).toByteArray()); + if (IFile *file = item->data(0, Qt::UserRole).value<IFile*>()) { + EditorView *view = item->data(0, Qt::UserRole+1).value<EditorView*>(); + EditorManager::instance()->activateEditor(view, file); + } else { + EditorManager::instance()->openEditor(item->toolTip(0), item->data(0, Qt::UserRole+2).toByteArray()); + } } void OpenEditorsWindow::editorClicked(QTreeWidgetItem *item) diff --git a/src/plugins/coreplugin/editormanager/openeditorswindow.h b/src/plugins/coreplugin/editormanager/openeditorswindow.h index 21f53bdf429529bffb1a142e4f4baabbd39fa39e..7ce25c1ac6498a42f8c645da9cf82dd89229b915 100644 --- a/src/plugins/coreplugin/editormanager/openeditorswindow.h +++ b/src/plugins/coreplugin/editormanager/openeditorswindow.h @@ -44,6 +44,9 @@ class OpenEditorsModel; namespace Internal { +class EditorHistoryItem; +class EditorView; + class OpenEditorsWindow : public QWidget { Q_OBJECT @@ -54,7 +57,7 @@ public: OpenEditorsWindow(QWidget *parent = 0); ~OpenEditorsWindow() {} - void setEditors(const QList<IEditor *>&editors, IEditor *current, OpenEditorsModel *model); + void setEditors(EditorView *mainView, EditorView *view, OpenEditorsModel *model); bool event(QEvent *e); bool eventFilter(QObject *src, QEvent *e); diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 0dc130d845e0820f341fdd796510864db67bbcaf..be678e721c5b792d3271c7e7cc2ea6e10c15e3e4 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -558,21 +558,21 @@ void MainWindow::registerDefaultActions() connect(m_focusToEditor, SIGNAL(activated()), this, SLOT(setFocusToEditor())); // New File Action - m_newAction = new QAction(QIcon(Constants::ICON_NEWFILE), tr("&New..."), this); + m_newAction = new QAction(QIcon(Constants::ICON_NEWFILE), tr("&New File/Project..."), this); cmd = am->registerAction(m_newAction, Constants::NEW, m_globalContext); cmd->setDefaultKeySequence(QKeySequence::New); mfile->addAction(cmd, Constants::G_FILE_NEW); connect(m_newAction, SIGNAL(triggered()), this, SLOT(newFile())); // Open Action - m_openAction = new QAction(QIcon(Constants::ICON_OPENFILE), tr("&Open..."), this); + m_openAction = new QAction(QIcon(Constants::ICON_OPENFILE), tr("&Open File/Project..."), this); cmd = am->registerAction(m_openAction, Constants::OPEN, m_globalContext); cmd->setDefaultKeySequence(QKeySequence::Open); mfile->addAction(cmd, Constants::G_FILE_OPEN); connect(m_openAction, SIGNAL(triggered()), this, SLOT(openFile())); // Open With Action - m_openWithAction = new QAction(tr("&Open With..."), this); + m_openWithAction = new QAction(tr("&Open File With..."), this); cmd = am->registerAction(m_openWithAction, Constants::OPEN_WITH, m_globalContext); mfile->addAction(cmd, Constants::G_FILE_OPEN); connect(m_openWithAction, SIGNAL(triggered()), this, SLOT(openFileWith())); diff --git a/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.cpp b/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.cpp index df8f7352adbf6b28307223f4e3e7c55f5964ea9a..1a4803ca71d6bc84adf4302ac951d22f63c59383 100644 --- a/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.cpp +++ b/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.cpp @@ -256,11 +256,6 @@ QList<Core::IEditor*> EditorManagerPrototype::openedEditors() const return callee()->openedEditors(); } -QList<Core::IEditor*> EditorManagerPrototype::editorHistory() const -{ - return callee()->editorHistory(); -} - QList<Core::IEditor*> EditorManagerPrototype::editorsForFiles(QList<Core::IFile*> files) const { return callee()->editorsForFiles(files); diff --git a/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.h b/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.h index a8d386bbf96596d0151503e5e2faac8b1014dcfd..52bad34648337272240ecb2cb72060aadf946d54 100644 --- a/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.h +++ b/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.h @@ -165,7 +165,6 @@ class EditorManagerPrototype : public QObject, public QScriptable Q_OBJECT Q_PROPERTY(Core::IEditor* currentEditor READ currentEditor WRITE activateEditor DESIGNABLE false SCRIPTABLE true STORED false) Q_PROPERTY(QList<Core::IEditor*> openedEditors READ openedEditors DESIGNABLE false SCRIPTABLE true STORED false) - Q_PROPERTY(QList<Core::IEditor*> editorHistory READ editorHistory DESIGNABLE false SCRIPTABLE true STORED false) public: typedef Core::EditorManager EditorManager; diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp index 295e59fae2914a858b8eb482ba06db4dd5d1df01..c48c7fe02c28a699f55d1ee820c6c90f31f4d881 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/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index 0005049ad4e263d3b65dd925ffd0cc5f41849bd6..e1f4451dbb6ce5d6ad3a392ce0c038dbca4c3aa7 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -372,9 +372,9 @@ void QtVersionManager::setNewQtVersions(QList<QtVersion *> newVersions, int newD emit qtVersionsChanged(); if (emitDefaultChanged) { emit defaultQtVersionChanged(); - updateExamples(); } + updateExamples(); writeVersionsIntoSettings(); } diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index c53d617d7af274f76df773113a46b66918486ef6..bf736aa962f5484b4b61ced2e85c6e35280ef531 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();