forked from qt-creator/qt-creator
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:
@@ -48,6 +48,11 @@ IDocument *EditorArea::currentDocument() const
|
|||||||
return m_currentDocument;
|
return m_currentDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditorView *EditorArea::currentView() const
|
||||||
|
{
|
||||||
|
return m_currentView;
|
||||||
|
}
|
||||||
|
|
||||||
void EditorArea::focusChanged(QWidget *old, QWidget *now)
|
void EditorArea::focusChanged(QWidget *old, QWidget *now)
|
||||||
{
|
{
|
||||||
Q_UNUSED(old)
|
Q_UNUSED(old)
|
||||||
@@ -104,5 +109,10 @@ void EditorArea::updateCloseSplitButton()
|
|||||||
v->setCloseSplitEnabled(false);
|
v->setCloseSplitEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorArea::hideEvent(QHideEvent *)
|
||||||
|
{
|
||||||
|
emit hidden();
|
||||||
|
}
|
||||||
|
|
||||||
} // Internal
|
} // Internal
|
||||||
} // Core
|
} // Core
|
||||||
|
@@ -22,15 +22,18 @@ public:
|
|||||||
~EditorArea() override;
|
~EditorArea() override;
|
||||||
|
|
||||||
IDocument *currentDocument() const;
|
IDocument *currentDocument() const;
|
||||||
|
EditorView *currentView() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void windowTitleNeedsUpdate();
|
void windowTitleNeedsUpdate();
|
||||||
|
void hidden();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void focusChanged(QWidget *old, QWidget *now);
|
void focusChanged(QWidget *old, QWidget *now);
|
||||||
void setCurrentView(EditorView *view);
|
void setCurrentView(EditorView *view);
|
||||||
void updateCurrentEditor(IEditor *editor);
|
void updateCurrentEditor(IEditor *editor);
|
||||||
void updateCloseSplitButton();
|
void updateCloseSplitButton();
|
||||||
|
void hideEvent(QHideEvent *) override;
|
||||||
|
|
||||||
IContext *m_context;
|
IContext *m_context;
|
||||||
QPointer<EditorView> m_currentView;
|
QPointer<EditorView> m_currentView;
|
||||||
|
@@ -687,8 +687,7 @@ void EditorManagerPrivate::init()
|
|||||||
mainEditorArea->hide();
|
mainEditorArea->hide();
|
||||||
connect(mainEditorArea, &EditorArea::windowTitleNeedsUpdate,
|
connect(mainEditorArea, &EditorArea::windowTitleNeedsUpdate,
|
||||||
this, &EditorManagerPrivate::updateWindowTitle);
|
this, &EditorManagerPrivate::updateWindowTitle);
|
||||||
connect(mainEditorArea, &QObject::destroyed, this, &EditorManagerPrivate::editorAreaDestroyed);
|
addEditorArea(mainEditorArea);
|
||||||
m_editorAreas.append(mainEditorArea);
|
|
||||||
setCurrentView(mainEditorArea->view());
|
setCurrentView(mainEditorArea->view());
|
||||||
|
|
||||||
updateActions();
|
updateActions();
|
||||||
@@ -1007,7 +1006,7 @@ IEditor *EditorManagerPrivate::openEditorWith(const FilePath &filePath, Id edito
|
|||||||
IEditor *EditorManagerPrivate::activateEditorForDocument(EditorView *view, IDocument *document,
|
IEditor *EditorManagerPrivate::activateEditorForDocument(EditorView *view, IDocument *document,
|
||||||
EditorManager::OpenEditorFlags flags)
|
EditorManager::OpenEditorFlags flags)
|
||||||
{
|
{
|
||||||
Q_ASSERT(view);
|
QTC_ASSERT(view, return nullptr);
|
||||||
IEditor *editor = view->editorForDocument(document);
|
IEditor *editor = view->editorForDocument(document);
|
||||||
if (!editor) {
|
if (!editor) {
|
||||||
const QList<IEditor*> editors = DocumentModel::editorsForDocument(document);
|
const QList<IEditor*> editors = DocumentModel::editorsForDocument(document);
|
||||||
@@ -1081,8 +1080,9 @@ void EditorManagerPrivate::doEscapeKeyFocusMoveMagic()
|
|||||||
return;
|
return;
|
||||||
QWidget *focus = QApplication::focusWidget();
|
QWidget *focus = QApplication::focusWidget();
|
||||||
EditorView *editorView = currentEditorView();
|
EditorView *editorView = currentEditorView();
|
||||||
bool editorViewActive = (focus && focus == editorView->focusWidget());
|
QTC_CHECK(editorView);
|
||||||
bool editorViewVisible = editorView->isVisible();
|
bool editorViewActive = (editorView && focus && focus == editorView->focusWidget());
|
||||||
|
bool editorViewVisible = editorView && editorView->isVisible();
|
||||||
|
|
||||||
bool stuffHidden = false;
|
bool stuffHidden = false;
|
||||||
FindToolBarPlaceHolder *findPane = FindToolBarPlaceHolder::getCurrent();
|
FindToolBarPlaceHolder *findPane = FindToolBarPlaceHolder::getCurrent();
|
||||||
@@ -1422,7 +1422,7 @@ IEditor *EditorManagerPrivate::duplicateEditor(IEditor *editor)
|
|||||||
IEditor *EditorManagerPrivate::activateEditor(EditorView *view, IEditor *editor,
|
IEditor *EditorManagerPrivate::activateEditor(EditorView *view, IEditor *editor,
|
||||||
EditorManager::OpenEditorFlags flags)
|
EditorManager::OpenEditorFlags flags)
|
||||||
{
|
{
|
||||||
Q_ASSERT(view);
|
QTC_ASSERT(view, return nullptr);
|
||||||
|
|
||||||
if (!editor)
|
if (!editor)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -1692,10 +1692,17 @@ int EditorManagerPrivate::visibleDocumentsCount()
|
|||||||
return visibleDocuments.count();
|
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)
|
void EditorManagerPrivate::setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory)
|
||||||
{
|
{
|
||||||
IEditor *previousEditor = d->m_currentEditor;
|
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;
|
EditorView *view = editor ? viewForEditor(editor) : previousView;
|
||||||
|
|
||||||
if (editor != previousEditor) {
|
if (editor != previousEditor) {
|
||||||
@@ -1711,7 +1718,7 @@ void EditorManagerPrivate::setCurrentEditor(IEditor *editor, bool ignoreNavigati
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (QTC_GUARD(view)) { // we should always have a view
|
if (QTC_GUARD(view)) { // we should always have a view
|
||||||
d->m_currentView = view;
|
setView(d->m_currentView, view);
|
||||||
view->setCurrentEditor(editor);
|
view->setCurrentEditor(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1723,14 +1730,17 @@ void EditorManagerPrivate::setCurrentEditor(IEditor *editor, bool ignoreNavigati
|
|||||||
|
|
||||||
void EditorManagerPrivate::setCurrentView(EditorView *view)
|
void EditorManagerPrivate::setCurrentView(EditorView *view)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(view, return); // view should always have a view
|
QTC_ASSERT(view, return); // we should always have a view
|
||||||
if (view != d->m_currentView) {
|
// currentView can empty if and only if we are currently initializing and setting
|
||||||
EditorView *previousView = d->m_currentView;
|
// the main editor area's view as the current one
|
||||||
d->m_currentView = view;
|
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)
|
if (previousView)
|
||||||
previousView->update();
|
previousView->update();
|
||||||
if (d->m_currentView)
|
if (d->m_currentView.constFirst())
|
||||||
view->update();
|
view->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1739,6 +1749,8 @@ void EditorManagerPrivate::setCurrentView(EditorView *view)
|
|||||||
|
|
||||||
EditorArea *EditorManagerPrivate::findEditorArea(const EditorView *view, int *areaIndex)
|
EditorArea *EditorManagerPrivate::findEditorArea(const EditorView *view, int *areaIndex)
|
||||||
{
|
{
|
||||||
|
if (!view)
|
||||||
|
return nullptr;
|
||||||
SplitterOrView *current = view->parentSplitterOrView();
|
SplitterOrView *current = view->parentSplitterOrView();
|
||||||
while (current) {
|
while (current) {
|
||||||
if (auto area = qobject_cast<EditorArea *>(current)) {
|
if (auto area = qobject_cast<EditorArea *>(current)) {
|
||||||
@@ -1825,14 +1837,43 @@ void EditorManagerPrivate::deleteEditors(const QList<IEditor *> &editors)
|
|||||||
EditorWindow *EditorManagerPrivate::createEditorWindow()
|
EditorWindow *EditorManagerPrivate::createEditorWindow()
|
||||||
{
|
{
|
||||||
auto win = new EditorWindow;
|
auto win = new EditorWindow;
|
||||||
EditorArea *area = win->editorArea();
|
addEditorArea(win->editorArea());
|
||||||
|
return win;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorManagerPrivate::addEditorArea(EditorArea *area)
|
||||||
|
{
|
||||||
d->m_editorAreas.append(area);
|
d->m_editorAreas.append(area);
|
||||||
connect(area, &QObject::destroyed, d, &EditorManagerPrivate::editorAreaDestroyed);
|
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)
|
void EditorManagerPrivate::splitNewWindow(EditorView *view)
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(view, return);
|
||||||
IEditor *editor = view->currentEditor();
|
IEditor *editor = view->currentEditor();
|
||||||
IEditor *newEditor = nullptr;
|
IEditor *newEditor = nullptr;
|
||||||
const QByteArray state = editor ? editor->saveState() : QByteArray();
|
const QByteArray state = editor ? editor->saveState() : QByteArray();
|
||||||
@@ -2107,6 +2148,7 @@ void EditorManagerPrivate::gotoNextDocHistory()
|
|||||||
dialog->selectNextEditor();
|
dialog->selectNextEditor();
|
||||||
} else {
|
} else {
|
||||||
EditorView *view = currentEditorView();
|
EditorView *view = currentEditorView();
|
||||||
|
QTC_ASSERT(view, return);
|
||||||
dialog->setEditors(d->m_globalHistory, view);
|
dialog->setEditors(d->m_globalHistory, view);
|
||||||
dialog->selectNextEditor();
|
dialog->selectNextEditor();
|
||||||
showPopupOrSelectDocument();
|
showPopupOrSelectDocument();
|
||||||
@@ -2120,6 +2162,7 @@ void EditorManagerPrivate::gotoPreviousDocHistory()
|
|||||||
dialog->selectPreviousEditor();
|
dialog->selectPreviousEditor();
|
||||||
} else {
|
} else {
|
||||||
EditorView *view = currentEditorView();
|
EditorView *view = currentEditorView();
|
||||||
|
QTC_ASSERT(view, return);
|
||||||
dialog->setEditors(d->m_globalHistory, view);
|
dialog->setEditors(d->m_globalHistory, view);
|
||||||
dialog->selectPreviousEditor();
|
dialog->selectPreviousEditor();
|
||||||
showPopupOrSelectDocument();
|
showPopupOrSelectDocument();
|
||||||
@@ -2128,14 +2171,15 @@ void EditorManagerPrivate::gotoPreviousDocHistory()
|
|||||||
|
|
||||||
void EditorManagerPrivate::gotoLastEditLocation()
|
void EditorManagerPrivate::gotoLastEditLocation()
|
||||||
{
|
{
|
||||||
currentEditorView()->goToEditLocation(d->m_globalLastEditLocation);
|
EditorView *view = currentEditorView();
|
||||||
|
QTC_ASSERT(view, return);
|
||||||
|
view->goToEditLocation(d->m_globalLastEditLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorManagerPrivate::gotoNextSplit()
|
void EditorManagerPrivate::gotoNextSplit()
|
||||||
{
|
{
|
||||||
EditorView *view = currentEditorView();
|
EditorView *view = currentEditorView();
|
||||||
if (!view)
|
QTC_ASSERT(view, return);
|
||||||
return;
|
|
||||||
EditorView *nextView = view->findNextView();
|
EditorView *nextView = view->findNextView();
|
||||||
if (!nextView) {
|
if (!nextView) {
|
||||||
// we are in the "last" view in this editor area
|
// we are in the "last" view in this editor area
|
||||||
@@ -2157,8 +2201,7 @@ void EditorManagerPrivate::gotoNextSplit()
|
|||||||
void EditorManagerPrivate::gotoPreviousSplit()
|
void EditorManagerPrivate::gotoPreviousSplit()
|
||||||
{
|
{
|
||||||
EditorView *view = currentEditorView();
|
EditorView *view = currentEditorView();
|
||||||
if (!view)
|
QTC_ASSERT(view, return);
|
||||||
return;
|
|
||||||
EditorView *prevView = view->findPreviousView();
|
EditorView *prevView = view->findPreviousView();
|
||||||
if (!prevView) {
|
if (!prevView) {
|
||||||
// we are in the "first" view in this editor area
|
// we are in the "first" view in this editor area
|
||||||
@@ -2600,7 +2643,8 @@ void EditorManagerPrivate::setCurrentEditorFromContextChange()
|
|||||||
|
|
||||||
EditorView *EditorManagerPrivate::currentEditorView()
|
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()
|
QList<EditorView *> EditorManagerPrivate::allEditorViews()
|
||||||
@@ -3372,7 +3416,9 @@ bool EditorManager::closeDocuments(const QList<IDocument *> &documents, bool ask
|
|||||||
*/
|
*/
|
||||||
void EditorManager::addCurrentPositionToNavigationHistory(const QByteArray &saveState)
|
void EditorManager::addCurrentPositionToNavigationHistory(const QByteArray &saveState)
|
||||||
{
|
{
|
||||||
EditorManagerPrivate::currentEditorView()->addCurrentPositionToNavigationHistory(saveState);
|
EditorView *view = EditorManagerPrivate::currentEditorView();
|
||||||
|
QTC_ASSERT(view, return);
|
||||||
|
view->addCurrentPositionToNavigationHistory(saveState);
|
||||||
EditorManagerPrivate::updateActions();
|
EditorManagerPrivate::updateActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3405,7 +3451,9 @@ void EditorManager::setLastEditLocation(const IEditor* editor)
|
|||||||
*/
|
*/
|
||||||
void EditorManager::cutForwardNavigationHistory()
|
void EditorManager::cutForwardNavigationHistory()
|
||||||
{
|
{
|
||||||
EditorManagerPrivate::currentEditorView()->cutForwardNavigationHistory();
|
EditorView *view = EditorManagerPrivate::currentEditorView();
|
||||||
|
QTC_ASSERT(view, return);
|
||||||
|
view->cutForwardNavigationHistory();
|
||||||
EditorManagerPrivate::updateActions();
|
EditorManagerPrivate::updateActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3417,9 +3465,10 @@ void EditorManager::cutForwardNavigationHistory()
|
|||||||
*/
|
*/
|
||||||
void EditorManager::goBackInNavigationHistory()
|
void EditorManager::goBackInNavigationHistory()
|
||||||
{
|
{
|
||||||
EditorManagerPrivate::currentEditorView()->goBackInNavigationHistory();
|
EditorView *view = EditorManagerPrivate::currentEditorView();
|
||||||
|
QTC_ASSERT(view, return);
|
||||||
|
view->goBackInNavigationHistory();
|
||||||
EditorManagerPrivate::updateActions();
|
EditorManagerPrivate::updateActions();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -3430,7 +3479,9 @@ void EditorManager::goBackInNavigationHistory()
|
|||||||
*/
|
*/
|
||||||
void EditorManager::goForwardInNavigationHistory()
|
void EditorManager::goForwardInNavigationHistory()
|
||||||
{
|
{
|
||||||
EditorManagerPrivate::currentEditorView()->goForwardInNavigationHistory();
|
EditorView *view = EditorManagerPrivate::currentEditorView();
|
||||||
|
QTC_ASSERT(view, return);
|
||||||
|
view->goForwardInNavigationHistory();
|
||||||
EditorManagerPrivate::updateActions();
|
EditorManagerPrivate::updateActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3600,9 +3651,9 @@ void EditorManager::showEditorStatusBar(const QString &id,
|
|||||||
QObject *object,
|
QObject *object,
|
||||||
const std::function<void()> &function)
|
const std::function<void()> &function)
|
||||||
{
|
{
|
||||||
|
EditorView *view = EditorManagerPrivate::currentEditorView();
|
||||||
EditorManagerPrivate::currentEditorView()->showEditorStatusBar(
|
QTC_ASSERT(view, return);
|
||||||
id, infoText, buttonText, object, function);
|
view->showEditorStatusBar(id, infoText, buttonText, object, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -3611,6 +3662,8 @@ void EditorManager::showEditorStatusBar(const QString &id,
|
|||||||
void EditorManager::hideEditorStatusBar(const QString &id)
|
void EditorManager::hideEditorStatusBar(const QString &id)
|
||||||
{
|
{
|
||||||
// TODO: what if the current editor view betwenn show and hideEditorStatusBar changed?
|
// TODO: what if the current editor view betwenn show and hideEditorStatusBar changed?
|
||||||
|
EditorView *view = EditorManagerPrivate::currentEditorView();
|
||||||
|
QTC_ASSERT(view, return);
|
||||||
EditorManagerPrivate::currentEditorView()->hideEditorStatusBar(id);
|
EditorManagerPrivate::currentEditorView()->hideEditorStatusBar(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3664,8 +3717,7 @@ void EditorManager::splitSideBySide()
|
|||||||
void EditorManager::gotoOtherSplit()
|
void EditorManager::gotoOtherSplit()
|
||||||
{
|
{
|
||||||
EditorView *view = EditorManagerPrivate::currentEditorView();
|
EditorView *view = EditorManagerPrivate::currentEditorView();
|
||||||
if (!view)
|
QTC_ASSERT(view, return);
|
||||||
return;
|
|
||||||
EditorView *nextView = view->findNextView();
|
EditorView *nextView = view->findNextView();
|
||||||
if (!nextView) {
|
if (!nextView) {
|
||||||
// we are in the "last" view in this editor area
|
// we are in the "last" view in this editor area
|
||||||
|
@@ -100,6 +100,7 @@ public:
|
|||||||
Qt::CaseSensitivity sensitivity);
|
Qt::CaseSensitivity sensitivity);
|
||||||
|
|
||||||
static EditorWindow *createEditorWindow();
|
static EditorWindow *createEditorWindow();
|
||||||
|
static void addEditorArea(EditorArea *area);
|
||||||
static void splitNewWindow(Internal::EditorView *view);
|
static void splitNewWindow(Internal::EditorView *view);
|
||||||
static void closeView(Internal::EditorView *view);
|
static void closeView(Internal::EditorView *view);
|
||||||
static const QList<IEditor *> emptyView(Internal::EditorView *view);
|
static const QList<IEditor *> emptyView(Internal::EditorView *view);
|
||||||
@@ -197,7 +198,7 @@ private:
|
|||||||
QList<EditorArea *> m_editorAreas;
|
QList<EditorArea *> m_editorAreas;
|
||||||
QPointer<IEditor> m_currentEditor;
|
QPointer<IEditor> m_currentEditor;
|
||||||
QPointer<IEditor> m_scheduledCurrentEditor;
|
QPointer<IEditor> m_scheduledCurrentEditor;
|
||||||
QPointer<EditorView> m_currentView;
|
QList<QPointer<EditorView>> m_currentView;
|
||||||
QTimer *m_autoSaveTimer = nullptr;
|
QTimer *m_autoSaveTimer = nullptr;
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
|
Reference in New Issue
Block a user