From 3f9580fe0eb819d9b134e041aad30cf2be48bf14 Mon Sep 17 00:00:00 2001 From: mae <qtc-committer@nokia.com> Date: Fri, 6 Mar 2009 11:59:16 +0100 Subject: [PATCH] fake session restored editors in the open documents widget and the tab history. This makes restoring sessions faster, but switching to restored documents for the first time a bit slower. --- .../editormanager/editormanager.cpp | 70 +++++++--- .../coreplugin/editormanager/editormanager.h | 3 + .../coreplugin/editormanager/editorview.cpp | 128 ++++++++++++++---- .../coreplugin/editormanager/editorview.h | 21 ++- .../editormanager/openeditorsview.cpp | 3 +- .../editormanager/openeditorswindow.cpp | 70 +++++----- .../editormanager/openeditorswindow.h | 9 +- 7 files changed, 213 insertions(+), 91 deletions(-) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 76a49f54f40..03959a5dc51 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -70,6 +70,8 @@ #include <QtGui/QSplitter> #include <QtGui/QStackedLayout> +Q_DECLARE_METATYPE(Core::IEditor*) + using namespace Core; using namespace Core::Internal; @@ -740,6 +742,26 @@ IEditor *EditorManager::pickUnusedEditor() const return 0; } + +void EditorManager::activateEditor(const QModelIndex &index, Internal::EditorView *view) +{ + IEditor *editor = index.data(Qt::UserRole).value<IEditor*>(); + if (editor) { + if (view) + activateEditor(view, editor); + else + activateEditor(editor); + return; + } + + 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(); + openEditor(fileName, kind); +} + void EditorManager::activateEditor(IEditor *editor, OpenEditorFlags flags) { SplitterOrView *splitterOrView = m_d->m_currentView; @@ -1244,7 +1266,7 @@ void EditorManager::gotoNextDocHistory() if (dialog->isVisible()) { dialog->selectNextEditor(); } else { - dialog->setEditors(m_d->m_editorHistory, m_d->m_currentEditor); + dialog->setEditors(m_d->m_editorHistory, m_d->m_currentEditor, m_d->m_editorModel); dialog->selectNextEditor(); showWindowPopup(); } @@ -1256,7 +1278,7 @@ void EditorManager::gotoPreviousDocHistory() if (dialog->isVisible()) { dialog->selectPreviousEditor(); } else { - dialog->setEditors(m_d->m_editorHistory, m_d->m_currentEditor); + dialog->setEditors(m_d->m_editorHistory, m_d->m_currentEditor, m_d->m_editorModel); dialog->selectPreviousEditor(); showWindowPopup(); } @@ -1451,24 +1473,30 @@ QByteArray EditorManager::saveState() const QByteArray bytes; QDataStream stream(&bytes, QIODevice::WriteOnly); - stream << QByteArray("EditorManagerV1"); - - stream << m_d->m_editorStates; + stream << QByteArray("EditorManagerV2"); QList<IEditor *> editors = openedEditors(); - int editorCount = editors.count(); - - if (editors.contains(m_d->m_currentEditor)) { - editors.removeAll(m_d->m_currentEditor); - editors.prepend(m_d->m_currentEditor); + foreach (IEditor *editor, editors) { + if (!editor->file()->fileName().isEmpty()) { + QByteArray state = editor->saveState(); + if (!state.isEmpty()) + m_d->m_editorStates.insert(editor->file()->fileName(), QVariant(state)); + } } + stream << m_d->m_editorStates; + + + QList<EditorModel::Entry> entries = m_d->m_editorModel->entries(); + stream << entries.count(); - stream << editorCount; - foreach (IEditor *editor, editors) { - stream << editor->file()->fileName() << QByteArray(editor->kind()); + if (IEditor *current = m_d->m_currentEditor) // current first + stream << current->file()->fileName() << current->displayName() << QByteArray(current->kind()); + foreach (EditorModel::Entry entry, entries) { + if (entry.editor && entry.editor == m_d->m_currentEditor) // all but current + continue; + stream << entry.fileName() << entry.displayName() << entry.kind(); } - return bytes; } @@ -1480,7 +1508,7 @@ bool EditorManager::restoreState(const QByteArray &state) QByteArray version; stream >> version; - if (version != "EditorManagerV1") + if (version != "EditorManagerV2") return false; QMap<QString, QVariant> editorstates; @@ -1500,11 +1528,16 @@ bool EditorManager::restoreState(const QByteArray &state) while (--editorCount >= 0) { QString fileName; stream >> fileName; + QString displayName; + stream >> displayName; QByteArray kind; stream >> kind; - IEditor *editor = openEditor(fileName, kind, IgnoreNavigationHistory | NoActivate); - if (!toActivate) - toActivate = editor; + + if (!toActivate) { + toActivate = openEditor(fileName, kind, IgnoreNavigationHistory | NoActivate); + } else if (!fileName.isEmpty() && !displayName.isEmpty()){ + m_d->m_editorModel->addRestoredEditor(fileName, displayName, kind); + } } if (toActivate) @@ -1702,6 +1735,7 @@ Core::IEditor *EditorManager::duplicateEditor(Core::IEditor *editor) return 0; IEditor *duplicate = editor->duplicate(0); + duplicate->restoreState(editor->saveState()); emit editorCreated(duplicate, duplicate->file()->fileName()); addEditor(duplicate, true); return duplicate; diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h index 1d03906bfd0..401e94b00d7 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -39,6 +39,7 @@ QT_BEGIN_NAMESPACE class QSettings; +class QModelIndex; QT_END_NAMESPACE namespace Core { @@ -125,6 +126,8 @@ public: QList<IEditor*> openedEditors() const; Internal::EditorModel *openedEditorsModel() const; + void activateEditor(const QModelIndex &index, Internal::EditorView *view = 0); + QList<IEditor*> editorsForFiles(QList<IFile*> files) const; //QList<EditorGroup *> editorGroups() const; diff --git a/src/plugins/coreplugin/editormanager/editorview.cpp b/src/plugins/coreplugin/editormanager/editorview.cpp index 480a3fd4ba2..484905ebbe9 100644 --- a/src/plugins/coreplugin/editormanager/editorview.cpp +++ b/src/plugins/coreplugin/editormanager/editorview.cpp @@ -61,6 +61,18 @@ using namespace Core::Internal; //================EditorModel==================== + +QString EditorModel::Entry::fileName() const { + return editor ? editor->file()->fileName() : m_fileName; +} +QString EditorModel::Entry::displayName() const { + return editor ? editor->displayName() : m_displayName; +} +QByteArray EditorModel::Entry::kind() const +{ + return editor ? QByteArray(editor->kind()) : m_kind; +} + int EditorModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); @@ -74,6 +86,15 @@ int EditorModel::rowCount(const QModelIndex &parent) const return 0; } +QList<IEditor *> EditorModel::editors() const +{ + QList<IEditor *> result; + foreach (Entry entry, m_editors) + if (entry.editor) + result += entry.editor; + return result; +} + void EditorModel::addEditor(IEditor *editor, bool isDuplicate) { if (isDuplicate) { @@ -81,23 +102,69 @@ void EditorModel::addEditor(IEditor *editor, bool isDuplicate) return; } - int index = 0; + Entry entry; + entry.editor = editor; + addEntry(entry); +} + +void EditorModel::addRestoredEditor(const QString &fileName, const QString &displayName, const QByteArray &kind) +{ + Entry entry; + entry.m_fileName = fileName; + entry.m_displayName = displayName; + entry.m_kind = kind; + addEntry(entry); +} - QString fileName = editor->file()->fileName(); - for (index = 0; index < m_editors.count(); ++index) - if (fileName < m_editors.at(index)->file()->fileName()) +void EditorModel::addEntry(const Entry &entry) +{ + QString fileName = entry.fileName(); + + int previousIndex = findFileName(fileName); + if (previousIndex >= 0) { + if (entry.editor && m_editors.at(previousIndex).editor == 0) { + m_editors[previousIndex] = entry; + QModelIndex mindex = index(previousIndex, 0); + emit dataChanged(mindex, mindex); + } + return; + } + + int index; + for (index = 0; index < m_editors.count(); ++index) { + if (fileName < m_editors.at(index).fileName()) break; + } beginInsertRows(QModelIndex(), index, index); - m_editors.insert(index, editor); - connect(editor, SIGNAL(changed()), this, SLOT(itemChanged())); + m_editors.insert(index, entry); + if (entry.editor) + connect(entry.editor, SIGNAL(changed()), this, SLOT(itemChanged())); endInsertRows(); } + +int EditorModel::findEditor(IEditor *editor) const +{ + for (int i = 0; i < m_editors.count(); ++i) + if (m_editors.at(i).editor == editor) + return i; + return -1; +} + +int EditorModel::findFileName(const QString &filename) const +{ + for (int i = 0; i < m_editors.count(); ++i) { + if (m_editors.at(i).fileName() == filename) + return i; + } + return -1; +} + void EditorModel::removeEditor(IEditor *editor) { m_duplicateEditors.removeAll(editor); - int idx = m_editors.indexOf(editor); + int idx = findEditor(editor); if (idx < 0) return; beginRemoveRows(QModelIndex(), idx, idx); @@ -114,9 +181,9 @@ bool EditorModel::isDuplicate(IEditor *editor) const IEditor *EditorModel::originalForDuplicate(IEditor *duplicate) const { IFile *file = duplicate->file(); - foreach(IEditor *e, m_editors) - if (e->file() == file) - return e; + foreach(Entry e, m_editors) + if (e.editor && e.editor->file() == file) + return e.editor; return 0; } @@ -132,7 +199,7 @@ QList<IEditor *> EditorModel::duplicatesFor(IEditor *editor) const void EditorModel::emitDataChanged(IEditor *editor) { - int idx = m_editors.indexOf(editor); + int idx = findEditor(editor); if (idx < 0) return; QModelIndex mindex = index(idx, 0); @@ -151,23 +218,26 @@ QVariant EditorModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); - IEditor *editor = m_editors.at(index.row()); - QTC_ASSERT(editor, return QVariant()); + Entry e = m_editors.at(index.row()); switch (role) { case Qt::DisplayRole: - return editor->file()->isModified() - ? editor->displayName() + QLatin1String("*") - : editor->displayName(); + return (e.editor && e.editor->file()->isModified()) + ? e.displayName() + QLatin1String("*") + : e.displayName(); case Qt::DecorationRole: - return editor->file()->isReadOnly() + return (e.editor && e.editor->file()->isReadOnly()) ? QIcon(QLatin1String(":/core/images/locked.png")) : QIcon(); case Qt::ToolTipRole: - return editor->file()->fileName().isEmpty() - ? editor->displayName() - : QDir::toNativeSeparators(editor->file()->fileName()); + return e.fileName().isEmpty() + ? e.displayName() + : QDir::toNativeSeparators(e.fileName()); case Qt::UserRole: - return qVariantFromValue(editor); + return qVariantFromValue(e.editor); + case Qt::UserRole + 1: + return e.fileName(); + case Qt::UserRole + 2: + return e.editor ? QByteArray(e.editor->kind()) : e.kind(); default: return QVariant(); } @@ -176,7 +246,7 @@ QVariant EditorModel::data(const QModelIndex &index, int role) const QModelIndex EditorModel::indexOf(IEditor *editor) const { - int idx = m_editors.indexOf(editor); + int idx = findEditor(editor); if (idx < 0) return indexOf(editor->file()->fileName()); return createIndex(idx, 0); @@ -184,9 +254,9 @@ QModelIndex EditorModel::indexOf(IEditor *editor) const QModelIndex EditorModel::indexOf(const QString &fileName) const { - for (int i = 0; i < m_editors.count(); ++i) - if (m_editors.at(i)->file()->fileName() == fileName) - return createIndex(i, 0); + int idx = findFileName(fileName); + if (idx >= 0) + return createIndex(idx, 0); return QModelIndex(); } @@ -524,9 +594,13 @@ void EditorView::makeEditorWritable() void EditorView::listSelectionActivated(int index) { + EditorManager *em = CoreImpl::instance()->editorManager(); QAbstractItemModel *model = m_editorList->model(); - IEditor *editor = model->data(model->index(index, 0), Qt::UserRole).value<IEditor*>(); - CoreImpl::instance()->editorManager()->activateEditor(this, editor); + if (IEditor *editor = model->data(model->index(index, 0), Qt::UserRole).value<IEditor*>()) { + em->activateEditor(this, editor); + } else { + em->activateEditor(model->index(index, 0), this); + } } diff --git a/src/plugins/coreplugin/editormanager/editorview.h b/src/plugins/coreplugin/editormanager/editorview.h index e6f7472d0d7..bc1f5a6e316 100644 --- a/src/plugins/coreplugin/editormanager/editorview.h +++ b/src/plugins/coreplugin/editormanager/editorview.h @@ -70,11 +70,24 @@ public: QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const; void addEditor(IEditor *editor, bool isDuplicate = false); + void addRestoredEditor(const QString &fileName, const QString &displayName, const QByteArray &kind); + + struct Entry { + Entry():editor(0){} + IEditor *editor; + QString fileName() const; + QString displayName() const; + QByteArray kind() const; + QString m_fileName; + QString m_displayName; + QByteArray m_kind; + }; + QList<Entry> entries() const { return m_editors; } void removeEditor(IEditor *editor); void emitDataChanged(IEditor *editor); - QList<IEditor *> editors() const { return m_editors; } + QList<IEditor *> editors() const; bool isDuplicate(IEditor *editor) const; QList<IEditor *> duplicatesFor(IEditor *editor) const; IEditor *originalForDuplicate(IEditor *duplicate) const; @@ -83,8 +96,12 @@ public: private slots: void itemChanged(); + private: - QList<IEditor *> m_editors; + void addEntry(const Entry &entry); + int findEditor(IEditor *editor) const; + int findFileName(const QString &filename) const; + QList<Entry> m_editors; QList<IEditor *>m_duplicateEditors; }; diff --git a/src/plugins/coreplugin/editormanager/openeditorsview.cpp b/src/plugins/coreplugin/editormanager/openeditorsview.cpp index 463ebf4390f..af10e6096f1 100644 --- a/src/plugins/coreplugin/editormanager/openeditorsview.cpp +++ b/src/plugins/coreplugin/editormanager/openeditorsview.cpp @@ -93,8 +93,7 @@ void OpenEditorsWidget::updateCurrentItem(Core::IEditor *editor) void OpenEditorsWidget::selectEditor(const QModelIndex &index) { - IEditor *editor = index.data(Qt::UserRole).value<IEditor*>(); - EditorManager::instance()->activateEditor(editor); + EditorManager::instance()->activateEditor(index); } diff --git a/src/plugins/coreplugin/editormanager/openeditorswindow.cpp b/src/plugins/coreplugin/editormanager/openeditorswindow.cpp index 3fadcf836f1..b91e3a0de3e 100644 --- a/src/plugins/coreplugin/editormanager/openeditorswindow.cpp +++ b/src/plugins/coreplugin/editormanager/openeditorswindow.cpp @@ -29,6 +29,7 @@ #include "openeditorswindow.h" #include "editormanager.h" +#include "editorview.h" #include <QtGui/QHeaderView> @@ -43,8 +44,7 @@ const int OpenEditorsWindow::MARGIN = 4; OpenEditorsWindow::OpenEditorsWindow(QWidget *parent) : QWidget(parent, Qt::Popup), - m_editorList(new QTreeWidget(this)), - m_current(0) + m_editorList(new QTreeWidget(this)) { resize(QSize(WIDTH, HEIGHT)); m_editorList->setColumnCount(1); @@ -113,8 +113,6 @@ bool OpenEditorsWindow::eventFilter(QObject *obj, QEvent *e) if (e->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast<QKeyEvent*>(e); if (ke->key() == Qt::Key_Escape) { - m_current = EditorManager::instance()->currentEditor(); - updateSelectedEditor(); setVisible(false); return true; } @@ -140,7 +138,7 @@ void OpenEditorsWindow::selectUpDown(bool up) int index = m_editorList->indexOfTopLevelItem(m_editorList->currentItem()); if (index < 0) return; - IEditor *editor = 0; + QTreeWidgetItem *editor = 0; int count = 0; while (!editor && count < itemCount) { if (up) { @@ -152,12 +150,13 @@ void OpenEditorsWindow::selectUpDown(bool up) if (index >= itemCount) index = 0; } - editor = m_editorList->topLevelItem(index) - ->data(0, Qt::UserRole).value<IEditor *>(); + editor = m_editorList->topLevelItem(index); count++; } - if (editor) - setSelectedEditor(editor); + if (editor) { + m_editorList->setCurrentItem(editor); + ensureCurrentVisible(); + } } void OpenEditorsWindow::selectPreviousEditor() @@ -188,7 +187,7 @@ void OpenEditorsWindow::centerOnItem(int selectedIndex) } } -void OpenEditorsWindow::setEditors(const QList<IEditor *>&editors, IEditor *current) +void OpenEditorsWindow::setEditors(const QList<IEditor *>&editors, IEditor *current, EditorModel *model) { static const QIcon lockedIcon(QLatin1String(":/core/images/locked.png")); static const QIcon emptyIcon(QLatin1String(":/core/images/empty14.png")); @@ -214,24 +213,40 @@ void OpenEditorsWindow::setEditors(const QList<IEditor *>&editors, IEditor *curr item->setText(0, title); item->setToolTip(0, editor->file()->fileName()); item->setData(0, Qt::UserRole, QVariant::fromValue(editor)); - //item->setFlags(Qt::ItemIsSelectable); - item->setTextAlignment(0, Qt::AlignLeft); m_editorList->addTopLevelItem(item); + if (editor == current) + m_editorList->setCurrentItem(item); + + } + + // add purely restored editors which are not initialised yet + foreach (EditorModel::Entry entry, model->entries()) { + if (entry.editor) + return; + QTreeWidgetItem *item = new QTreeWidgetItem(); + QString title = entry.displayName(); + item->setIcon(0, emptyIcon); + item->setText(0, title); + item->setToolTip(0, entry.fileName()); + item->setData(0, Qt::UserRole+1, QVariant::fromValue(entry.kind())); + item->setTextAlignment(0, Qt::AlignLeft); + + m_editorList->addTopLevelItem(item); } - setSelectedEditor(current); } void OpenEditorsWindow::selectEditor(QTreeWidgetItem *item) { - IEditor *editor = 0; - if (item) - editor = item->data(0, Qt::UserRole).value<IEditor*>(); - if (editor) + 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()); } void OpenEditorsWindow::editorClicked(QTreeWidgetItem *item) @@ -241,27 +256,8 @@ void OpenEditorsWindow::editorClicked(QTreeWidgetItem *item) } -void OpenEditorsWindow::setSelectedEditor(IEditor *editor) -{ - m_current = editor; - updateSelectedEditor(); -} - -void OpenEditorsWindow::updateSelectedEditor() +void OpenEditorsWindow::ensureCurrentVisible() { - if (m_current == 0 && m_editorList->currentItem()) { - m_editorList->currentItem()->setSelected(false); - return; - } - int num = m_editorList->topLevelItemCount(); - for (int i = 0; i < num; ++i) { - IEditor *editor = m_editorList->topLevelItem(i) - ->data(0, Qt::UserRole).value<IEditor *>(); - if (editor == m_current) { - m_editorList->setCurrentItem(m_editorList->topLevelItem(i)); - break; - } - } m_editorList->scrollTo(m_editorList->currentIndex(), QAbstractItemView::PositionAtCenter); } diff --git a/src/plugins/coreplugin/editormanager/openeditorswindow.h b/src/plugins/coreplugin/editormanager/openeditorswindow.h index 6c376e6e9d3..7d0d9c623b5 100644 --- a/src/plugins/coreplugin/editormanager/openeditorswindow.h +++ b/src/plugins/coreplugin/editormanager/openeditorswindow.h @@ -43,6 +43,8 @@ class IEditor; namespace Internal { +class EditorModel; + class OpenEditorsWindow : public QWidget { Q_OBJECT @@ -53,7 +55,7 @@ public: OpenEditorsWindow(QWidget *parent = 0); ~OpenEditorsWindow() {} - void setEditors(const QList<IEditor *>&editors, IEditor *current); + void setEditors(const QList<IEditor *>&editors, IEditor *current, EditorModel *model); bool event(QEvent *e); bool eventFilter(QObject *src, QEvent *e); @@ -61,8 +63,6 @@ public: void setVisible(bool visible); void selectNextEditor(); void selectPreviousEditor(); - IEditor *selectedEditor() const { return m_current; } - void setSelectedEditor(IEditor *); private slots: void editorClicked(QTreeWidgetItem *item); @@ -75,7 +75,7 @@ private: static const int MARGIN; static void updateItem(QTreeWidgetItem *item, IEditor *editor); - void updateSelectedEditor(); + void ensureCurrentVisible(); bool isCentering(); void centerOnItem(int selectedIndex); void selectUpDown(bool up); @@ -84,7 +84,6 @@ private: QTreeWidget *m_editorList; QTimer m_autoHide; - IEditor *m_current; }; } // namespace Internal -- GitLab