Do not keep the central editor view around even when split.

The view of the top level splitter was kept around for the global editor
history, which lead to unnecessarily complicated code (e.g. flagging the
root splitter as "root" and adding logic to keep the view around for
it).
Instead we just keep a global editor history.

Change-Id: I6558ca0eae681ebacbe6a6fbbc5c103f0b061a6b
Reviewed-by: David Schulz <david.schulz@digia.com>
This commit is contained in:
Eike Ziller
2013-04-30 19:15:04 +02:00
committed by David Schulz
parent 934cea560d
commit d1cb5dade0
5 changed files with 73 additions and 93 deletions

View File

@@ -175,7 +175,7 @@ struct EditorManagerPrivate
{ {
explicit EditorManagerPrivate(QWidget *parent); explicit EditorManagerPrivate(QWidget *parent);
~EditorManagerPrivate(); ~EditorManagerPrivate();
Internal::EditorView *m_view; QList<EditLocation> m_globalHistory;
Internal::SplitterOrView *m_splitter; Internal::SplitterOrView *m_splitter;
QPointer<IEditor> m_currentEditor; QPointer<IEditor> m_currentEditor;
QPointer<EditorView> m_currentView; QPointer<EditorView> m_currentView;
@@ -227,7 +227,6 @@ struct EditorManagerPrivate
} }
EditorManagerPrivate::EditorManagerPrivate(QWidget *parent) : EditorManagerPrivate::EditorManagerPrivate(QWidget *parent) :
m_view(0),
m_splitter(0), m_splitter(0),
m_autoSaveTimer(0), m_autoSaveTimer(0),
m_revertToSavedAction(new QAction(EditorManager::tr("Revert to Saved"), parent)), m_revertToSavedAction(new QAction(EditorManager::tr("Revert to Saved"), parent)),
@@ -418,9 +417,7 @@ EditorManager::EditorManager(QWidget *parent) :
advancedMenu->addSeparator(editManagerContext, Constants::G_EDIT_EDITOR); advancedMenu->addSeparator(editManagerContext, Constants::G_EDIT_EDITOR);
// other setup // other setup
d->m_splitter = new SplitterOrView(d->m_editorModel); d->m_splitter = new SplitterOrView();
d->m_view = d->m_splitter->view();
QHBoxLayout *layout = new QHBoxLayout(this); QHBoxLayout *layout = new QHBoxLayout(this);
layout->setMargin(0); layout->setMargin(0);
@@ -514,7 +511,8 @@ void EditorManager::setCurrentEditor(IEditor *editor, bool ignoreNavigationHisto
if (editor) { if (editor) {
if (EditorView *view = viewForEditor(editor)) if (EditorView *view = viewForEditor(editor))
view->setCurrentEditor(editor); view->setCurrentEditor(editor);
d->m_view->updateEditorHistory(editor); // the global view should have a complete history // update global history
EditorView::updateEditorHistory(editor, d->m_globalHistory);
} }
updateActions(); updateActions();
updateWindowTitle(); updateWindowTitle();
@@ -597,48 +595,38 @@ void EditorManager::emptyView(Core::Internal::EditorView *view)
QList<IEditor *> editors = view->editors(); QList<IEditor *> editors = view->editors();
foreach (IEditor *editor, editors) { foreach (IEditor *editor, editors) {
if (!d->m_editorModel->isDuplicate(editor)) { if (!d->m_editorModel->isDuplicate(editor)) {
QList<IEditor *> duplicates = d->m_editorModel->duplicatesFor(editor);
if (!duplicates.isEmpty()) {
d->m_editorModel->makeOriginal(duplicates.first());
} else {
// it's the only editor for that file and it's not a duplicate,
// so we need to keep it around (--> in the editor model)
if (currentEditor() == editor) {
// we don't want a current editor that is not open in a view
setCurrentEditor(0);
}
editors.removeAll(editor); editors.removeAll(editor);
view->removeEditor(editor); view->removeEditor(editor);
continue; continue; // don't close the editor
}
} }
emit editorAboutToClose(editor); emit editorAboutToClose(editor);
removeEditor(editor); removeEditor(editor);
view->removeEditor(editor); view->removeEditor(editor);
} }
if (!editors.isEmpty()) {
emit editorsClosed(editors); emit editorsClosed(editors);
foreach (IEditor *editor, editors) { foreach (IEditor *editor, editors) {
delete editor; delete editor;
} }
} }
}
void EditorManager::closeView(Core::Internal::EditorView *view) void EditorManager::closeView(Core::Internal::EditorView *view)
{ {
if (!view) if (!view)
return; return;
if (view == d->m_view) {
if (IEditor *e = view->currentEditor())
closeEditors(QList<IEditor *>() << e);
return;
}
if (IEditor *e = view->currentEditor()) {
/*
when we are closing a view with an original editor which has
duplicates, then make one of the duplicates the original.
Otherwise the original would be kept around and the user might
experience jumping to a missleading position within the file when
visiting the file again. With the code below, the position within
the file will be the position of the first duplicate which is still
around.
*/
if (!d->m_editorModel->isDuplicate(e)) {
QList<IEditor *> duplicates = d->m_editorModel->duplicatesFor(e);
if (!duplicates.isEmpty())
d->m_editorModel->makeOriginal(duplicates.first());
}
}
emptyView(view); emptyView(view);
SplitterOrView *splitterOrView = view->parentSplitterOrView(); SplitterOrView *splitterOrView = view->parentSplitterOrView();
@@ -1654,7 +1642,7 @@ void EditorManager::gotoNextDocHistory()
dialog->selectNextEditor(); dialog->selectNextEditor();
} else { } else {
EditorView *view = currentEditorView(); EditorView *view = currentEditorView();
dialog->setEditors(d->m_view, view, d->m_editorModel); dialog->setEditors(d->m_globalHistory, view, d->m_editorModel);
dialog->selectNextEditor(); dialog->selectNextEditor();
showPopupOrSelectDocument(); showPopupOrSelectDocument();
} }
@@ -1667,7 +1655,7 @@ void EditorManager::gotoPreviousDocHistory()
dialog->selectPreviousEditor(); dialog->selectPreviousEditor();
} else { } else {
EditorView *view = currentEditorView(); EditorView *view = currentEditorView();
dialog->setEditors(d->m_view, view, d->m_editorModel); dialog->setEditors(d->m_globalHistory, view, d->m_editorModel);
dialog->selectPreviousEditor(); dialog->selectPreviousEditor();
showPopupOrSelectDocument(); showPopupOrSelectDocument();
} }
@@ -2207,16 +2195,7 @@ void EditorManager::removeAllSplits()
{ {
if (!d->m_splitter->isSplitter()) if (!d->m_splitter->isSplitter())
return; return;
IEditor *editor = d->m_currentEditor;
// trigger update below
d->m_currentEditor = 0;
if (editor && d->m_editorModel->isDuplicate(editor))
d->m_editorModel->makeOriginal(editor);
d->m_splitter->unsplitAll(); d->m_splitter->unsplitAll();
if (!editor)
editor = pickUnusedEditor();
if (editor)
activateEditor(editor);
} }
void EditorManager::gotoOtherSplit() void EditorManager::gotoOtherSplit()

