diff --git a/src/plugins/coreplugin/editormanager/editorarea.cpp b/src/plugins/coreplugin/editormanager/editorarea.cpp index 2b47988c3b3..cb311320cde 100644 --- a/src/plugins/coreplugin/editormanager/editorarea.cpp +++ b/src/plugins/coreplugin/editormanager/editorarea.cpp @@ -48,6 +48,11 @@ IDocument *EditorArea::currentDocument() const return m_currentDocument; } +EditorView *EditorArea::currentView() const +{ + return m_currentView; +} + void EditorArea::focusChanged(QWidget *old, QWidget *now) { Q_UNUSED(old) @@ -104,5 +109,10 @@ void EditorArea::updateCloseSplitButton() v->setCloseSplitEnabled(false); } +void EditorArea::hideEvent(QHideEvent *) +{ + emit hidden(); +} + } // Internal } // Core diff --git a/src/plugins/coreplugin/editormanager/editorarea.h b/src/plugins/coreplugin/editormanager/editorarea.h index 30cf25ba775..f4cc6e62c2f 100644 --- a/src/plugins/coreplugin/editormanager/editorarea.h +++ b/src/plugins/coreplugin/editormanager/editorarea.h @@ -22,15 +22,18 @@ public: ~EditorArea() override; IDocument *currentDocument() const; + EditorView *currentView() const; signals: void windowTitleNeedsUpdate(); + void hidden(); private: void focusChanged(QWidget *old, QWidget *now); void setCurrentView(EditorView *view); void updateCurrentEditor(IEditor *editor); void updateCloseSplitButton(); + void hideEvent(QHideEvent *) override; IContext *m_context; QPointer m_currentView; diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 66cf795c894..9041d2bd4a8 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -687,8 +687,7 @@ void EditorManagerPrivate::init() mainEditorArea->hide(); connect(mainEditorArea, &EditorArea::windowTitleNeedsUpdate, this, &EditorManagerPrivate::updateWindowTitle); - connect(mainEditorArea, &QObject::destroyed, this, &EditorManagerPrivate::editorAreaDestroyed); - m_editorAreas.append(mainEditorArea); + addEditorArea(mainEditorArea); setCurrentView(mainEditorArea->view()); updateActions(); @@ -1007,7 +1006,7 @@ IEditor *EditorManagerPrivate::openEditorWith(const FilePath &filePath, Id edito IEditor *EditorManagerPrivate::activateEditorForDocument(EditorView *view, IDocument *document, EditorManager::OpenEditorFlags flags) { - Q_ASSERT(view); + QTC_ASSERT(view, return nullptr); IEditor *editor = view->editorForDocument(document); if (!editor) { const QList editors = DocumentModel::editorsForDocument(document); @@ -1081,8 +1080,9 @@ void EditorManagerPrivate::doEscapeKeyFocusMoveMagic() return; QWidget *focus = QApplication::focusWidget(); EditorView *editorView = currentEditorView(); - bool editorViewActive = (focus && focus == editorView->focusWidget()); - bool editorViewVisible = editorView->isVisible(); + QTC_CHECK(editorView); + bool editorViewActive = (editorView && focus && focus == editorView->focusWidget()); + bool editorViewVisible = editorView && editorView->isVisible(); bool stuffHidden = false; FindToolBarPlaceHolder *findPane = FindToolBarPlaceHolder::getCurrent(); @@ -1422,7 +1422,7 @@ IEditor *EditorManagerPrivate::duplicateEditor(IEditor *editor) IEditor *EditorManagerPrivate::activateEditor(EditorView *view, IEditor *editor, EditorManager::OpenEditorFlags flags) { - Q_ASSERT(view); + QTC_ASSERT(view, return nullptr); if (!editor) return nullptr; @@ -1692,10 +1692,17 @@ int EditorManagerPrivate::visibleDocumentsCount() return visibleDocuments.count(); } +static void setView(QList> &list, EditorView *view) +{ + // remove view from the list, as well as any deleted views + Utils::erase(list, [view](QPointer v) { return !v || v == view; }); + list.prepend(view); +} + void EditorManagerPrivate::setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory) { IEditor *previousEditor = d->m_currentEditor; - EditorView *previousView = d->m_currentView; + EditorView *previousView = d->m_currentView.isEmpty() ? nullptr : d->m_currentView.constFirst(); EditorView *view = editor ? viewForEditor(editor) : previousView; if (editor != previousEditor) { @@ -1711,7 +1718,7 @@ void EditorManagerPrivate::setCurrentEditor(IEditor *editor, bool ignoreNavigati } if (QTC_GUARD(view)) { // we should always have a view - d->m_currentView = view; + setView(d->m_currentView, view); view->setCurrentEditor(editor); } @@ -1723,14 +1730,17 @@ void EditorManagerPrivate::setCurrentEditor(IEditor *editor, bool ignoreNavigati void EditorManagerPrivate::setCurrentView(EditorView *view) { - QTC_ASSERT(view, return); // view should always have a view - if (view != d->m_currentView) { - EditorView *previousView = d->m_currentView; - d->m_currentView = view; + QTC_ASSERT(view, return); // we should always have a view + // currentView can empty if and only if we are currently initializing and setting + // the main editor area's view as the current one + if (d->m_currentView.isEmpty() || view != d->m_currentView.constFirst()) { + EditorView *previousView = d->m_currentView.isEmpty() ? nullptr + : d->m_currentView.constFirst(); + setView(d->m_currentView, view); if (previousView) previousView->update(); - if (d->m_currentView) + if (d->m_currentView.constFirst()) view->update(); } @@ -1739,6 +1749,8 @@ void EditorManagerPrivate::setCurrentView(EditorView *view) EditorArea *EditorManagerPrivate::findEditorArea(const EditorView *view, int *areaIndex) { + if (!view) + return nullptr; SplitterOrView *current = view->parentSplitterOrView(); while (current) { if (auto area = qobject_cast(current)) { @@ -1825,14 +1837,43 @@ void EditorManagerPrivate::deleteEditors(const QList &editors) EditorWindow *EditorManagerPrivate::createEditorWindow() { auto win = new EditorWindow; - EditorArea *area = win->editorArea(); + addEditorArea(win->editorArea()); + return win; +} + +void EditorManagerPrivate::addEditorArea(EditorArea *area) +{ d->m_editorAreas.append(area); connect(area, &QObject::destroyed, d, &EditorManagerPrivate::editorAreaDestroyed); - return win; + connect( + area, + &EditorArea::hidden, + d, + [area = QPointer(area)] { + // The connection is queued, because the hiding might be very short term, e.g. + // when switching between Edit and Debug modes. Check if it is still hidden. + const auto isReallyVisibile = [](QWidget *w) { + return w && w->isVisible() && !w->window()->isMinimized(); + }; + if (isReallyVisibile(area)) + return; + // In case the hidden editor area has the current view, look for a view + // that is not hidden, iterating through the history of current views. + // This could be the first==current view (which results in a no-op). + for (const QPointer &view : d->m_currentView) { + if (isReallyVisibile(view)) { + setCurrentView(view); + return; + } + } + // If we didn't find a better view, so be it + }, + Qt::QueuedConnection); } void EditorManagerPrivate::splitNewWindow(EditorView *view) { + QTC_ASSERT(view, return); IEditor *editor = view->currentEditor(); IEditor *newEditor = nullptr; const QByteArray state = editor ? editor->saveState() : QByteArray(); @@ -2107,6 +2148,7 @@ void EditorManagerPrivate::gotoNextDocHistory() dialog->selectNextEditor(); } else { EditorView *view = currentEditorView(); + QTC_ASSERT(view, return); dialog->setEditors(d->m_globalHistory, view); dialog->selectNextEditor(); showPopupOrSelectDocument(); @@ -2120,6 +2162,7 @@ void EditorManagerPrivate::gotoPreviousDocHistory() dialog->selectPreviousEditor(); } else { EditorView *view = currentEditorView(); + QTC_ASSERT(view, return); dialog->setEditors(d->m_globalHistory, view); dialog->selectPreviousEditor(); showPopupOrSelectDocument(); @@ -2128,14 +2171,15 @@ void EditorManagerPrivate::gotoPreviousDocHistory() void EditorManagerPrivate::gotoLastEditLocation() { - currentEditorView()->goToEditLocation(d->m_globalLastEditLocation); + EditorView *view = currentEditorView(); + QTC_ASSERT(view, return); + view->goToEditLocation(d->m_globalLastEditLocation); } void EditorManagerPrivate::gotoNextSplit() { EditorView *view = currentEditorView(); - if (!view) - return; + QTC_ASSERT(view, return); EditorView *nextView = view->findNextView(); if (!nextView) { // we are in the "last" view in this editor area @@ -2157,8 +2201,7 @@ void EditorManagerPrivate::gotoNextSplit() void EditorManagerPrivate::gotoPreviousSplit() { EditorView *view = currentEditorView(); - if (!view) - return; + QTC_ASSERT(view, return); EditorView *prevView = view->findPreviousView(); if (!prevView) { // we are in the "first" view in this editor area @@ -2600,7 +2643,8 @@ void EditorManagerPrivate::setCurrentEditorFromContextChange() EditorView *EditorManagerPrivate::currentEditorView() { - return d->m_currentView; + QTC_ASSERT(d->m_currentView.size() > 0, return nullptr); + return d->m_currentView.constFirst(); } QList EditorManagerPrivate::allEditorViews() @@ -3372,7 +3416,9 @@ bool EditorManager::closeDocuments(const QList &documents, bool ask */ void EditorManager::addCurrentPositionToNavigationHistory(const QByteArray &saveState) { - EditorManagerPrivate::currentEditorView()->addCurrentPositionToNavigationHistory(saveState); + EditorView *view = EditorManagerPrivate::currentEditorView(); + QTC_ASSERT(view, return); + view->addCurrentPositionToNavigationHistory(saveState); EditorManagerPrivate::updateActions(); } @@ -3405,7 +3451,9 @@ void EditorManager::setLastEditLocation(const IEditor* editor) */ void EditorManager::cutForwardNavigationHistory() { - EditorManagerPrivate::currentEditorView()->cutForwardNavigationHistory(); + EditorView *view = EditorManagerPrivate::currentEditorView(); + QTC_ASSERT(view, return); + view->cutForwardNavigationHistory(); EditorManagerPrivate::updateActions(); } @@ -3417,9 +3465,10 @@ void EditorManager::cutForwardNavigationHistory() */ void EditorManager::goBackInNavigationHistory() { - EditorManagerPrivate::currentEditorView()->goBackInNavigationHistory(); + EditorView *view = EditorManagerPrivate::currentEditorView(); + QTC_ASSERT(view, return); + view->goBackInNavigationHistory(); EditorManagerPrivate::updateActions(); - return; } /*! @@ -3430,7 +3479,9 @@ void EditorManager::goBackInNavigationHistory() */ void EditorManager::goForwardInNavigationHistory() { - EditorManagerPrivate::currentEditorView()->goForwardInNavigationHistory(); + EditorView *view = EditorManagerPrivate::currentEditorView(); + QTC_ASSERT(view, return); + view->goForwardInNavigationHistory(); EditorManagerPrivate::updateActions(); } @@ -3600,9 +3651,9 @@ void EditorManager::showEditorStatusBar(const QString &id, QObject *object, const std::function &function) { - - EditorManagerPrivate::currentEditorView()->showEditorStatusBar( - id, infoText, buttonText, object, function); + EditorView *view = EditorManagerPrivate::currentEditorView(); + QTC_ASSERT(view, return); + view->showEditorStatusBar(id, infoText, buttonText, object, function); } /*! @@ -3611,6 +3662,8 @@ void EditorManager::showEditorStatusBar(const QString &id, void EditorManager::hideEditorStatusBar(const QString &id) { // TODO: what if the current editor view betwenn show and hideEditorStatusBar changed? + EditorView *view = EditorManagerPrivate::currentEditorView(); + QTC_ASSERT(view, return); EditorManagerPrivate::currentEditorView()->hideEditorStatusBar(id); } @@ -3664,8 +3717,7 @@ void EditorManager::splitSideBySide() void EditorManager::gotoOtherSplit() { EditorView *view = EditorManagerPrivate::currentEditorView(); - if (!view) - return; + QTC_ASSERT(view, return); EditorView *nextView = view->findNextView(); if (!nextView) { // we are in the "last" view in this editor area diff --git a/src/plugins/coreplugin/editormanager/editormanager_p.h b/src/plugins/coreplugin/editormanager/editormanager_p.h index 7e6430621a2..789acd16e15 100644 --- a/src/plugins/coreplugin/editormanager/editormanager_p.h +++ b/src/plugins/coreplugin/editormanager/editormanager_p.h @@ -100,6 +100,7 @@ public: Qt::CaseSensitivity sensitivity); static EditorWindow *createEditorWindow(); + static void addEditorArea(EditorArea *area); static void splitNewWindow(Internal::EditorView *view); static void closeView(Internal::EditorView *view); static const QList emptyView(Internal::EditorView *view); @@ -197,7 +198,7 @@ private: QList m_editorAreas; QPointer m_currentEditor; QPointer m_scheduledCurrentEditor; - QPointer m_currentView; + QList> m_currentView; QTimer *m_autoSaveTimer = nullptr; // actions