EditorManager: Make sure the current view is visible

If an editor area is hidden, for example by unchecking the "Editor" view
in Debug mode, this might hide the current view. This is ugly, because
opening an editor in that state either opens the editor in an invisible
view, or in case of Debug mode with hidden "Editor" view it switches to
Edit mode. Which is detrimental if the user has a separate editor window
open that could be used instead.

When an editor area is hidden, try to set a current view that is visible
(which might be the same as before).

Fixes: QTCREATORBUG-30408
Change-Id: I0eb65fddbc857b6efb12972b861b9f44204bd715
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Eike Ziller
2024-04-25 14:45:51 +02:00
parent 8fcf3a26c1
commit 6f56310e31
4 changed files with 98 additions and 32 deletions

View File

@@ -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

View File

@@ -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<EditorView> m_currentView;

View File

@@ -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<IEditor*> 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<QPointer<EditorView>> &list, EditorView *view)
{
// remove view from the list, as well as any deleted views
Utils::erase(list, [view](QPointer<EditorView> 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<EditorArea *>(current)) {
@@ -1825,14 +1837,43 @@ void EditorManagerPrivate::deleteEditors(const QList<IEditor *> &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<EditorArea>(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<EditorView> &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<EditorView *> EditorManagerPrivate::allEditorViews()
@@ -3372,7 +3416,9 @@ bool EditorManager::closeDocuments(const QList<IDocument *> &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<void()> &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

View File

@@ -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<IEditor *> emptyView(Internal::EditorView *view);
@@ -197,7 +198,7 @@ private:
QList<EditorArea *> m_editorAreas;
QPointer<IEditor> m_currentEditor;
QPointer<IEditor> m_scheduledCurrentEditor;
QPointer<EditorView> m_currentView;
QList<QPointer<EditorView>> m_currentView;
QTimer *m_autoSaveTimer = nullptr;
// actions