From 3557603b1ef30edb57901948c6d1038d6b49b7ad Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 3 Jul 2013 17:18:06 +0200 Subject: [PATCH] Editors: Don't use model index outside of model/view. The model index is an internal detail of the model/view and shouldn't be used outside that context. Change-Id: I2c1f742fff427484f6ff244dd3e0d8428a7318d3 Reviewed-by: hjk Reviewed-by: Eike Ziller --- .../editormanager/editormanager.cpp | 114 ++++++------ .../coreplugin/editormanager/editormanager.h | 15 +- .../coreplugin/editormanager/editorview.cpp | 18 +- .../editormanager/openeditorsmodel.cpp | 173 ++++++++++-------- .../editormanager/openeditorsmodel.h | 27 +-- .../editormanager/openeditorsview.cpp | 19 +- .../editormanager/openeditorswindow.cpp | 10 +- src/plugins/coreplugin/editortoolbar.cpp | 23 ++- src/plugins/fakevim/fakevimplugin.cpp | 6 +- src/plugins/locator/opendocumentsfilter.cpp | 10 +- src/plugins/qmldesigner/designmodewidget.h | 1 - src/plugins/texteditor/findinopenfiles.cpp | 4 +- 12 files changed, 227 insertions(+), 193 deletions(-) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 52b2d7a2748..e55c7d05458 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -212,7 +212,7 @@ public: QAction *m_closeOtherEditorsContextAction; QAction *m_openGraphicalShellAction; QAction *m_openTerminalAction; - QModelIndex m_contextMenuEditorIndex; + OpenEditorsModel::Entry *m_contextMenuEntry; Internal::OpenEditorsWindow *m_windowPopup; Internal::EditorClosingCoreListener *m_coreListener; @@ -812,16 +812,16 @@ static void assignAction(QAction *self, QAction *other) self->setIconVisibleInMenu(other->isIconVisibleInMenu()); } -void EditorManager::addSaveAndCloseEditorActions(QMenu *contextMenu, const QModelIndex &editorIndex) +void EditorManager::addSaveAndCloseEditorActions(QMenu *contextMenu, OpenEditorsModel::Entry *entry) { QTC_ASSERT(contextMenu, return); - d->m_contextMenuEditorIndex = editorIndex; + d->m_contextMenuEntry = entry; assignAction(d->m_saveCurrentEditorContextAction, ActionManager::command(Constants::SAVE)->action()); assignAction(d->m_saveAsCurrentEditorContextAction, ActionManager::command(Constants::SAVEAS)->action()); assignAction(d->m_revertToSavedCurrentEditorContextAction, ActionManager::command(Constants::REVERTTOSAVED)->action()); - IEditor *editor = d->m_contextMenuEditorIndex.data(Qt::UserRole).value(); + IEditor *editor = entry ? entry->editor : 0; setupSaveActions(editor, d->m_saveCurrentEditorContextAction, @@ -835,25 +835,26 @@ void EditorManager::addSaveAndCloseEditorActions(QMenu *contextMenu, const QMode contextMenu->addSeparator(); - d->m_closeCurrentEditorContextAction->setText(editorIndex.isValid() - ? tr("Close \"%1\"").arg(editorIndex.data().toString()) + d->m_closeCurrentEditorContextAction->setText(entry + ? tr("Close \"%1\"").arg(entry->displayName()) : tr("Close Editor")); - d->m_closeOtherEditorsContextAction->setText(editorIndex.isValid() - ? tr("Close All Except \"%1\"").arg(editorIndex.data().toString()) + d->m_closeOtherEditorsContextAction->setText(entry + ? tr("Close All Except \"%1\"").arg(entry->displayName()) : tr("Close Other Editors")); - d->m_closeCurrentEditorContextAction->setEnabled(editorIndex.isValid()); - d->m_closeOtherEditorsContextAction->setEnabled(editorIndex.isValid()); + d->m_closeCurrentEditorContextAction->setEnabled(entry != 0); + d->m_closeOtherEditorsContextAction->setEnabled(entry != 0); d->m_closeAllEditorsContextAction->setEnabled(!openedEditors().isEmpty()); contextMenu->addAction(d->m_closeCurrentEditorContextAction); contextMenu->addAction(d->m_closeAllEditorsContextAction); contextMenu->addAction(d->m_closeOtherEditorsContextAction); } -void EditorManager::addNativeDirActions(QMenu *contextMenu, const QModelIndex &editorIndex) +void EditorManager::addNativeDirActions(QMenu *contextMenu, OpenEditorsModel::Entry *entry) { QTC_ASSERT(contextMenu, return); - d->m_openGraphicalShellAction->setEnabled(editorIndex.isValid()); - d->m_openTerminalAction->setEnabled(editorIndex.isValid()); + bool enabled = entry && !entry->fileName().isEmpty(); + d->m_openGraphicalShellAction->setEnabled(enabled); + d->m_openTerminalAction->setEnabled(enabled); contextMenu->addAction(d->m_openGraphicalShellAction); contextMenu->addAction(d->m_openTerminalAction); } @@ -953,45 +954,50 @@ void EditorManager::doEscapeKeyFocusMoveMagic() void EditorManager::saveDocumentFromContextMenu() { - IEditor *editor = d->m_contextMenuEditorIndex.data(Qt::UserRole).value(); + IEditor *editor = d->m_contextMenuEntry ? d->m_contextMenuEntry->editor : 0; if (editor) saveDocument(editor->document()); } void EditorManager::saveDocumentAsFromContextMenu() { - IEditor *editor = d->m_contextMenuEditorIndex.data(Qt::UserRole).value(); + IEditor *editor = d->m_contextMenuEntry ? d->m_contextMenuEntry->editor : 0; if (editor) saveDocumentAs(editor->document()); } void EditorManager::revertToSavedFromContextMenu() { - IEditor *editor = d->m_contextMenuEditorIndex.data(Qt::UserRole).value(); + IEditor *editor = d->m_contextMenuEntry ? d->m_contextMenuEntry->editor : 0; if (editor) revertToSaved(editor); } void EditorManager::closeEditorFromContextMenu() { - closeEditor(d->m_contextMenuEditorIndex); + IEditor *editor = d->m_contextMenuEntry ? d->m_contextMenuEntry->editor : 0; + if (editor) + closeEditor(editor); } void EditorManager::closeOtherEditorsFromContextMenu() { - closeOtherEditors(d->m_contextMenuEditorIndex.data(Qt::UserRole).value()); + IEditor *editor = d->m_contextMenuEntry ? d->m_contextMenuEntry->editor : 0; + closeOtherEditors(editor); } void EditorManager::showInGraphicalShell() { - const QString path = d->m_contextMenuEditorIndex.data(Qt::UserRole + 1).toString(); - Core::FileUtils::showInGraphicalShell(ICore::mainWindow(), path); + if (!d->m_contextMenuEntry || d->m_contextMenuEntry->fileName().isEmpty()) + return; + Core::FileUtils::showInGraphicalShell(ICore::mainWindow(), d->m_contextMenuEntry->fileName()); } void EditorManager::openTerminal() { - const QString path = QFileInfo(d->m_contextMenuEditorIndex.data(Qt::UserRole + 1).toString()).path(); - Core::FileUtils::openTerminal(path); + if (!d->m_contextMenuEntry || d->m_contextMenuEntry->fileName().isEmpty()) + return; + Core::FileUtils::openTerminal(QFileInfo(d->m_contextMenuEntry->fileName()).path()); } void EditorManager::rootDestroyed(QObject *root) @@ -1057,13 +1063,14 @@ void EditorManager::closeEditor(Core::IEditor *editor) closeEditors(QList() << editor); } -void EditorManager::closeEditor(const QModelIndex &index) +void EditorManager::closeEditor(OpenEditorsModel::Entry *entry) { - IEditor *editor = index.data(Qt::UserRole).value(); - if (editor) - closeEditor(editor); + if (!entry) + return; + if (entry->editor) + closeEditor(entry->editor); else - d->m_editorModel->removeEditor(index); + d->m_editorModel->removeEntry(entry); } bool EditorManager::closeEditors(const QList &editorsToClose, bool askAboutModifiedEditors) @@ -1143,20 +1150,26 @@ bool EditorManager::closeEditors(const QList &editorsToClose, bool ask } } + bool currentViewHandled = false; foreach (EditorView *view, closedViews) { + OpenEditorFlags flags; + if (view == currentView) + currentViewHandled = true; + else + flags = OpenEditorFlags(DoNotChangeCurrentEditor); IEditor *newCurrent = view->currentEditor(); if (!newCurrent) newCurrent = pickUnusedEditor(); if (newCurrent) { - activateEditor(view, newCurrent, DoNotChangeCurrentEditor); + activateEditor(view, newCurrent, flags); } else { - QModelIndex idx = d->m_editorModel->firstRestoredEditor(); - if (idx.isValid()) { - activateEditorForIndex(view, idx, DoNotChangeCurrentEditor); + OpenEditorsModel::Entry *entry = d->m_editorModel->firstRestoredEditor(); + if (entry) { + activateEditorForEntry(view, entry, flags); } else { const QList editors = d->m_editorModel->editors(); if (!editors.isEmpty()) - activateEditor(view, editors.last(), DoNotChangeCurrentEditor); + activateEditor(view, editors.last(), flags); } } } @@ -1167,7 +1180,7 @@ bool EditorManager::closeEditors(const QList &editorsToClose, bool ask delete editor; } - if (currentView) { + if (currentView && !currentViewHandled) { if (IEditor *editor = currentView->currentEditor()) activateEditor(currentView, editor); else @@ -1213,9 +1226,9 @@ void EditorManager::closeDuplicate(Core::IEditor *editor) if (newCurrent) { activateEditor(view, newCurrent, DoNotChangeCurrentEditor); } else { - QModelIndex idx = d->m_editorModel->firstRestoredEditor(); - if (idx.isValid()) - activateEditorForIndex(view, idx, DoNotChangeCurrentEditor); + OpenEditorsModel::Entry *entry = d->m_editorModel->firstRestoredEditor(); + if (entry) + activateEditorForEntry(view, entry, DoNotChangeCurrentEditor); } } @@ -1237,24 +1250,23 @@ Core::IEditor *EditorManager::pickUnusedEditor() const return 0; } -void EditorManager::activateEditorForIndex(const QModelIndex &index, OpenEditorFlags flags) +void EditorManager::activateEditorForEntry(OpenEditorsModel::Entry *entry, OpenEditorFlags flags) { - activateEditorForIndex(currentEditorView(), index, flags); + activateEditorForEntry(currentEditorView(), entry, flags); } -void EditorManager::activateEditorForIndex(Internal::EditorView *view, const QModelIndex &index, OpenEditorFlags flags) +void EditorManager::activateEditorForEntry(Internal::EditorView *view, OpenEditorsModel::Entry *entry, OpenEditorFlags flags) { - Q_ASSERT(view); - IEditor *editor = index.data(Qt::UserRole).value(); + QTC_ASSERT(view, return); + QTC_ASSERT(entry, return); + IEditor *editor = entry->editor; if (editor) { activateEditor(view, editor, flags); return; } - QString fileName = index.data(Qt::UserRole + 1).toString(); - Core::Id id = index.data(Qt::UserRole + 2).value(); - if (!openEditor(view, fileName, id, flags)) - d->m_editorModel->removeEditor(index); + if (!openEditor(view, entry->fileName(), entry->id(), flags)) + d->m_editorModel->removeEntry(entry); } void EditorManager::activateView(EditorView *view) @@ -2226,19 +2238,19 @@ QByteArray EditorManager::saveState() const stream << d->m_editorStates; - QList entries = d->m_editorModel->entries(); + QList entries = d->m_editorModel->entries(); int entriesCount = 0; - foreach (const OpenEditorsModel::Entry &entry, entries) { + foreach (OpenEditorsModel::Entry *entry, entries) { // The editor may be 0 if it was not loaded yet: In that case it is not temporary - if (!entry.editor || !entry.editor->isTemporary()) + if (!entry->editor || !entry->editor->isTemporary()) ++entriesCount; } stream << entriesCount; - foreach (const OpenEditorsModel::Entry &entry, entries) { - if (!entry.editor || !entry.editor->isTemporary()) - stream << entry.fileName() << entry.displayName() << entry.id(); + foreach (OpenEditorsModel::Entry *entry, entries) { + if (!entry->editor || !entry->editor->isTemporary()) + stream << entry->fileName() << entry->displayName() << entry->id(); } stream << d->m_root.first()->saveState(); // TODO diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h index 6321687b688..b9daf5ac51f 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -32,6 +32,8 @@ #include "../core_global.h" +#include "openeditorsmodel.h" + #include #include // enumerations @@ -40,7 +42,6 @@ #include QT_BEGIN_NAMESPACE -class QModelIndex; QT_END_NAMESPACE namespace Core { @@ -63,8 +64,6 @@ enum MakeWritableResult { Failed }; -class OpenEditorsModel; - namespace Internal { class EditorClosingCoreListener; class EditorView; @@ -132,11 +131,11 @@ public: QList openedEditors() const; static void activateEditor(IEditor *editor, OpenEditorFlags flags = 0); - void activateEditorForIndex(const QModelIndex &index, OpenEditorFlags = 0); + void activateEditorForEntry(OpenEditorsModel::Entry *entry, OpenEditorFlags flags = 0); IEditor *activateEditorForDocument(Internal::EditorView *view, IDocument *document, OpenEditorFlags flags = 0); OpenEditorsModel *openedEditorsModel() const; - void closeEditor(const QModelIndex &index); + void closeEditor(OpenEditorsModel::Entry *entry); void closeOtherEditors(IEditor *editor); QList editorsForDocuments(QList documents) const; @@ -184,8 +183,8 @@ public: void setWindowTitleAddition(const QString &addition); QString windowTitleAddition() const; - void addSaveAndCloseEditorActions(QMenu *contextMenu, const QModelIndex &editorIndex); - void addNativeDirActions(QMenu *contextMenu, const QModelIndex &editorIndex); + void addSaveAndCloseEditorActions(QMenu *contextMenu, OpenEditorsModel::Entry *entry); + void addNativeDirActions(QMenu *contextMenu, OpenEditorsModel::Entry *entry); signals: void currentEditorChanged(Core::IEditor *editor); @@ -259,7 +258,7 @@ private: IEditor *placeEditor(Internal::EditorView *view, IEditor *editor); IEditor *duplicateEditor(IEditor *editor); IEditor *activateEditor(Internal::EditorView *view, IEditor *editor, OpenEditorFlags flags = 0); - void activateEditorForIndex(Internal::EditorView *view, const QModelIndex &index, OpenEditorFlags = 0); + void activateEditorForEntry(Internal::EditorView *view, OpenEditorsModel::Entry *entry, OpenEditorFlags flags = 0); void activateView(Internal::EditorView *view); IEditor *openEditor(Internal::EditorView *view, const QString &fileName, const Id &id = Id(), OpenEditorFlags flags = 0, bool *newEditor = 0); diff --git a/src/plugins/coreplugin/editormanager/editorview.cpp b/src/plugins/coreplugin/editormanager/editorview.cpp index 4da158eb376..26ddfb2e510 100644 --- a/src/plugins/coreplugin/editormanager/editorview.cpp +++ b/src/plugins/coreplugin/editormanager/editorview.cpp @@ -291,15 +291,15 @@ void EditorView::removeEditor(IEditor *editor) IEditor *EditorView::currentEditor() const { - if (m_container->count() > 0) + if (m_editors.size() > 0) return m_widgetEditorMap.value(m_container->currentWidget()); return 0; } void EditorView::listSelectionActivated(int index) { - QAbstractItemModel *model = EditorManager::instance()->openedEditorsModel(); - EditorManager::instance()->activateEditorForIndex(this, model->index(index, 0)); + OpenEditorsModel *model = EditorManager::instance()->openedEditorsModel(); + EditorManager::instance()->activateEditorForEntry(this, model->entryAtRow(index)); } void EditorView::splitHorizontally() @@ -338,7 +338,7 @@ void EditorView::setParentSplitterOrView(SplitterOrView *splitterOrView) void EditorView::setCurrentEditor(IEditor *editor) { if (!editor || m_container->count() <= 0 - || m_container->indexOf(editor->widget()) == -1) { + || m_container->indexOf(editor->widget()) == -1) { m_toolBar->updateEditorStatus(0); m_infoBarDisplay->setInfoBar(0); QTC_CHECK(m_container->count() == 0); @@ -360,12 +360,12 @@ void EditorView::setCurrentEditor(IEditor *editor) int EditorView::editorCount() const { - return m_container->count(); + return m_editors.size(); } QList EditorView::editors() const { - return m_widgetEditorMap.values(); + return m_editors; } void EditorView::updateEditorHistory(IEditor *editor) @@ -788,9 +788,9 @@ void SplitterOrView::restoreState(const QByteArray &state) | Core::EditorManager::DoNotChangeCurrentEditor); if (!e) { - QModelIndex idx = em->openedEditorsModel()->firstRestoredEditor(); - if (idx.isValid()) - em->activateEditorForIndex(view(), idx, Core::EditorManager::IgnoreNavigationHistory + OpenEditorsModel::Entry *entry = em->openedEditorsModel()->firstRestoredEditor(); + if (entry) + em->activateEditorForEntry(view(), entry, Core::EditorManager::IgnoreNavigationHistory | Core::EditorManager::DoNotChangeCurrentEditor); } diff --git a/src/plugins/coreplugin/editormanager/openeditorsmodel.cpp b/src/plugins/coreplugin/editormanager/openeditorsmodel.cpp index aa226066a3f..51e7736514d 100644 --- a/src/plugins/coreplugin/editormanager/openeditorsmodel.cpp +++ b/src/plugins/coreplugin/editormanager/openeditorsmodel.cpp @@ -31,6 +31,8 @@ #include "ieditor.h" #include "idocument.h" +#include + #include #include @@ -43,7 +45,7 @@ struct OpenEditorsModelPrivate const QIcon m_lockedIcon; const QIcon m_unlockedIcon; - QList m_editors; + QList m_editors; QList m_duplicateEditors; }; @@ -93,8 +95,9 @@ Id OpenEditorsModel::Entry::id() const int OpenEditorsModel::columnCount(const QModelIndex &parent) const { - Q_UNUSED(parent) - return 2; + if (!parent.isValid()) + return 2; + return 0; } int OpenEditorsModel::rowCount(const QModelIndex &parent) const @@ -107,9 +110,9 @@ int OpenEditorsModel::rowCount(const QModelIndex &parent) const QList OpenEditorsModel::editors() const { QList result; - foreach (const Entry &entry, d->m_editors) - if (entry.editor) - result += entry.editor; + foreach (const Entry *entry, d->m_editors) + if (entry->editor) + result += entry->editor; return result; } @@ -123,52 +126,52 @@ void OpenEditorsModel::addEditor(IEditor *editor, bool isDuplicate) return; } - Entry entry; - entry.editor = editor; + Entry *entry = new Entry; + entry->editor = editor; addEntry(entry); } void OpenEditorsModel::addRestoredEditor(const QString &fileName, const QString &displayName, const Id &id) { - Entry entry; - entry.m_fileName = fileName; - entry.m_displayName = displayName; - entry.m_id = id; + Entry *entry = new Entry; + entry->m_fileName = fileName; + entry->m_displayName = displayName; + entry->m_id = id; addEntry(entry); } -QModelIndex OpenEditorsModel::firstRestoredEditor() const +OpenEditorsModel::Entry *OpenEditorsModel::firstRestoredEditor() const { for (int i = 0; i < d->m_editors.count(); ++i) - if (!d->m_editors.at(i).editor) - return createIndex(i, 0); - return QModelIndex(); + if (!d->m_editors.at(i)->editor) + return d->m_editors.at(i); + return 0; } -void OpenEditorsModel::addEntry(const Entry &entry) +void OpenEditorsModel::addEntry(Entry *entry) { - QString fileName = entry.fileName(); + QString fileName = entry->fileName(); int previousIndex = findFileName(fileName); if (previousIndex >= 0) { - if (entry.editor && d->m_editors.at(previousIndex).editor == 0) { + if (entry->editor && d->m_editors.at(previousIndex)->editor == 0) { d->m_editors[previousIndex] = entry; - connect(entry.editor, SIGNAL(changed()), this, SLOT(itemChanged())); + connect(entry->editor, SIGNAL(changed()), this, SLOT(itemChanged())); } return; } int index; - QString displayName = entry.displayName(); + QString displayName = entry->displayName(); for (index = 0; index < d->m_editors.count(); ++index) { - if (displayName < d->m_editors.at(index).displayName()) + if (displayName < d->m_editors.at(index)->displayName()) break; } - - beginInsertRows(QModelIndex(), index, index); + int row = index + 1/**/; + beginInsertRows(QModelIndex(), row, row); d->m_editors.insert(index, entry); - if (entry.editor) - connect(entry.editor, SIGNAL(changed()), this, SLOT(itemChanged())); + if (entry->editor) + connect(entry->editor, SIGNAL(changed()), this, SLOT(itemChanged())); endInsertRows(); } @@ -176,7 +179,7 @@ void OpenEditorsModel::addEntry(const Entry &entry) int OpenEditorsModel::findEditor(IEditor *editor) const { for (int i = 0; i < d->m_editors.count(); ++i) - if (d->m_editors.at(i).editor == editor) + if (d->m_editors.at(i)->editor == editor) return i; return -1; } @@ -186,23 +189,24 @@ int OpenEditorsModel::findFileName(const QString &filename) const if (filename.isEmpty()) return -1; for (int i = 0; i < d->m_editors.count(); ++i) { - if (d->m_editors.at(i).fileName() == filename) + if (d->m_editors.at(i)->fileName() == filename) return i; } return -1; } +void OpenEditorsModel::removeEntry(OpenEditorsModel::Entry *entry) +{ + int index = d->m_editors.indexOf(entry); + removeEditor(index); +} + void OpenEditorsModel::removeEditor(IEditor *editor) { d->m_duplicateEditors.removeAll(editor); removeEditor(findEditor(editor)); } -void OpenEditorsModel::removeEditor(const QModelIndex &index) -{ - removeEditor(index.row()); -} - void OpenEditorsModel::removeEditor(const QString &fileName) { removeEditor(findFileName(fileName)); @@ -210,10 +214,11 @@ void OpenEditorsModel::removeEditor(const QString &fileName) void OpenEditorsModel::removeEditor(int idx) { - if (idx < 0) + if (idx < 0 || idx >= d->m_editors.size()) return; - IEditor *editor= d->m_editors.at(idx).editor; - beginRemoveRows(QModelIndex(), idx, idx); + IEditor *editor = d->m_editors.at(idx)->editor; + int row = idx; + beginRemoveRows(QModelIndex(), row, row); d->m_editors.removeAt(idx); endRemoveRows(); if (editor) @@ -223,24 +228,15 @@ void OpenEditorsModel::removeEditor(int idx) void OpenEditorsModel::removeAllRestoredEditors() { for (int i = d->m_editors.count()-1; i >= 0; --i) { - if (!d->m_editors.at(i).editor) { - beginRemoveRows(QModelIndex(), i, i); + if (!d->m_editors.at(i)->editor) { + int row = i; + beginRemoveRows(QModelIndex(), row, row); d->m_editors.removeAt(i); endRemoveRows(); } } } -QList OpenEditorsModel::restoredEditors() const -{ - QList result; - for (int i = d->m_editors.count()-1; i >= 0; --i) { - if (!d->m_editors.at(i).editor) - result.append(d->m_editors.at(i)); - } - return result; -} - bool OpenEditorsModel::isDuplicate(IEditor *editor) const { return editor && d->m_duplicateEditors.contains(editor); @@ -249,9 +245,9 @@ bool OpenEditorsModel::isDuplicate(IEditor *editor) const IEditor *OpenEditorsModel::originalForDuplicate(IEditor *duplicate) const { IDocument *document = duplicate->document(); - foreach (const Entry &e, d->m_editors) - if (e.editor && e.editor->document() == document) - return e.editor; + foreach (const Entry *e, d->m_editors) + if (e->editor && e->editor->document() == document) + return e->editor; return 0; } @@ -271,13 +267,20 @@ void OpenEditorsModel::makeOriginal(IEditor *duplicate) IEditor *original = originalForDuplicate(duplicate); Q_ASSERT(original); int i = findEditor(original); - d->m_editors[i].editor = duplicate; + d->m_editors[i]->editor = duplicate; d->m_duplicateEditors.removeOne(duplicate); d->m_duplicateEditors.append(original); disconnect(original, SIGNAL(changed()), this, SLOT(itemChanged())); connect(duplicate, SIGNAL(changed()), this, SLOT(itemChanged())); } +int OpenEditorsModel::indexOfEditor(IEditor *editor) const +{ + if (!editor) + return -1; + return findEditor(editor); +} + void OpenEditorsModel::emitDataChanged(IEditor *editor) { int idx = findEditor(editor); @@ -295,6 +298,14 @@ QModelIndex OpenEditorsModel::index(int row, int column, const QModelIndex &pare return createIndex(row, column); } +OpenEditorsModel::Entry *OpenEditorsModel::entryAtRow(int row) const +{ + int editorIndex = row; + if (editorIndex < 0) + return 0; + return d->m_editors[editorIndex]; +} + int OpenEditorsModel::openDocumentCount() const { return d->m_editors.count(); @@ -304,51 +315,64 @@ QVariant OpenEditorsModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || (index.column() != 0 && role < Qt::UserRole)) return QVariant(); - Entry e = d->m_editors.at(index.row()); + int editorIndex = index.row(); + if (editorIndex < 0) { + // entry + switch (role) { + case Qt::DisplayRole: + return tr(""); + case Qt::ToolTipRole: + return tr("No document is selected."); + default: + return QVariant(); + } + } + const Entry *e = d->m_editors.at(editorIndex); switch (role) { case Qt::DisplayRole: - return (e.editor && e.editor->document()->isModified()) - ? e.displayName() + QLatin1Char('*') - : e.displayName(); + return (e->editor && e->editor->document()->isModified()) + ? e->displayName() + QLatin1Char('*') + : e->displayName(); case Qt::DecorationRole: { bool showLock = false; - if (e.editor) { - showLock = e.editor->document()->fileName().isEmpty() + if (e->editor) { + showLock = e->editor->document()->fileName().isEmpty() ? false - : e.editor->document()->isFileReadOnly(); + : e->editor->document()->isFileReadOnly(); } else { - showLock = !QFileInfo(e.m_fileName).isWritable(); + showLock = !QFileInfo(e->m_fileName).isWritable(); } return showLock ? d->m_lockedIcon : QIcon(); } case Qt::ToolTipRole: - return e.fileName().isEmpty() - ? e.displayName() - : QDir::toNativeSeparators(e.fileName()); + return e->fileName().isEmpty() + ? e->displayName() + : QDir::toNativeSeparators(e->fileName()); case Qt::UserRole: - return qVariantFromValue(e.editor); + return qVariantFromValue(e->editor); case Qt::UserRole + 1: - return e.fileName(); + return e->fileName(); case Qt::UserRole + 2: - return QVariant::fromValue(e.editor ? Core::Id(e.editor->id()) : e.id()); + return QVariant::fromValue(e->editor ? Core::Id(e->editor->id()) : e->id()); default: return QVariant(); } return QVariant(); } -QModelIndex OpenEditorsModel::indexOf(IEditor *editor) const +int OpenEditorsModel::rowOfEditor(IEditor *editor) const { - int idx = findEditor(originalForDuplicate(editor)); - return createIndex(idx, 0); + if (!editor) + return -1; + return findEditor(originalForDuplicate(editor)); } QString OpenEditorsModel::displayNameForDocument(IDocument *document) const { for (int i = 0; i < d->m_editors.count(); ++i) - if (d->m_editors.at(i).editor && d->m_editors.at(i).editor->document() == document) - return d->m_editors.at(i).editor->displayName(); + if (d->m_editors.at(i)->editor && d->m_editors.at(i)->editor->document() == document) + return d->m_editors.at(i)->editor->displayName(); return QString(); } @@ -357,14 +381,9 @@ void OpenEditorsModel::itemChanged() emitDataChanged(qobject_cast(sender())); } -QList OpenEditorsModel::entries() const +QList OpenEditorsModel::entries() const { return d->m_editors; } -IEditor *OpenEditorsModel::editorAt(int row) const -{ - return d->m_editors.at(row).editor; -} - } // namespace Core diff --git a/src/plugins/coreplugin/editormanager/openeditorsmodel.h b/src/plugins/coreplugin/editormanager/openeditorsmodel.h index 01d8aec3110..2edb31d4bb6 100644 --- a/src/plugins/coreplugin/editormanager/openeditorsmodel.h +++ b/src/plugins/coreplugin/editormanager/openeditorsmodel.h @@ -60,12 +60,6 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const; QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const; - int openDocumentCount() const; - - void addEditor(IEditor *editor, bool isDuplicate = false); - void addRestoredEditor(const QString &fileName, const QString &displayName, const Id &id); - QModelIndex firstRestoredEditor() const; - struct CORE_EXPORT Entry { Entry(); IEditor *editor; @@ -76,24 +70,30 @@ public: QString m_displayName; Id m_id; }; - QList entries() const; - IEditor *editorAt(int row) const; + Entry *entryAtRow(int row) const; + int rowOfEditor(IEditor *editor) const; + int openDocumentCount() const; + + void addEditor(IEditor *editor, bool isDuplicate = false); + void addRestoredEditor(const QString &fileName, const QString &displayName, const Id &id); + Entry *firstRestoredEditor() const; + + QList entries() const; + + void removeEntry(Entry *entry); void removeEditor(IEditor *editor); - void removeEditor(const QModelIndex &index); void removeEditor(const QString &fileName); void removeAllRestoredEditors(); - void emitDataChanged(IEditor *editor); QList editors() const; - QList restoredEditors() const; bool isDuplicate(IEditor *editor) const; QList duplicatesFor(IEditor *editor) const; IEditor *originalForDuplicate(IEditor *duplicate) const; void makeOriginal(IEditor *duplicate); - QModelIndex indexOf(IEditor *editor) const; + int indexOfEditor(IEditor *editor) const; QString displayNameForDocument(IDocument *document) const; @@ -101,10 +101,11 @@ private slots: void itemChanged(); private: - void addEntry(const Entry &entry); + void addEntry(Entry *entry); int findEditor(IEditor *editor) const; int findFileName(const QString &filename) const; void removeEditor(int idx); + void emitDataChanged(IEditor *editor); OpenEditorsModelPrivate *d; }; diff --git a/src/plugins/coreplugin/editormanager/openeditorsview.cpp b/src/plugins/coreplugin/editormanager/openeditorsview.cpp index 0b6dacba5bd..c0b1858fe34 100644 --- a/src/plugins/coreplugin/editormanager/openeditorsview.cpp +++ b/src/plugins/coreplugin/editormanager/openeditorsview.cpp @@ -124,12 +124,13 @@ OpenEditorsWidget::~OpenEditorsWidget() void OpenEditorsWidget::updateCurrentItem(Core::IEditor *editor) { - if (!editor) { + EditorManager *em = EditorManager::instance(); + QModelIndex index = model()->index(em->openedEditorsModel()->rowOfEditor(editor), 0); + if (!index.isValid()) { clearSelection(); return; } - EditorManager *em = EditorManager::instance(); - setCurrentIndex(em->openedEditorsModel()->indexOf(editor)); + setCurrentIndex(index); selectionModel()->select(currentIndex(), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); scrollTo(currentIndex()); @@ -189,12 +190,14 @@ void OpenEditorsWidget::handleClicked(const QModelIndex &index) void OpenEditorsWidget::activateEditor(const QModelIndex &index) { selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); - EditorManager::instance()->activateEditorForIndex(index); + EditorManager *em = EditorManager::instance(); + em->activateEditorForEntry(em->openedEditorsModel()->entryAtRow(index.row())); } void OpenEditorsWidget::closeEditor(const QModelIndex &index) { - EditorManager::instance()->closeEditor(index); + EditorManager *em = EditorManager::instance(); + em->closeEditor(em->openedEditorsModel()->entryAtRow(index.row())); // work around selection changes updateCurrentItem(EditorManager::currentEditor()); } @@ -203,9 +206,11 @@ void OpenEditorsWidget::contextMenuRequested(QPoint pos) { QMenu contextMenu; QModelIndex editorIndex = indexAt(pos); - EditorManager::instance()->addSaveAndCloseEditorActions(&contextMenu, editorIndex); + OpenEditorsModel::Entry *entry = EditorManager::instance()->openedEditorsModel()->entryAtRow( + editorIndex.row()); + EditorManager::instance()->addSaveAndCloseEditorActions(&contextMenu, entry); contextMenu.addSeparator(); - EditorManager::instance()->addNativeDirActions(&contextMenu, editorIndex); + EditorManager::instance()->addNativeDirActions(&contextMenu, entry); contextMenu.exec(mapToGlobal(pos)); } diff --git a/src/plugins/coreplugin/editormanager/openeditorswindow.cpp b/src/plugins/coreplugin/editormanager/openeditorswindow.cpp index 1367c799a5a..a195dfac2fe 100644 --- a/src/plugins/coreplugin/editormanager/openeditorswindow.cpp +++ b/src/plugins/coreplugin/editormanager/openeditorswindow.cpp @@ -203,15 +203,15 @@ void OpenEditorsWindow::setEditors(const QList &globalHistory, Edi addHistoryItems(globalHistory, view, model, documentsDone); // add purely restored editors which are not initialised yet - foreach (const OpenEditorsModel::Entry &entry, model->entries()) { - if (entry.editor) + foreach (OpenEditorsModel::Entry *entry, model->entries()) { + if (entry->editor) continue; QTreeWidgetItem *item = new QTreeWidgetItem(); - QString title = entry.displayName(); + QString title = entry->displayName(); item->setIcon(0, m_emptyIcon); item->setText(0, title); - item->setToolTip(0, entry.fileName()); - item->setData(0, Qt::UserRole+2, QVariant::fromValue(entry.id())); + item->setToolTip(0, entry->fileName()); + item->setData(0, Qt::UserRole+2, QVariant::fromValue(entry->id())); item->setTextAlignment(0, Qt::AlignLeft); m_editorList->addTopLevelItem(item); diff --git a/src/plugins/coreplugin/editortoolbar.cpp b/src/plugins/coreplugin/editortoolbar.cpp index 9fd7e2ca828..dac5846cf88 100644 --- a/src/plugins/coreplugin/editortoolbar.cpp +++ b/src/plugins/coreplugin/editortoolbar.cpp @@ -290,13 +290,12 @@ void EditorToolBar::setToolbarCreationFlags(ToolbarCreationFlags flags) void EditorToolBar::setCurrentEditor(IEditor *editor) { - QTC_ASSERT(editor, return); - d->m_editorList->setCurrentIndex(d->m_editorsListModel->indexOf(editor).row()); + d->m_editorList->setCurrentIndex(d->m_editorsListModel->rowOfEditor(editor)); // If we never added the toolbar from the editor, we will never change // the editor, so there's no need to update the toolbar either. if (!d->m_isStandalone) - updateToolBar(editor->toolBar()); + updateToolBar(editor ? editor->toolBar() : 0); updateEditorStatus(editor); } @@ -304,28 +303,28 @@ void EditorToolBar::setCurrentEditor(IEditor *editor) void EditorToolBar::updateEditorListSelection(IEditor *newSelection) { if (newSelection) - d->m_editorList->setCurrentIndex(d->m_editorsListModel->indexOf(newSelection).row()); + d->m_editorList->setCurrentIndex(d->m_editorsListModel->rowOfEditor(newSelection)); } void EditorToolBar::changeActiveEditor(int row) { - EditorManager *em = ICore::editorManager(); - QAbstractItemModel *model = d->m_editorList->model(); - em->activateEditorForIndex(model->index(row, 0)); + EditorManager *em = EditorManager::instance(); + em->activateEditorForEntry(d->m_editorsListModel->entryAtRow(row)); } void EditorToolBar::listContextMenu(QPoint pos) { - QModelIndex index = d->m_editorsListModel->index(d->m_editorList->currentIndex(), 0); - QString fileName = d->m_editorsListModel->data(index, Qt::UserRole + 1).toString(); + OpenEditorsModel::Entry *entry = EditorManager::instance() + ->openedEditorsModel()->entryAtRow(d->m_editorList->currentIndex()); + QString fileName = entry ? entry->fileName() : QString(); if (fileName.isEmpty()) return; QMenu menu; QAction *copyPath = menu.addAction(tr("Copy Full Path to Clipboard")); menu.addSeparator(); - EditorManager::instance()->addSaveAndCloseEditorActions(&menu, index); + EditorManager::instance()->addSaveAndCloseEditorActions(&menu, entry); menu.addSeparator(); - EditorManager::instance()->addNativeDirActions(&menu, index); + EditorManager::instance()->addNativeDirActions(&menu, entry); QAction *result = menu.exec(d->m_editorList->mapToGlobal(pos)); if (result == copyPath) QApplication::clipboard()->setText(QDir::toNativeSeparators(fileName)); @@ -376,7 +375,7 @@ void EditorToolBar::updateEditorStatus(IEditor *editor) return; } - d->m_editorList->setCurrentIndex(d->m_editorsListModel->indexOf(editor).row()); + d->m_editorList->setCurrentIndex(d->m_editorsListModel->rowOfEditor(editor)); if (editor->document()->fileName().isEmpty()) { d->m_lockButton->setIcon(QIcon()); diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index 082125ff538..fae51543102 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -1999,19 +1999,19 @@ int FakeVimPluginPrivate::currentFile() const { OpenEditorsModel *model = EditorManager::instance()->openedEditorsModel(); IEditor *editor = EditorManager::currentEditor(); - return model->indexOf(editor).row(); + return model->indexOfEditor(editor); } void FakeVimPluginPrivate::switchToFile(int n) { EditorManager *editorManager = ICore::editorManager(); OpenEditorsModel *model = editorManager->openedEditorsModel(); - int size = model->rowCount(); + int size = model->openDocumentCount(); QTC_ASSERT(size, return); n = n % size; if (n < 0) n += size; - editorManager->activateEditorForIndex(model->index(n, 0)); + editorManager->activateEditorForEntry(model->entries().at(n)); } ExCommandMap &FakeVimExCommandsPage::exCommandMap() diff --git a/src/plugins/locator/opendocumentsfilter.cpp b/src/plugins/locator/opendocumentsfilter.cpp index c626b2de948..0e2a91fc6b4 100644 --- a/src/plugins/locator/opendocumentsfilter.cpp +++ b/src/plugins/locator/opendocumentsfilter.cpp @@ -87,14 +87,14 @@ QList OpenDocumentsFilter::matchesFor(QFutureInterfaceopenedEditors()) { + foreach (OpenEditorsModel::Entry *e, EditorManager::instance()->openedEditorsModel()->entries()) { OpenEditorsModel::Entry entry; - // don't work on IEditor directly, since that will be useless with split windows - entry.m_displayName = editor->displayName(); - entry.m_fileName = editor->document()->fileName(); + // create copy with only the information relevant to use + // to avoid model deleting entries behind our back + entry.m_displayName = e->displayName(); + entry.m_fileName = e->fileName(); m_editors.append(entry); } - m_editors += m_editorManager->openedEditorsModel()->restoredEditors(); } void OpenDocumentsFilter::refresh(QFutureInterface &future) diff --git a/src/plugins/qmldesigner/designmodewidget.h b/src/plugins/qmldesigner/designmodewidget.h index 58142ab8c3c..b4bfac4706f 100644 --- a/src/plugins/qmldesigner/designmodewidget.h +++ b/src/plugins/qmldesigner/designmodewidget.h @@ -51,7 +51,6 @@ QT_END_NAMESPACE namespace Core { class SideBar; class SideBarItem; - class OpenEditorsModel; class EditorToolBar; class OutputPanePlaceHolder; } diff --git a/src/plugins/texteditor/findinopenfiles.cpp b/src/plugins/texteditor/findinopenfiles.cpp index c109e17126b..2ef4414dec8 100644 --- a/src/plugins/texteditor/findinopenfiles.cpp +++ b/src/plugins/texteditor/findinopenfiles.cpp @@ -67,9 +67,9 @@ Utils::FileIterator *FindInOpenFiles::files(const QStringList &nameFilters, QMap openEditorEncodings = ITextEditor::openedTextEditorsEncodings(); QStringList fileNames; QList codecs; - foreach (const Core::OpenEditorsModel::Entry &entry, + foreach (Core::OpenEditorsModel::Entry *entry, Core::EditorManager::instance()->openedEditorsModel()->entries()) { - QString fileName = entry.fileName(); + QString fileName = entry->fileName(); if (!fileName.isEmpty()) { fileNames.append(fileName); QTextCodec *codec = openEditorEncodings.value(fileName);