Commit f16d0c4d authored by mae's avatar mae
Browse files

imlemented per-view edit location navigation

parent 7c57f260
......@@ -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);
......
......@@ -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;
......
......@@ -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) {
......
......@@ -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
......
......@@ -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);
......
......@@ -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();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment