Commit 3f9580fe authored by mae's avatar mae
Browse files

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.
parent 1f32ba92
......@@ -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;
......
......@@ -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;
......
......@@ -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);
}
}
......
......@@ -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;
};
......
......@@ -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);
}
......
......@@ -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);
}
......@@ -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
......