forked from qt-creator/qt-creator
EditorManager: Move closeEditor implementation to private class
It's internal API will change soon Change-Id: Ib3290d4ac0622e39ecccfe673a485a4445739a4e Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
This commit is contained in:
@@ -1273,6 +1273,144 @@ void EditorManagerPrivate::closeEditorOrDocument(IEditor *editor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EditorManagerPrivate::closeEditors(const QList<IEditor*> &editors, bool askAboutModifiedEditors)
|
||||||
|
{
|
||||||
|
if (editors.isEmpty())
|
||||||
|
return true;
|
||||||
|
bool closingFailed = false;
|
||||||
|
// close Editor History list
|
||||||
|
windowPopup()->setVisible(false);
|
||||||
|
|
||||||
|
|
||||||
|
EditorView *currentView = currentEditorView();
|
||||||
|
|
||||||
|
// go through all editors to close and
|
||||||
|
// 1. ask all core listeners to check whether the editor can be closed
|
||||||
|
// 2. keep track of the document and all the editors that might remain open for it
|
||||||
|
QSet<IEditor*> acceptedEditors;
|
||||||
|
QMap<IDocument *, QList<IEditor *> > documentMap;
|
||||||
|
foreach (IEditor *editor, editors) {
|
||||||
|
bool editorAccepted = true;
|
||||||
|
foreach (const std::function<bool(IEditor*)> listener, d->m_closeEditorListeners) {
|
||||||
|
if (!listener(editor)) {
|
||||||
|
editorAccepted = false;
|
||||||
|
closingFailed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (editorAccepted) {
|
||||||
|
acceptedEditors.insert(editor);
|
||||||
|
IDocument *document = editor->document();
|
||||||
|
if (!documentMap.contains(document)) // insert the document to track
|
||||||
|
documentMap.insert(document, DocumentModel::editorsForDocument(document));
|
||||||
|
// keep track that we'll close this editor for the document
|
||||||
|
documentMap[document].removeAll(editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (acceptedEditors.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//ask whether to save modified documents that we are about to close
|
||||||
|
if (askAboutModifiedEditors) {
|
||||||
|
// Check for which documents we will close all editors, and therefore might have to ask the user
|
||||||
|
QList<IDocument *> documentsToClose;
|
||||||
|
for (auto i = documentMap.constBegin(); i != documentMap.constEnd(); ++i) {
|
||||||
|
if (i.value().isEmpty())
|
||||||
|
documentsToClose.append(i.key());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cancelled = false;
|
||||||
|
QList<IDocument *> rejectedList;
|
||||||
|
DocumentManager::saveModifiedDocuments(documentsToClose, QString(), &cancelled,
|
||||||
|
QString(), 0, &rejectedList);
|
||||||
|
if (cancelled)
|
||||||
|
return false;
|
||||||
|
if (!rejectedList.isEmpty()) {
|
||||||
|
closingFailed = true;
|
||||||
|
QSet<IEditor*> skipSet = DocumentModel::editorsForDocuments(rejectedList).toSet();
|
||||||
|
acceptedEditors = acceptedEditors.subtract(skipSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (acceptedEditors.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QList<EditorView*> closedViews;
|
||||||
|
EditorView *focusView = 0;
|
||||||
|
|
||||||
|
// remove the editors
|
||||||
|
foreach (IEditor *editor, acceptedEditors) {
|
||||||
|
emit m_instance->editorAboutToClose(editor);
|
||||||
|
if (!editor->document()->filePath().isEmpty()
|
||||||
|
&& !editor->document()->isTemporary()) {
|
||||||
|
QByteArray state = editor->saveState();
|
||||||
|
if (!state.isEmpty())
|
||||||
|
d->m_editorStates.insert(editor->document()->filePath().toString(), QVariant(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
removeEditor(editor);
|
||||||
|
if (EditorView *view = viewForEditor(editor)) {
|
||||||
|
if (qApp->focusWidget() && qApp->focusWidget() == editor->widget()->focusWidget())
|
||||||
|
focusView = view;
|
||||||
|
if (editor == view->currentEditor())
|
||||||
|
closedViews += view;
|
||||||
|
if (d->m_currentEditor == editor) {
|
||||||
|
// avoid having a current editor without view
|
||||||
|
setCurrentView(view);
|
||||||
|
setCurrentEditor(0);
|
||||||
|
}
|
||||||
|
view->removeEditor(editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO doesn't work as expected with multiple areas in main window and some other cases
|
||||||
|
// instead each view should have its own file history and handle solely themselves
|
||||||
|
// which editor is shown if their current editor closes
|
||||||
|
EditorView *forceViewToShowEditor = 0;
|
||||||
|
if (!closedViews.isEmpty() && EditorManager::visibleEditors().isEmpty()) {
|
||||||
|
if (closedViews.contains(currentView))
|
||||||
|
forceViewToShowEditor = currentView;
|
||||||
|
else
|
||||||
|
forceViewToShowEditor = closedViews.first();
|
||||||
|
}
|
||||||
|
foreach (EditorView *view, closedViews) {
|
||||||
|
IEditor *newCurrent = view->currentEditor();
|
||||||
|
if (!newCurrent && forceViewToShowEditor == view)
|
||||||
|
newCurrent = pickUnusedEditor();
|
||||||
|
if (newCurrent) {
|
||||||
|
activateEditor(view, newCurrent, EditorManager::DoNotChangeCurrentEditor);
|
||||||
|
} else if (forceViewToShowEditor == view) {
|
||||||
|
DocumentModel::Entry *entry = DocumentModelPrivate::firstSuspendedEntry();
|
||||||
|
if (entry) {
|
||||||
|
activateEditorForEntry(view, entry, EditorManager::DoNotChangeCurrentEditor);
|
||||||
|
} else { // no "suspended" ones, so any entry left should have a document
|
||||||
|
const QList<DocumentModel::Entry *> documents = DocumentModel::entries();
|
||||||
|
if (!documents.isEmpty()) {
|
||||||
|
if (IDocument *document = documents.last()->document) {
|
||||||
|
activateEditorForDocument(view, document, EditorManager::DoNotChangeCurrentEditor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emit m_instance->editorsClosed(acceptedEditors.toList());
|
||||||
|
|
||||||
|
foreach (IEditor *editor, acceptedEditors)
|
||||||
|
delete editor;
|
||||||
|
|
||||||
|
if (focusView)
|
||||||
|
activateView(focusView);
|
||||||
|
else
|
||||||
|
setCurrentEditor(currentView->currentEditor());
|
||||||
|
|
||||||
|
if (!EditorManager::currentEditor()) {
|
||||||
|
emit m_instance->currentEditorChanged(0);
|
||||||
|
updateActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
return !closingFailed;
|
||||||
|
}
|
||||||
|
|
||||||
void EditorManagerPrivate::activateView(EditorView *view)
|
void EditorManagerPrivate::activateView(EditorView *view)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(view, return);
|
QTC_ASSERT(view, return);
|
||||||
@@ -2318,141 +2456,7 @@ void EditorManager::closeDocument(DocumentModel::Entry *entry)
|
|||||||
|
|
||||||
bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool askAboutModifiedEditors)
|
bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool askAboutModifiedEditors)
|
||||||
{
|
{
|
||||||
if (editorsToClose.isEmpty())
|
return EditorManagerPrivate::closeEditors(editorsToClose, askAboutModifiedEditors);
|
||||||
return true;
|
|
||||||
bool closingFailed = false;
|
|
||||||
// close Editor History list
|
|
||||||
EditorManagerPrivate::windowPopup()->setVisible(false);
|
|
||||||
|
|
||||||
|
|
||||||
EditorView *currentView = EditorManagerPrivate::currentEditorView();
|
|
||||||
|
|
||||||
// go through all editors to close and
|
|
||||||
// 1. ask all core listeners to check whether the editor can be closed
|
|
||||||
// 2. keep track of the document and all the editors that might remain open for it
|
|
||||||
QSet<IEditor*> acceptedEditors;
|
|
||||||
QMap<IDocument *, QList<IEditor *> > documentMap;
|
|
||||||
foreach (IEditor *editor, editorsToClose) {
|
|
||||||
bool editorAccepted = true;
|
|
||||||
foreach (const std::function<bool(IEditor*)> listener, d->m_closeEditorListeners) {
|
|
||||||
if (!listener(editor)) {
|
|
||||||
editorAccepted = false;
|
|
||||||
closingFailed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (editorAccepted) {
|
|
||||||
acceptedEditors.insert(editor);
|
|
||||||
IDocument *document = editor->document();
|
|
||||||
if (!documentMap.contains(document)) // insert the document to track
|
|
||||||
documentMap.insert(document, DocumentModel::editorsForDocument(document));
|
|
||||||
// keep track that we'll close this editor for the document
|
|
||||||
documentMap[document].removeAll(editor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (acceptedEditors.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//ask whether to save modified documents that we are about to close
|
|
||||||
if (askAboutModifiedEditors) {
|
|
||||||
// Check for which documents we will close all editors, and therefore might have to ask the user
|
|
||||||
QList<IDocument *> documentsToClose;
|
|
||||||
for (auto i = documentMap.constBegin(); i != documentMap.constEnd(); ++i) {
|
|
||||||
if (i.value().isEmpty())
|
|
||||||
documentsToClose.append(i.key());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cancelled = false;
|
|
||||||
QList<IDocument *> rejectedList;
|
|
||||||
DocumentManager::saveModifiedDocuments(documentsToClose, QString(), &cancelled,
|
|
||||||
QString(), 0, &rejectedList);
|
|
||||||
if (cancelled)
|
|
||||||
return false;
|
|
||||||
if (!rejectedList.isEmpty()) {
|
|
||||||
closingFailed = true;
|
|
||||||
QSet<IEditor*> skipSet = DocumentModel::editorsForDocuments(rejectedList).toSet();
|
|
||||||
acceptedEditors = acceptedEditors.subtract(skipSet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (acceptedEditors.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QList<EditorView*> closedViews;
|
|
||||||
EditorView *focusView = 0;
|
|
||||||
|
|
||||||
// remove the editors
|
|
||||||
foreach (IEditor *editor, acceptedEditors) {
|
|
||||||
emit m_instance->editorAboutToClose(editor);
|
|
||||||
if (!editor->document()->filePath().isEmpty()
|
|
||||||
&& !editor->document()->isTemporary()) {
|
|
||||||
QByteArray state = editor->saveState();
|
|
||||||
if (!state.isEmpty())
|
|
||||||
d->m_editorStates.insert(editor->document()->filePath().toString(), QVariant(state));
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorManagerPrivate::removeEditor(editor);
|
|
||||||
if (EditorView *view = EditorManagerPrivate::viewForEditor(editor)) {
|
|
||||||
if (qApp->focusWidget() && qApp->focusWidget() == editor->widget()->focusWidget())
|
|
||||||
focusView = view;
|
|
||||||
if (editor == view->currentEditor())
|
|
||||||
closedViews += view;
|
|
||||||
if (d->m_currentEditor == editor) {
|
|
||||||
// avoid having a current editor without view
|
|
||||||
EditorManagerPrivate::setCurrentView(view);
|
|
||||||
EditorManagerPrivate::setCurrentEditor(0);
|
|
||||||
}
|
|
||||||
view->removeEditor(editor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO doesn't work as expected with multiple areas in main window and some other cases
|
|
||||||
// instead each view should have its own file history and handle solely themselves
|
|
||||||
// which editor is shown if their current editor closes
|
|
||||||
EditorView *forceViewToShowEditor = 0;
|
|
||||||
if (!closedViews.isEmpty() && visibleEditors().isEmpty()) {
|
|
||||||
if (closedViews.contains(currentView))
|
|
||||||
forceViewToShowEditor = currentView;
|
|
||||||
else
|
|
||||||
forceViewToShowEditor = closedViews.first();
|
|
||||||
}
|
|
||||||
foreach (EditorView *view, closedViews) {
|
|
||||||
IEditor *newCurrent = view->currentEditor();
|
|
||||||
if (!newCurrent && forceViewToShowEditor == view)
|
|
||||||
newCurrent = EditorManagerPrivate::pickUnusedEditor();
|
|
||||||
if (newCurrent) {
|
|
||||||
EditorManagerPrivate::activateEditor(view, newCurrent, DoNotChangeCurrentEditor);
|
|
||||||
} else if (forceViewToShowEditor == view) {
|
|
||||||
DocumentModel::Entry *entry = DocumentModelPrivate::firstSuspendedEntry();
|
|
||||||
if (entry) {
|
|
||||||
EditorManagerPrivate::activateEditorForEntry(view, entry, DoNotChangeCurrentEditor);
|
|
||||||
} else { // no "suspended" ones, so any entry left should have a document
|
|
||||||
const QList<DocumentModel::Entry *> documents = DocumentModel::entries();
|
|
||||||
if (!documents.isEmpty()) {
|
|
||||||
if (IDocument *document = documents.last()->document) {
|
|
||||||
EditorManagerPrivate::activateEditorForDocument(
|
|
||||||
view, document, DoNotChangeCurrentEditor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
emit m_instance->editorsClosed(acceptedEditors.toList());
|
|
||||||
|
|
||||||
foreach (IEditor *editor, acceptedEditors)
|
|
||||||
delete editor;
|
|
||||||
|
|
||||||
if (focusView)
|
|
||||||
EditorManagerPrivate::activateView(focusView);
|
|
||||||
else
|
|
||||||
EditorManagerPrivate::setCurrentEditor(currentView->currentEditor());
|
|
||||||
|
|
||||||
if (!currentEditor()) {
|
|
||||||
emit m_instance->currentEditorChanged(0);
|
|
||||||
EditorManagerPrivate::updateActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
return !closingFailed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorManager::activateEditorForEntry(DocumentModel::Entry *entry, OpenEditorFlags flags)
|
void EditorManager::activateEditorForEntry(DocumentModel::Entry *entry, OpenEditorFlags flags)
|
||||||
|
@@ -90,6 +90,7 @@ public:
|
|||||||
EditorManager::OpenEditorFlags flags = EditorManager::NoFlags);
|
EditorManager::OpenEditorFlags flags = EditorManager::NoFlags);
|
||||||
/* closes the document if there is no other editor on the document visible */
|
/* closes the document if there is no other editor on the document visible */
|
||||||
static void closeEditorOrDocument(IEditor *editor);
|
static void closeEditorOrDocument(IEditor *editor);
|
||||||
|
static bool closeEditors(const QList<IEditor *> &editors, bool askAboutModifiedEditors);
|
||||||
|
|
||||||
static EditorView *viewForEditor(IEditor *editor);
|
static EditorView *viewForEditor(IEditor *editor);
|
||||||
static void setCurrentView(EditorView *view);
|
static void setCurrentView(EditorView *view);
|
||||||
|
Reference in New Issue
Block a user