View File

@@ -190,6 +190,34 @@ void EditorView::setCloseSplitIcon(const QIcon &icon)
m_toolBar->setCloseSplitIcon(icon); m_toolBar->setCloseSplitIcon(icon);
} }
void EditorView::updateEditorHistory(IEditor *editor, QList<EditLocation> &history)
{
if (!editor)
return;
IDocument *document = editor->document();
if (!document)
return;
QByteArray state = editor->saveState();
EditLocation location;
location.document = document;
location.fileName = document->fileName();
location.id = editor->id();
location.state = QVariant(state);
for (int i = 0; i < history.size(); ++i) {
if (history.at(i).document == 0
|| history.at(i).document == document
){
history.removeAt(i--);
continue;
}
}
history.prepend(location);
}
void EditorView::paintEvent(QPaintEvent *) void EditorView::paintEvent(QPaintEvent *)
{ {
EditorView *editorView = ICore::editorManager()->currentEditorView(); EditorView *editorView = ICore::editorManager()->currentEditorView();
@@ -332,30 +360,7 @@ QList<IEditor *> EditorView::editors() const
void EditorView::updateEditorHistory(IEditor *editor) void EditorView::updateEditorHistory(IEditor *editor)
{ {
if (!editor) updateEditorHistory(editor, m_editorHistory);
return;
IDocument *document = editor->document();
if (!document)
return;
QByteArray state = editor->saveState();
EditLocation location;
location.document = document;
location.fileName = document->fileName();
location.id = editor->id();
location.state = QVariant(state);
for (int i = 0; i < m_editorHistory.size(); ++i) {
if (m_editorHistory.at(i).document == 0
|| m_editorHistory.at(i).document == document
){
m_editorHistory.removeAt(i--);
continue;
}
}
m_editorHistory.prepend(location);
} }
void EditorView::addCurrentPositionToNavigationHistory(IEditor *editor, const QByteArray &saveState) void EditorView::addCurrentPositionToNavigationHistory(IEditor *editor, const QByteArray &saveState)
@@ -492,20 +497,8 @@ void EditorView::goForwardInNavigationHistory()
} }
SplitterOrView::SplitterOrView(OpenEditorsModel *model)
{
Q_ASSERT(model);
Q_UNUSED(model); // For building in release mode.
m_isRoot = true;
m_layout = new QStackedLayout(this);
m_view = new EditorView(this);
m_splitter = 0;
m_layout->addWidget(m_view);
}
SplitterOrView::SplitterOrView(Core::IEditor *editor) SplitterOrView::SplitterOrView(Core::IEditor *editor)
{ {
m_isRoot = false;
m_layout = new QStackedLayout(this); m_layout = new QStackedLayout(this);
m_view = new EditorView(this); m_view = new EditorView(this);
if (editor) if (editor)
@@ -620,7 +613,7 @@ void SplitterOrView::split(Qt::Orientation orientation)
otherView->view()->setCloseSplitIcon(QIcon(QLatin1String(Constants::ICON_CLOSE_SPLIT_BOTTOM))); otherView->view()->setCloseSplitIcon(QIcon(QLatin1String(Constants::ICON_CLOSE_SPLIT_BOTTOM)));
} }
if (m_view && !m_isRoot) { if (m_view) {
em->emptyView(m_view); em->emptyView(m_view);
delete m_view; delete m_view;
m_view = 0; m_view = 0;
@@ -634,16 +627,26 @@ void SplitterOrView::split(Qt::Orientation orientation)
void SplitterOrView::unsplitAll() void SplitterOrView::unsplitAll()
{ {
QTC_ASSERT(m_splitter, return);
EditorView *currentView = EditorManager::instance()->currentEditorView();
if (currentView) {
currentView->parentSplitterOrView()->takeView();
currentView->setParentSplitterOrView(this);
} else {
currentView = new EditorView(this);
}
m_splitter->hide(); m_splitter->hide();
m_layout->removeWidget(m_splitter); // workaround Qt bug m_layout->removeWidget(m_splitter); // workaround Qt bug
unsplitAll_helper(); unsplitAll_helper();
m_view = currentView;
m_layout->addWidget(m_view);
delete m_splitter; delete m_splitter;
m_splitter = 0; m_splitter = 0;
} }
void SplitterOrView::unsplitAll_helper() void SplitterOrView::unsplitAll_helper()
{ {
if (!m_isRoot && m_view) if (m_view)
ICore::editorManager()->emptyView(m_view); ICore::editorManager()->emptyView(m_view);
if (m_splitter) { if (m_splitter) {
for (int i = 0; i < m_splitter->count(); ++i) { for (int i = 0; i < m_splitter->count(); ++i) {

View File

@@ -100,6 +100,8 @@ public:
void setCloseSplitEnabled(bool enable); void setCloseSplitEnabled(bool enable);
void setCloseSplitIcon(const QIcon &icon); void setCloseSplitIcon(const QIcon &icon);
static void updateEditorHistory(IEditor *editor, QList<EditLocation> &history);
protected: protected:
void paintEvent(QPaintEvent *); void paintEvent(QPaintEvent *);
void mousePressEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e);
@@ -159,7 +161,6 @@ class SplitterOrView : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit SplitterOrView(OpenEditorsModel *model); // creates a root splitter
explicit SplitterOrView(Core::IEditor *editor = 0); explicit SplitterOrView(Core::IEditor *editor = 0);
~SplitterOrView(); ~SplitterOrView();
@@ -167,9 +168,8 @@ public:
void unsplit(); void unsplit();
inline bool isView() const { return m_view != 0; } inline bool isView() const { return m_view != 0; }
inline bool isRoot() const { return m_isRoot; }
inline bool isSplitter() const { return m_splitter != 0; } inline bool isSplitter() const { return m_splitter != 0; }
inline Core::IEditor *editor() const { return m_view ? m_view->currentEditor() : 0; } inline Core::IEditor *editor() const { return m_view ? m_view->currentEditor() : 0; }
inline QList<Core::IEditor *> editors() const { return m_view ? m_view->editors() : QList<Core::IEditor*>(); } inline QList<Core::IEditor *> editors() const { return m_view ? m_view->editors() : QList<Core::IEditor*>(); }
inline bool hasEditor(Core::IEditor *editor) const { return m_view && m_view->hasEditor(editor); } inline bool hasEditor(Core::IEditor *editor) const { return m_view && m_view->hasEditor(editor); }
@@ -192,7 +192,6 @@ public:
private: private:
void unsplitAll_helper(); void unsplitAll_helper();
bool m_isRoot;
QStackedLayout *m_layout; QStackedLayout *m_layout;
EditorView *m_view; EditorView *m_view;
QSplitter *m_splitter; QSplitter *m_splitter;

View File

@@ -193,15 +193,14 @@ void OpenEditorsWindow::centerOnItem(int selectedIndex)
} }
} }
void OpenEditorsWindow::setEditors(EditorView *mainView, EditorView *view, OpenEditorsModel *model) void OpenEditorsWindow::setEditors(const QList<EditLocation> &globalHistory, EditorView *view, OpenEditorsModel *model)
{ {
m_editorList->clear(); m_editorList->clear();
QSet<IDocument*> documentsDone; QSet<IDocument*> documentsDone;
addHistoryItems(view->editorHistory(), view, model, documentsDone); addHistoryItems(view->editorHistory(), view, model, documentsDone);
// add missing editors from the main view // add missing editors from the global history
if (mainView != view) addHistoryItems(globalHistory, view, model, documentsDone);
addHistoryItems(mainView->editorHistory(), view, model, documentsDone);
// add purely restored editors which are not initialised yet // add purely restored editors which are not initialised yet
foreach (const OpenEditorsModel::Entry &entry, model->entries()) { foreach (const OpenEditorsModel::Entry &entry, model->entries()) {

View File

@@ -60,7 +60,7 @@ public:
explicit OpenEditorsWindow(QWidget *parent = 0); explicit OpenEditorsWindow(QWidget *parent = 0);
void setEditors(EditorView *mainView, EditorView *view, OpenEditorsModel *model); void setEditors(const QList<EditLocation> &globalHistory, EditorView *view, OpenEditorsModel *model);
bool eventFilter(QObject *src, QEvent *e); bool eventFilter(QObject *src, QEvent *e);
void focusInEvent(QFocusEvent *); void focusInEvent(QFocusEvent *);