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);
~EditorManagerPrivate();
Internal::EditorView *m_view;
QList<EditLocation> m_globalHistory;
Internal::SplitterOrView *m_splitter;
QPointer<IEditor> m_currentEditor;
QPointer<EditorView> m_currentView;
@@ -227,7 +227,6 @@ struct EditorManagerPrivate
}
EditorManagerPrivate::EditorManagerPrivate(QWidget *parent) :
m_view(0),
m_splitter(0),
m_autoSaveTimer(0),
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);
// other setup
d->m_splitter = new SplitterOrView(d->m_editorModel);
d->m_view = d->m_splitter->view();
d->m_splitter = new SplitterOrView();
QHBoxLayout *layout = new QHBoxLayout(this);
layout->setMargin(0);
@@ -514,7 +511,8 @@ void EditorManager::setCurrentEditor(IEditor *editor, bool ignoreNavigationHisto
if (editor) {
if (EditorView *view = viewForEditor(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();
updateWindowTitle();
@@ -597,18 +595,31 @@ void EditorManager::emptyView(Core::Internal::EditorView *view)
QList<IEditor *> editors = view->editors();
foreach (IEditor *editor, editors) {
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);
view->removeEditor(editor);
continue;
continue; // don't close the editor
}
}
emit editorAboutToClose(editor);
removeEditor(editor);
view->removeEditor(editor);
}
if (!editors.isEmpty()) {
emit editorsClosed(editors);
foreach (IEditor *editor, editors) {
delete editor;
}
}
}
void EditorManager::closeView(Core::Internal::EditorView *view)
@@ -616,29 +627,6 @@ void EditorManager::closeView(Core::Internal::EditorView *view)
if (!view)
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);
SplitterOrView *splitterOrView = view->parentSplitterOrView();
@@ -1654,7 +1642,7 @@ void EditorManager::gotoNextDocHistory()
dialog->selectNextEditor();
} else {
EditorView *view = currentEditorView();
dialog->setEditors(d->m_view, view, d->m_editorModel);
dialog->setEditors(d->m_globalHistory, view, d->m_editorModel);
dialog->selectNextEditor();
showPopupOrSelectDocument();
}
@@ -1667,7 +1655,7 @@ void EditorManager::gotoPreviousDocHistory()
dialog->selectPreviousEditor();
} else {
EditorView *view = currentEditorView();
dialog->setEditors(d->m_view, view, d->m_editorModel);
dialog->setEditors(d->m_globalHistory, view, d->m_editorModel);
dialog->selectPreviousEditor();
showPopupOrSelectDocument();
}
@@ -2207,16 +2195,7 @@ void EditorManager::removeAllSplits()
{
if (!d->m_splitter->isSplitter())
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();
if (!editor)
editor = pickUnusedEditor();
if (editor)
activateEditor(editor);
}
void EditorManager::gotoOtherSplit()

View File

@@ -190,6 +190,34 @@ void EditorView::setCloseSplitIcon(const QIcon &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 *)
{
EditorView *editorView = ICore::editorManager()->currentEditorView();
@@ -332,30 +360,7 @@ QList<IEditor *> EditorView::editors() const
void EditorView::updateEditorHistory(IEditor *editor)
{
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 < 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);
updateEditorHistory(editor, m_editorHistory);
}
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)
{
m_isRoot = false;
m_layout = new QStackedLayout(this);
m_view = new EditorView(this);
if (editor)
@@ -620,7 +613,7 @@ void SplitterOrView::split(Qt::Orientation orientation)
otherView->view()->setCloseSplitIcon(QIcon(QLatin1String(Constants::ICON_CLOSE_SPLIT_BOTTOM)));
}
if (m_view && !m_isRoot) {
if (m_view) {
em->emptyView(m_view);
delete m_view;
m_view = 0;
@@ -634,16 +627,26 @@ void SplitterOrView::split(Qt::Orientation orientation)
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_layout->removeWidget(m_splitter); // workaround Qt bug
unsplitAll_helper();
m_view = currentView;
m_layout->addWidget(m_view);
delete m_splitter;
m_splitter = 0;
}
void SplitterOrView::unsplitAll_helper()
{
if (!m_isRoot && m_view)
if (m_view)
ICore::editorManager()->emptyView(m_view);
if (m_splitter) {
for (int i = 0; i < m_splitter->count(); ++i) {

View File

@@ -100,6 +100,8 @@ public:
void setCloseSplitEnabled(bool enable);
void setCloseSplitIcon(const QIcon &icon);
static void updateEditorHistory(IEditor *editor, QList<EditLocation> &history);
protected:
void paintEvent(QPaintEvent *);
void mousePressEvent(QMouseEvent *e);
@@ -159,7 +161,6 @@ class SplitterOrView : public QWidget
{
Q_OBJECT
public:
explicit SplitterOrView(OpenEditorsModel *model); // creates a root splitter
explicit SplitterOrView(Core::IEditor *editor = 0);
~SplitterOrView();
@@ -167,9 +168,8 @@ public:
void unsplit();
inline bool isView() const { return m_view != 0; }
inline bool isRoot() const { return m_isRoot; }
inline bool isSplitter() const { return m_splitter != 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 bool hasEditor(Core::IEditor *editor) const { return m_view && m_view->hasEditor(editor); }
@@ -192,7 +192,6 @@ public:
private:
void unsplitAll_helper();
bool m_isRoot;
QStackedLayout *m_layout;
EditorView *m_view;
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();
QSet<IDocument*> documentsDone;
addHistoryItems(view->editorHistory(), view, model, documentsDone);
// add missing editors from the main view
if (mainView != view)
addHistoryItems(mainView->editorHistory(), view, model, documentsDone);
// add missing editors from the global history
addHistoryItems(globalHistory, view, model, documentsDone);
// add purely restored editors which are not initialised yet
foreach (const OpenEditorsModel::Entry &entry, model->entries()) {

View File

@@ -60,7 +60,7 @@ public:
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);
void focusInEvent(QFocusEvent *);