forked from qt-creator/qt-creator
Fix closing editor with ctrl+w or "x" or File > Close
If there are other editors on the document visible in some split, it should not close the document, but only the editor. Task-number: QTCREATORBUG-9346 Change-Id: Idce1ae2f518d4c6e875d86f9831d41c46c06361c Reviewed-by: Eike Ziller <eike.ziller@digia.com>
This commit is contained in:
@@ -691,7 +691,8 @@ void BazaarPlugin::commitFromEditor()
|
||||
{
|
||||
// Close the submit editor
|
||||
m_submitActionTriggered = true;
|
||||
EditorManager::closeEditor(submitEditor());
|
||||
QTC_ASSERT(submitEditor(), return);
|
||||
EditorManager::closeDocument(submitEditor()->document());
|
||||
}
|
||||
|
||||
void BazaarPlugin::uncommit()
|
||||
|
||||
@@ -1475,7 +1475,8 @@ void ClearCasePlugin::describe(const QString &source, const QString &changeNr)
|
||||
void ClearCasePlugin::checkInSelected()
|
||||
{
|
||||
m_submitActionTriggered = true;
|
||||
EditorManager::closeEditor(submitEditor());
|
||||
QTC_ASSERT(submitEditor(), return);
|
||||
EditorManager::closeDocument(submitEditor()->document());
|
||||
}
|
||||
|
||||
QString ClearCasePlugin::runCleartoolSync(const QString &workingDir,
|
||||
|
||||
@@ -322,7 +322,8 @@ void EditorManagerPrivate::init()
|
||||
cmd->setAttribute(Core::Command::CA_UpdateText);
|
||||
cmd->setDescription(m_closeCurrentEditorAction->text());
|
||||
mfile->addAction(cmd, Constants::G_FILE_CLOSE);
|
||||
connect(m_closeCurrentEditorAction, SIGNAL(triggered()), m_instance, SLOT(closeEditor()));
|
||||
connect(m_closeCurrentEditorAction, SIGNAL(triggered()),
|
||||
m_instance, SLOT(slotCloseCurrentEditorOrDocument()));
|
||||
|
||||
if (Utils::HostOsInfo::isWindowsHost()) {
|
||||
// workaround for QTCREATORBUG-72
|
||||
@@ -330,7 +331,7 @@ void EditorManagerPrivate::init()
|
||||
cmd = ActionManager::registerAction(action, Constants::CLOSE_ALTERNATIVE, editManagerContext);
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+F4")));
|
||||
cmd->setDescription(EditorManager::tr("Close"));
|
||||
connect(action, SIGNAL(triggered()), m_instance, SLOT(closeEditor()));
|
||||
connect(action, SIGNAL(triggered()), m_instance, SLOT(slotCloseCurrentEditorOrDocument()));
|
||||
}
|
||||
|
||||
// Close All Action
|
||||
@@ -1023,6 +1024,20 @@ void EditorManagerPrivate::activateEditorForEntry(EditorView *view, DocumentMode
|
||||
DocumentModel::removeEntry(entry);
|
||||
}
|
||||
|
||||
void EditorManagerPrivate::closeEditorOrDocument(IEditor *editor)
|
||||
{
|
||||
QTC_ASSERT(editor, return);
|
||||
QList<IEditor *> visible = EditorManager::visibleEditors();
|
||||
if (Utils::contains(visible,
|
||||
[&editor](IEditor *other) {
|
||||
return editor != other && other->document() == editor->document();
|
||||
})) {
|
||||
EditorManager::closeEditor(editor);
|
||||
} else {
|
||||
EditorManager::closeDocument(editor->document());
|
||||
}
|
||||
}
|
||||
|
||||
void EditorManagerPrivate::activateView(EditorView *view)
|
||||
{
|
||||
QTC_ASSERT(view, return);
|
||||
@@ -1597,10 +1612,14 @@ void EditorManagerPrivate::revertToSavedFromContextMenu()
|
||||
|
||||
void EditorManagerPrivate::closeEditorFromContextMenu()
|
||||
{
|
||||
if (d->m_contextMenuEditor) {
|
||||
closeEditorOrDocument(d->m_contextMenuEditor);
|
||||
} else {
|
||||
IDocument *document = d->m_contextMenuEntry ? d->m_contextMenuEntry->document : 0;
|
||||
if (document)
|
||||
EditorManager::closeDocument(document);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorManagerPrivate::closeOtherDocumentsFromContextMenu()
|
||||
{
|
||||
@@ -1856,12 +1875,12 @@ void EditorManager::closeOtherDocuments(IDocument *document)
|
||||
}
|
||||
|
||||
// SLOT connected to action
|
||||
void EditorManager::closeEditor()
|
||||
void EditorManager::slotCloseCurrentEditorOrDocument()
|
||||
{
|
||||
if (!d->m_currentEditor)
|
||||
return;
|
||||
addCurrentPositionToNavigationHistory();
|
||||
closeEditor(d->m_currentEditor);
|
||||
d->closeEditorOrDocument(d->m_currentEditor);
|
||||
}
|
||||
|
||||
void EditorManager::closeOtherDocuments()
|
||||
@@ -1878,10 +1897,12 @@ static void assignAction(QAction *self, QAction *other)
|
||||
self->setIconVisibleInMenu(other->isIconVisibleInMenu());
|
||||
}
|
||||
|
||||
void EditorManager::addSaveAndCloseEditorActions(QMenu *contextMenu, DocumentModel::Entry *entry)
|
||||
void EditorManager::addSaveAndCloseEditorActions(QMenu *contextMenu, DocumentModel::Entry *entry,
|
||||
IEditor *editor)
|
||||
{
|
||||
QTC_ASSERT(contextMenu, return);
|
||||
d->m_contextMenuEntry = entry;
|
||||
d->m_contextMenuEditor = editor;
|
||||
|
||||
const QString filePath = entry ? entry->fileName() : QString();
|
||||
const bool copyActionsEnabled = !filePath.isEmpty();
|
||||
@@ -1929,6 +1950,7 @@ void EditorManager::addSaveAndCloseEditorActions(QMenu *contextMenu, DocumentMod
|
||||
void EditorManager::addNativeDirAndOpenWithActions(QMenu *contextMenu, DocumentModel::Entry *entry)
|
||||
{
|
||||
QTC_ASSERT(contextMenu, return);
|
||||
d->m_contextMenuEntry = entry;
|
||||
bool enabled = entry && !entry->fileName().isEmpty();
|
||||
d->m_openGraphicalShellAction->setEnabled(enabled);
|
||||
d->m_openTerminalAction->setEnabled(enabled);
|
||||
@@ -1980,13 +2002,18 @@ bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool ask
|
||||
{
|
||||
if (editorsToClose.isEmpty())
|
||||
return true;
|
||||
bool closingFailed = false;
|
||||
// close Editor History list
|
||||
EditorManagerPrivate::windowPopup()->setVisible(false);
|
||||
|
||||
|
||||
EditorView *currentView = EditorManagerPrivate::currentEditorView();
|
||||
|
||||
bool closingFailed = false;
|
||||
// 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;
|
||||
QSet<IDocument *> acceptedDocuments;
|
||||
//ask all core listeners to check whether the editor can be closed
|
||||
QMap<IDocument *, QList<IEditor *> > documentMap;
|
||||
const QList<ICoreListener *> listeners =
|
||||
ExtensionSystem::PluginManager::getObjects<ICoreListener>();
|
||||
foreach (IEditor *editor, editorsToClose) {
|
||||
@@ -1999,32 +2026,40 @@ bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool ask
|
||||
}
|
||||
}
|
||||
if (editorAccepted) {
|
||||
acceptedEditors += DocumentModel::editorsForDocument(editor->document()).toSet();
|
||||
acceptedDocuments.insert(editor->document());
|
||||
}
|
||||
}
|
||||
if (acceptedEditors.isEmpty())
|
||||
return false;
|
||||
//ask whether to save modified files
|
||||
if (askAboutModifiedEditors) {
|
||||
bool cancelled = false;
|
||||
QList<IDocument *> list;
|
||||
DocumentManager::saveModifiedDocuments(acceptedDocuments.toList(), QString(), &cancelled,
|
||||
QString(), 0, &list);
|
||||
if (cancelled)
|
||||
return false;
|
||||
if (!list.isEmpty()) {
|
||||
closingFailed = true;
|
||||
acceptedDocuments.subtract(list.toSet());
|
||||
QSet<IEditor*> skipSet = DocumentModel::editorsForDocuments(list).toSet();
|
||||
acceptedEditors = acceptedEditors.subtract(skipSet);
|
||||
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;
|
||||
|
||||
// close Editor History list
|
||||
EditorManagerPrivate::windowPopup()->setVisible(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;
|
||||
|
||||
@@ -2051,6 +2086,16 @@ bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool ask
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
bool currentViewHandled = false;
|
||||
foreach (EditorView *view, closedViews) {
|
||||
OpenEditorFlags flags;
|
||||
@@ -2059,11 +2104,11 @@ bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool ask
|
||||
else
|
||||
flags = OpenEditorFlags(DoNotChangeCurrentEditor);
|
||||
IEditor *newCurrent = view->currentEditor();
|
||||
if (!newCurrent)
|
||||
if (!newCurrent && forceViewToShowEditor == view)
|
||||
newCurrent = EditorManagerPrivate::pickUnusedEditor();
|
||||
if (newCurrent) {
|
||||
EditorManagerPrivate::activateEditor(view, newCurrent, flags);
|
||||
} else {
|
||||
} else if (forceViewToShowEditor == view) {
|
||||
DocumentModel::Entry *entry = DocumentModel::firstRestoredEntry();
|
||||
if (entry) {
|
||||
EditorManagerPrivate::activateEditorForEntry(view, entry, flags);
|
||||
@@ -2363,9 +2408,9 @@ bool EditorManager::closeDocument(IDocument *document, bool askAboutModifiedEdit
|
||||
return closeDocuments(QList<IDocument *>() << document, askAboutModifiedEditors);
|
||||
}
|
||||
|
||||
bool EditorManager::closeDocuments(const QList<IDocument *> &document, bool askAboutModifiedEditors)
|
||||
bool EditorManager::closeDocuments(const QList<IDocument *> &documents, bool askAboutModifiedEditors)
|
||||
{
|
||||
return m_instance->closeEditors(DocumentModel::editorsForDocuments(document), askAboutModifiedEditors);
|
||||
return m_instance->closeEditors(DocumentModel::editorsForDocuments(documents), askAboutModifiedEditors);
|
||||
}
|
||||
|
||||
void EditorManager::addCurrentPositionToNavigationHistory(IEditor *editor, const QByteArray &saveState)
|
||||
|
||||
@@ -167,7 +167,8 @@ public:
|
||||
static void setWindowTitleAdditionHandler(WindowTitleHandler handler);
|
||||
static void setWindowTitleVcsTopicHandler(WindowTitleHandler handler);
|
||||
|
||||
static void addSaveAndCloseEditorActions(QMenu *contextMenu, DocumentModel::Entry *entry);
|
||||
static void addSaveAndCloseEditorActions(QMenu *contextMenu, DocumentModel::Entry *entry,
|
||||
IEditor *editor = 0);
|
||||
static void addNativeDirAndOpenWithActions(QMenu *contextMenu, DocumentModel::Entry *entry);
|
||||
|
||||
signals:
|
||||
@@ -184,7 +185,7 @@ public slots:
|
||||
static void saveDocumentAs();
|
||||
static void revertToSaved();
|
||||
static bool closeAllEditors(bool askAboutModifiedEditors = true);
|
||||
static void closeEditor();
|
||||
static void slotCloseCurrentEditorOrDocument();
|
||||
static void closeOtherDocuments();
|
||||
static void splitSideBySide();
|
||||
static void gotoOtherSplit();
|
||||
|
||||
@@ -82,6 +82,9 @@ public:
|
||||
EditorManager::OpenEditorFlags flags = 0);
|
||||
static void activateEditorForEntry(EditorView *view, DocumentModel::Entry *entry,
|
||||
EditorManager::OpenEditorFlags flags = EditorManager::NoFlags);
|
||||
/* closes the document if there is no other editor on the document visible */
|
||||
static void closeEditorOrDocument(IEditor *editor);
|
||||
|
||||
static EditorView *viewForEditor(IEditor *editor);
|
||||
static void setCurrentView(EditorView *view);
|
||||
|
||||
@@ -214,6 +217,7 @@ private:
|
||||
QAction *m_openTerminalAction;
|
||||
QAction *m_findInDirectoryAction;
|
||||
DocumentModel::Entry *m_contextMenuEntry;
|
||||
IEditor *m_contextMenuEditor;
|
||||
|
||||
OpenEditorsWindow *m_windowPopup;
|
||||
EditorClosingCoreListener *m_coreListener;
|
||||
|
||||
@@ -76,12 +76,14 @@ EditorView::EditorView(SplitterOrView *parentSplitterOrView, QWidget *parent) :
|
||||
{
|
||||
connect(m_toolBar, SIGNAL(goBackClicked()), this, SLOT(goBackInNavigationHistory()));
|
||||
connect(m_toolBar, SIGNAL(goForwardClicked()), this, SLOT(goForwardInNavigationHistory()));
|
||||
connect(m_toolBar, SIGNAL(closeClicked()), this, SLOT(closeView()));
|
||||
connect(m_toolBar, SIGNAL(closeClicked()), this, SLOT(closeCurrentEditor()));
|
||||
connect(m_toolBar, SIGNAL(listSelectionActivated(int)), this, SLOT(listSelectionActivated(int)));
|
||||
connect(m_toolBar, SIGNAL(horizontalSplitClicked()), this, SLOT(splitHorizontally()));
|
||||
connect(m_toolBar, SIGNAL(verticalSplitClicked()), this, SLOT(splitVertically()));
|
||||
connect(m_toolBar, SIGNAL(splitNewWindowClicked()), this, SLOT(splitNewWindow()));
|
||||
connect(m_toolBar, SIGNAL(closeSplitClicked()), this, SLOT(closeSplit()));
|
||||
connect(m_toolBar, &EditorToolBar::listContextMenuRequested,
|
||||
this, &EditorView::showListContextMenu);
|
||||
tl->addWidget(m_toolBar);
|
||||
}
|
||||
|
||||
@@ -159,11 +161,11 @@ EditorView *EditorView::findNextView()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EditorView::closeView()
|
||||
void EditorView::closeCurrentEditor()
|
||||
{
|
||||
IEditor *editor = currentEditor();
|
||||
if (editor)
|
||||
EditorManager::closeEditor(editor);
|
||||
EditorManagerPrivate::closeEditorOrDocument(editor);
|
||||
}
|
||||
|
||||
void EditorView::showEditorStatusBar(const QString &id,
|
||||
@@ -311,6 +313,18 @@ void EditorView::listSelectionActivated(int index)
|
||||
EditorManagerPrivate::activateEditorForEntry(this, DocumentModel::entryAtRow(index));
|
||||
}
|
||||
|
||||
void EditorView::showListContextMenu(QPoint pos)
|
||||
{
|
||||
IEditor *editor = currentEditor();
|
||||
DocumentModel::Entry entry;
|
||||
entry.document = editor ? editor->document() : 0;
|
||||
QMenu menu;
|
||||
EditorManager::addSaveAndCloseEditorActions(&menu, &entry, editor);
|
||||
menu.addSeparator();
|
||||
EditorManager::addNativeDirAndOpenWithActions(&menu, &entry);
|
||||
menu.exec(pos);
|
||||
}
|
||||
|
||||
void EditorView::splitHorizontally()
|
||||
{
|
||||
if (m_parentSplitterOrView)
|
||||
|
||||
@@ -112,8 +112,9 @@ protected:
|
||||
void focusInEvent(QFocusEvent *);
|
||||
|
||||
private slots:
|
||||
void closeView();
|
||||
void closeCurrentEditor();
|
||||
void listSelectionActivated(int index);
|
||||
void showListContextMenu(QPoint pos);
|
||||
void splitHorizontally();
|
||||
void splitVertically();
|
||||
void splitNewWindow();
|
||||
|
||||
@@ -233,12 +233,8 @@ void EditorToolBar::setCloseSplitIcon(const QIcon &icon)
|
||||
|
||||
void EditorToolBar::closeEditor()
|
||||
{
|
||||
IEditor *current = EditorManager::currentEditor();
|
||||
if (!current)
|
||||
return;
|
||||
|
||||
if (d->m_isStandalone)
|
||||
EditorManager::closeEditor(current);
|
||||
EditorManager::slotCloseCurrentEditorOrDocument();
|
||||
emit closeClicked();
|
||||
}
|
||||
|
||||
@@ -314,13 +310,18 @@ void EditorToolBar::changeActiveEditor(int row)
|
||||
|
||||
void EditorToolBar::listContextMenu(QPoint pos)
|
||||
{
|
||||
DocumentModel::Entry *entry = DocumentModel::entryAtRow(
|
||||
d->m_editorList->currentIndex());
|
||||
if (d->m_isStandalone) {
|
||||
IEditor *editor = EditorManager::currentEditor();
|
||||
DocumentModel::Entry entry;
|
||||
entry.document = editor ? editor->document() : 0;
|
||||
QMenu menu;
|
||||
EditorManager::addSaveAndCloseEditorActions(&menu, entry);
|
||||
EditorManager::addSaveAndCloseEditorActions(&menu, &entry, editor);
|
||||
menu.addSeparator();
|
||||
EditorManager::addNativeDirAndOpenWithActions(&menu, entry);
|
||||
EditorManager::addNativeDirAndOpenWithActions(&menu, &entry);
|
||||
menu.exec(d->m_editorList->mapToGlobal(pos));
|
||||
} else {
|
||||
emit listContextMenuRequested(d->m_editorList->mapToGlobal(pos));
|
||||
}
|
||||
}
|
||||
|
||||
void EditorToolBar::makeEditorWritable()
|
||||
|
||||
@@ -93,6 +93,7 @@ signals:
|
||||
void splitNewWindowClicked();
|
||||
void closeSplitClicked();
|
||||
void listSelectionActivated(int row);
|
||||
void listContextMenuRequested(QPoint globalpos);
|
||||
|
||||
private slots:
|
||||
void updateEditorListSelection(Core::IEditor *newSelection);
|
||||
|
||||
@@ -1131,7 +1131,8 @@ bool CvsPlugin::describe(const QString &repositoryPath,
|
||||
void CvsPlugin::submitCurrentLog()
|
||||
{
|
||||
m_submitActionTriggered = true;
|
||||
EditorManager::closeEditor(submitEditor());
|
||||
QTC_ASSERT(submitEditor(), return);
|
||||
EditorManager::closeDocument(submitEditor()->document());
|
||||
}
|
||||
|
||||
// Run CVS. At this point, file arguments must be relative to
|
||||
|
||||
@@ -1034,7 +1034,8 @@ void GitPlugin::submitCurrentLog()
|
||||
{
|
||||
// Close the submit editor
|
||||
m_submitActionTriggered = true;
|
||||
EditorManager::closeEditor(submitEditor());
|
||||
QTC_ASSERT(submitEditor(), return);
|
||||
EditorManager::closeDocument(submitEditor()->document());
|
||||
}
|
||||
|
||||
bool GitPlugin::submitEditorAboutToClose()
|
||||
|
||||
@@ -612,7 +612,8 @@ void MercurialPlugin::commitFromEditor()
|
||||
{
|
||||
// Close the submit editor
|
||||
m_submitActionTriggered = true;
|
||||
Core::EditorManager::closeEditor(submitEditor());
|
||||
QTC_ASSERT(submitEditor(), return);
|
||||
Core::EditorManager::closeDocument(submitEditor()->document());
|
||||
}
|
||||
|
||||
bool MercurialPlugin::submitEditorAboutToClose()
|
||||
|
||||
@@ -1329,7 +1329,8 @@ void PerforcePlugin::describe(const QString & source, const QString &n)
|
||||
void PerforcePlugin::submitCurrentLog()
|
||||
{
|
||||
m_submitActionTriggered = true;
|
||||
EditorManager::closeEditor(submitEditor());
|
||||
QTC_ASSERT(submitEditor(), return);
|
||||
EditorManager::closeDocument(submitEditor()->document());
|
||||
}
|
||||
|
||||
void PerforcePlugin::cleanCommitMessageFile()
|
||||
|
||||
@@ -92,7 +92,7 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex
|
||||
|
||||
//Close Editor
|
||||
Core::ActionManager::registerAction(&m_closeCurrentEditorAction, Core::Constants::CLOSE, qmlDesignerMainContext);
|
||||
connect(&m_closeCurrentEditorAction, SIGNAL(triggered()), em, SLOT(closeEditor()));
|
||||
connect(&m_closeCurrentEditorAction, SIGNAL(triggered()), em, SLOT(slotCloseCurrentEditorOrDocument()));
|
||||
|
||||
//Close All
|
||||
Core::ActionManager::registerAction(&m_closeAllEditorsAction, Core::Constants::CLOSEALL, qmlDesignerMainContext);
|
||||
|
||||
@@ -990,7 +990,8 @@ void SubversionPlugin::slotDescribe()
|
||||
void SubversionPlugin::submitCurrentLog()
|
||||
{
|
||||
m_submitActionTriggered = true;
|
||||
EditorManager::closeEditor(submitEditor());
|
||||
QTC_ASSERT(submitEditor(), return);
|
||||
EditorManager::closeDocument(submitEditor()->document());
|
||||
}
|
||||
|
||||
SubversionResponse
|
||||
|
||||
Reference in New Issue
Block a user