Add split in new window action for editor views.

A few details are still to be done:
- extra windows are not restored yet
- window title of extra windows should show information about current
  editor
- the "raise main window" hack for Linux doesn't work with Qt 5

But it should already now be quite usable.

Change-Id: I638583ee4b2abe32e95c261bdf31b4a10b472748
Reviewed-by: David Schulz <david.schulz@digia.com>
This commit is contained in:
Eike Ziller
2013-04-15 12:53:34 +02:00
committed by David Schulz
parent d1cb5dade0
commit 65ce453c4e
18 changed files with 255 additions and 62 deletions

View File

@@ -41,6 +41,7 @@ class QTCREATOR_UTILS_EXPORT AppMainWindow : public QMainWindow
public: public:
AppMainWindow(); AppMainWindow();
public slots:
void raiseWindow(); void raiseWindow();
signals: signals:

View File

@@ -105,6 +105,7 @@ const char ZOOM_WINDOW[] = "QtCreator.ZoomWindow";
const char SPLIT[] = "QtCreator.Split"; const char SPLIT[] = "QtCreator.Split";
const char SPLIT_SIDE_BY_SIDE[] = "QtCreator.SplitSideBySide"; const char SPLIT_SIDE_BY_SIDE[] = "QtCreator.SplitSideBySide";
const char SPLIT_NEW_WINDOW[] = "QtCreator.SplitNewWindow";
const char REMOVE_CURRENT_SPLIT[] = "QtCreator.RemoveCurrentSplit"; const char REMOVE_CURRENT_SPLIT[] = "QtCreator.RemoveCurrentSplit";
const char REMOVE_ALL_SPLITS[] = "QtCreator.RemoveAllSplits"; const char REMOVE_ALL_SPLITS[] = "QtCreator.RemoveAllSplits";
const char GOTO_OTHER_SPLIT[] = "QtCreator.GotoOtherSplit"; const char GOTO_OTHER_SPLIT[] = "QtCreator.GotoOtherSplit";

View File

@@ -122,7 +122,7 @@ QObject *CorePlugin::remoteCommand(const QStringList & /* options */, const QStr
{ {
IDocument *res = m_mainWindow->openFiles( IDocument *res = m_mainWindow->openFiles(
args, ICore::OpenFilesFlags(ICore::SwitchMode | ICore::CanContainLineNumbers)); args, ICore::OpenFilesFlags(ICore::SwitchMode | ICore::CanContainLineNumbers));
m_mainWindow->activateWindow(); m_mainWindow->raiseWindow();
return res; return res;
} }

View File

@@ -176,8 +176,9 @@ struct EditorManagerPrivate
explicit EditorManagerPrivate(QWidget *parent); explicit EditorManagerPrivate(QWidget *parent);
~EditorManagerPrivate(); ~EditorManagerPrivate();
QList<EditLocation> m_globalHistory; QList<EditLocation> m_globalHistory;
Internal::SplitterOrView *m_splitter; QList<Internal::SplitterOrView *> m_root;
QPointer<IEditor> m_currentEditor; QPointer<IEditor> m_currentEditor;
QPointer<IEditor> m_scheduledCurrentEditor;
QPointer<EditorView> m_currentView; QPointer<EditorView> m_currentView;
QTimer *m_autoSaveTimer; QTimer *m_autoSaveTimer;
@@ -194,6 +195,7 @@ struct EditorManagerPrivate
QAction *m_goForwardAction; QAction *m_goForwardAction;
QAction *m_splitAction; QAction *m_splitAction;
QAction *m_splitSideBySideAction; QAction *m_splitSideBySideAction;
QAction *m_splitNewWindowAction;
QAction *m_removeCurrentSplitAction; QAction *m_removeCurrentSplitAction;
QAction *m_removeAllSplitsAction; QAction *m_removeAllSplitsAction;
QAction *m_gotoOtherSplitAction; QAction *m_gotoOtherSplitAction;
@@ -227,7 +229,6 @@ struct EditorManagerPrivate
} }
EditorManagerPrivate::EditorManagerPrivate(QWidget *parent) : EditorManagerPrivate::EditorManagerPrivate(QWidget *parent) :
m_splitter(0),
m_autoSaveTimer(0), m_autoSaveTimer(0),
m_revertToSavedAction(new QAction(EditorManager::tr("Revert to Saved"), parent)), m_revertToSavedAction(new QAction(EditorManager::tr("Revert to Saved"), parent)),
m_saveAction(new QAction(parent)), m_saveAction(new QAction(parent)),
@@ -382,6 +383,12 @@ EditorManager::EditorManager(QWidget *parent) :
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
connect(d->m_splitSideBySideAction, SIGNAL(triggered()), this, SLOT(splitSideBySide())); connect(d->m_splitSideBySideAction, SIGNAL(triggered()), this, SLOT(splitSideBySide()));
d->m_splitNewWindowAction = new QAction(tr("Split New Window"), this);
cmd = ActionManager::registerAction(d->m_splitNewWindowAction, Constants::SPLIT_NEW_WINDOW, editManagerContext);
cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,4") : tr("Ctrl+E,4")));
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
connect(d->m_splitNewWindowAction, SIGNAL(triggered()), this, SLOT(splitNewWindow()));
d->m_removeCurrentSplitAction = new QAction(tr("Remove Current Split"), this); d->m_removeCurrentSplitAction = new QAction(tr("Remove Current Split"), this);
cmd = ActionManager::registerAction(d->m_removeCurrentSplitAction, Constants::REMOVE_CURRENT_SPLIT, editManagerContext); cmd = ActionManager::registerAction(d->m_removeCurrentSplitAction, Constants::REMOVE_CURRENT_SPLIT, editManagerContext);
cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,0") : tr("Ctrl+E,0"))); cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,0") : tr("Ctrl+E,0")));
@@ -417,12 +424,14 @@ EditorManager::EditorManager(QWidget *parent) :
advancedMenu->addSeparator(editManagerContext, Constants::G_EDIT_EDITOR); advancedMenu->addSeparator(editManagerContext, Constants::G_EDIT_EDITOR);
// other setup // other setup
d->m_splitter = new SplitterOrView(); SplitterOrView *firstRoot = new SplitterOrView();
d->m_root.append(firstRoot);
d->m_currentView = firstRoot->view();
QHBoxLayout *layout = new QHBoxLayout(this); QHBoxLayout *layout = new QHBoxLayout(this);
layout->setMargin(0); layout->setMargin(0);
layout->setSpacing(0); layout->setSpacing(0);
layout->addWidget(d->m_splitter); layout->addWidget(firstRoot);
updateActions(); updateActions();
@@ -444,6 +453,15 @@ EditorManager::~EditorManager()
ExtensionSystem::PluginManager::removeObject(d->m_openEditorsFactory); ExtensionSystem::PluginManager::removeObject(d->m_openEditorsFactory);
delete d->m_openEditorsFactory; delete d->m_openEditorsFactory;
} }
// close all extra windows
for (int i = 1; i < d->m_root.size(); ++i) {
SplitterOrView *root = d->m_root.at(i);
disconnect(root, SIGNAL(destroyed(QObject*)), this, SLOT(rootDestroyed(QObject*)));
delete root;
}
d->m_root.clear();
delete d; delete d;
} }
@@ -490,11 +508,19 @@ void EditorManager::handleContextChange(Core::IContext *context)
{ {
if (debugEditorManager) if (debugEditorManager)
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
d->m_scheduledCurrentEditor = 0;
IEditor *editor = context ? qobject_cast<IEditor*>(context) : 0; IEditor *editor = context ? qobject_cast<IEditor*>(context) : 0;
if (editor) if (editor && editor != d->m_currentEditor) {
setCurrentEditor(editor); // Delay actually setting the current editor to after the current event queue has been handled
else // Without doing this, e.g. clicking into projects tree or locator would always open editors
// in the main window. That is because clicking anywhere in the main window (even over e.g.
// the locator line edit) first activates the window and sets focus to its focus widget.
// Only afterwards the focus is shifted to the widget that received the click.
d->m_scheduledCurrentEditor = editor;
QTimer::singleShot(0, this, SLOT(setCurrentEditorFromContextChange()));
} else {
updateActions(); updateActions();
}
} }
void EditorManager::setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory) void EditorManager::setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory)
@@ -535,18 +561,29 @@ void EditorManager::setCurrentView(Internal::EditorView *view)
if (view && !view->currentEditor()) { if (view && !view->currentEditor()) {
view->setFocus(); view->setFocus();
view->activateWindow(); ICore::raiseWindow(view);
} }
} }
Internal::EditorView *EditorManager::currentEditorView() const Internal::EditorView *EditorManager::currentEditorView() const
{ {
EditorView *view = d->m_currentView; EditorView *view = d->m_currentView;
if (!view) if (!view) {
view = d->m_currentEditor ? viewForEditor(d->m_currentEditor) if (d->m_currentEditor) {
: d->m_splitter->findFirstView(); view = viewForEditor(d->m_currentEditor);
if (!view) QTC_ASSERT(view, view = d->m_root.first()->findFirstView());
return d->m_splitter->view(); }
QTC_CHECK(view);
if (!view) { // should not happen, we should always have either currentview or currentdocument
foreach (SplitterOrView *root, d->m_root) {
if (root->window()->isActiveWindow()) {
view = root->findFirstView();
break;
}
}
QTC_ASSERT(view, view = d->m_root.first()->findFirstView());
}
}
return view; return view;
} }
@@ -561,6 +598,15 @@ EditorView *EditorManager::viewForEditor(IEditor *editor)
return 0; return 0;
} }
SplitterOrView *EditorManager::findRoot(EditorView *view)
{
SplitterOrView *current = view->parentSplitterOrView();
while (current && !m_instance->d->m_root.contains(current)) {
current = current->findParentSplitter();
}
return current;
}
QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) const QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) const
{ {
QList<IEditor *> found; QList<IEditor *> found;
@@ -622,6 +668,30 @@ void EditorManager::emptyView(Core::Internal::EditorView *view)
} }
} }
void EditorManager::splitNewWindow(Internal::EditorView *view)
{
SplitterOrView *splitter;
IEditor *editor = view->currentEditor();
IEditor *newEditor = 0;
if (editor && editor->duplicateSupported())
newEditor = m_instance->duplicateEditor(editor);
else
newEditor = editor; // move to the new view
splitter = new SplitterOrView;
splitter->setAttribute(Qt::WA_DeleteOnClose);
splitter->setAttribute(Qt::WA_QuitOnClose, false); // don't prevent Qt Creator from closing
splitter->resize(QSize(800, 600));
splitter->show();
ICore::raiseWindow(splitter);
if (newEditor)
m_instance->activateEditor(splitter->view(), newEditor, IgnoreNavigationHistory);
else
splitter->view()->setFocus();
m_instance->d->m_root.append(splitter);
connect(splitter, SIGNAL(destroyed(QObject*)), m_instance, SLOT(rootDestroyed(QObject*)));
m_instance->updateActions();
}
void EditorManager::closeView(Core::Internal::EditorView *view) void EditorManager::closeView(Core::Internal::EditorView *view)
{ {
if (!view) if (!view)
@@ -807,6 +877,57 @@ void EditorManager::openTerminal()
Core::FileUtils::openTerminal(path); Core::FileUtils::openTerminal(path);
} }
void EditorManager::rootDestroyed(QObject *root)
{
QWidget *activeWin = qApp->activeWindow();
SplitterOrView *newActiveRoot = 0;
for (int i = 0; i < d->m_root.size(); ++i) {
SplitterOrView *r = d->m_root.at(i);
if (r == root)
d->m_root.removeAll(r);
else if (r->window() == activeWin)
newActiveRoot = r;
}
// check if the destroyed root had the current view or current editor
if (d->m_currentEditor || (d->m_currentView && d->m_currentView->parentSplitterOrView() != root))
return;
// we need to set a new current editor or view
if (!newActiveRoot) {
// some window managers behave weird and don't activate another window
// or there might be a Qt Creator toplevel activated that doesn't have editor windows
newActiveRoot = d->m_root.first();
}
// check if the focusWidget points to some view
SplitterOrView *focusSplitterOrView = 0;
QWidget *candidate = newActiveRoot->focusWidget();
while (candidate && candidate != newActiveRoot) {
if ((focusSplitterOrView = qobject_cast<SplitterOrView *>(candidate)))
break;
candidate = candidate->parentWidget();
}
// focusWidget might have been 0
if (!focusSplitterOrView)
focusSplitterOrView = newActiveRoot->findFirstView()->parentSplitterOrView();
QTC_ASSERT(focusSplitterOrView, focusSplitterOrView = newActiveRoot);
EditorView *focusView = focusSplitterOrView->findFirstView(); // can be just focusSplitterOrView
QTC_ASSERT(focusView, focusView = newActiveRoot->findFirstView());
QTC_ASSERT(focusView, return);
if (focusView->currentEditor())
setCurrentEditor(focusView->currentEditor());
else
setCurrentView(focusView);
}
void EditorManager::setCurrentEditorFromContextChange()
{
if (!d->m_scheduledCurrentEditor)
return;
IEditor *newCurrent = d->m_scheduledCurrentEditor;
d->m_scheduledCurrentEditor = 0;
setCurrentEditor(newCurrent);
}
void EditorManager::closeEditor(Core::IEditor *editor) void EditorManager::closeEditor(Core::IEditor *editor)
{ {
if (!editor) if (!editor)
@@ -922,6 +1043,8 @@ bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool ask
if (currentView) { if (currentView) {
if (IEditor *editor = currentView->currentEditor()) if (IEditor *editor = currentView->currentEditor())
activateEditor(currentView, editor); activateEditor(currentView, editor);
else
setCurrentView(currentView);
} }
if (!currentEditor()) { if (!currentEditor()) {
@@ -1040,7 +1163,7 @@ Core::IEditor *EditorManager::placeEditor(Core::Internal::EditorView *view, Core
void EditorManager::activateEditor(Core::IEditor *editor, OpenEditorFlags flags) void EditorManager::activateEditor(Core::IEditor *editor, OpenEditorFlags flags)
{ {
EditorView *view = viewForEditor(editor); EditorView *view = viewForEditor(editor);
// TODO an IEditor doesn't have to belong to a view, which makes this method a bit funny // an IEditor doesn't have to belong to a view, it might be kept in storage by the editor model
if (!view) if (!view)
view = m_instance->currentEditorView(); view = m_instance->currentEditorView();
m_instance->activateEditor(view, editor, flags); m_instance->activateEditor(view, editor, flags);
@@ -1064,7 +1187,7 @@ Core::IEditor *EditorManager::activateEditor(Core::Internal::EditorView *view, C
switchToPreferedMode(); switchToPreferedMode();
if (isVisible()) { if (isVisible()) {
editor->widget()->setFocus(); editor->widget()->setFocus();
editor->widget()->activateWindow(); ICore::raiseWindow(editor->widget());
} }
} }
return editor; return editor;
@@ -1806,7 +1929,8 @@ void EditorManager::updateActions()
window()->setWindowModified(false); window()->setWindowModified(false);
} }
setCloseSplitEnabled(d->m_splitter, d->m_splitter->isSplitter()); foreach (SplitterOrView *root, d->m_root)
setCloseSplitEnabled(root, root->isSplitter());
QString quotedName; QString quotedName;
if (!fileName.isEmpty()) if (!fileName.isEmpty())
@@ -1825,7 +1949,9 @@ void EditorManager::updateActions()
d->m_goBackAction->setEnabled(view ? view->canGoBack() : false); d->m_goBackAction->setEnabled(view ? view->canGoBack() : false);
d->m_goForwardAction->setEnabled(view ? view->canGoForward() : false); d->m_goForwardAction->setEnabled(view ? view->canGoForward() : false);
bool hasSplitter = d->m_splitter->isSplitter(); SplitterOrView *viewParent = (view ? view->parentSplitterOrView() : 0);
SplitterOrView *parentSplitter = (viewParent ? viewParent->findParentSplitter() : 0);
bool hasSplitter = parentSplitter && parentSplitter->isSplitter();
d->m_removeCurrentSplitAction->setEnabled(hasSplitter); d->m_removeCurrentSplitAction->setEnabled(hasSplitter);
d->m_removeAllSplitsAction->setEnabled(hasSplitter); d->m_removeAllSplitsAction->setEnabled(hasSplitter);
d->m_gotoOtherSplitAction->setEnabled(hasSplitter); d->m_gotoOtherSplitAction->setEnabled(hasSplitter);
@@ -1846,25 +1972,31 @@ void EditorManager::setCloseSplitEnabled(SplitterOrView *splitterOrView, bool en
bool EditorManager::hasSplitter() const bool EditorManager::hasSplitter() const
{ {
return d->m_splitter->isSplitter(); EditorView *view = currentEditorView();
QTC_ASSERT(view, return false);
SplitterOrView *root = findRoot(view);
QTC_ASSERT(root, return false);
return root->isSplitter();
} }
QList<IEditor*> EditorManager::visibleEditors() const QList<IEditor*> EditorManager::visibleEditors() const
{ {
QList<IEditor *> editors; QList<IEditor *> editors;
if (d->m_splitter->isSplitter()) { foreach (SplitterOrView *root, d->m_root) {
EditorView *firstView = d->m_splitter->findFirstView(); if (root->isSplitter()) {
EditorView *view = firstView; EditorView *firstView = root->findFirstView();
if (view) { EditorView *view = firstView;
do { if (view) {
if (view->currentEditor()) do {
editors.append(view->currentEditor()); if (view->currentEditor())
view = view->findNextView(); editors.append(view->currentEditor());
} while (view && view != firstView); view = view->findNextView();
} while (view && view != firstView);
}
} else {
if (root->editor())
editors.append(root->editor());
} }
} else {
if (d->m_splitter->editor())
editors.append(d->m_splitter->editor());
} }
return editors; return editors;
} }
@@ -1959,7 +2091,7 @@ QByteArray EditorManager::saveState() const
stream << entry.fileName() << entry.displayName() << entry.id(); stream << entry.fileName() << entry.displayName() << entry.id();
} }
stream << d->m_splitter->saveState(); stream << d->m_root.first()->saveState(); // TODO
return bytes; return bytes;
} }
@@ -1967,7 +2099,11 @@ QByteArray EditorManager::saveState() const
bool EditorManager::restoreState(const QByteArray &state) bool EditorManager::restoreState(const QByteArray &state)
{ {
closeAllEditors(true); closeAllEditors(true);
removeAllSplits(); // remove extra windows
for (int i = d->m_root.count() - 1; i > 0 /* keep first alive */; --i)
delete d->m_root.at(i); // automatically removes it from list
if (d->m_root.first()->isSplitter())
removeAllSplits();
QDataStream stream(state); QDataStream stream(state);
QByteArray version; QByteArray version;
@@ -2004,7 +2140,7 @@ bool EditorManager::restoreState(const QByteArray &state)
QByteArray splitterstates; QByteArray splitterstates;
stream >> splitterstates; stream >> splitterstates;
d->m_splitter->restoreState(splitterstates); d->m_root.first()->restoreState(splitterstates); // TODO
// splitting and stuff results in focus trouble, that's why we set the focus again after restoration // splitting and stuff results in focus trouble, that's why we set the focus again after restoration
if (d->m_currentEditor) { if (d->m_currentEditor) {
@@ -2180,12 +2316,17 @@ void EditorManager::splitSideBySide()
split(Qt::Horizontal); split(Qt::Horizontal);
} }
void EditorManager::splitNewWindow()
{
splitNewWindow(currentEditorView());
}
void EditorManager::removeCurrentSplit() void EditorManager::removeCurrentSplit()
{ {
EditorView *viewToClose = currentEditorView(); EditorView *viewToClose = currentEditorView();
if (!viewToClose || viewToClose == d->m_splitter->view()) QTC_ASSERT(viewToClose, return);
return; QTC_ASSERT(!d->m_root.contains(viewToClose->parentSplitterOrView()), return);
closeView(viewToClose); closeView(viewToClose);
updateActions(); updateActions();
@@ -2193,23 +2334,29 @@ void EditorManager::removeCurrentSplit()
void EditorManager::removeAllSplits() void EditorManager::removeAllSplits()
{ {
if (!d->m_splitter->isSplitter()) EditorView *view = currentEditorView();
return; QTC_ASSERT(view, return);
d->m_splitter->unsplitAll(); SplitterOrView *root = findRoot(view);
QTC_ASSERT(root, return);
root->unsplitAll();
} }
void EditorManager::gotoOtherSplit() void EditorManager::gotoOtherSplit()
{ {
if (!d->m_splitter->isSplitter()) EditorView *view = currentEditorView();
if (!view)
return;
SplitterOrView *root = findRoot(view);
QTC_ASSERT(root, return);
if (!root->isSplitter())
splitSideBySide(); splitSideBySide();
EditorView *view = currentEditorView();
view = view->findNextView(); view = view->findNextView();
if (view) { if (view) {
if (IEditor *editor = view->currentEditor()) { if (IEditor *editor = view->currentEditor()) {
setCurrentEditor(editor, true); setCurrentEditor(editor, true);
editor->widget()->setFocus(); editor->widget()->setFocus();
editor->widget()->activateWindow(); ICore::raiseWindow(editor->widget());
} else { } else {
setCurrentView(view); setCurrentView(view);
} }

View File

@@ -231,12 +231,16 @@ private slots:
void showInGraphicalShell(); void showInGraphicalShell();
void openTerminal(); void openTerminal();
void rootDestroyed(QObject *root);
void setCurrentEditorFromContextChange();
public slots: public slots:
void goBackInNavigationHistory(); void goBackInNavigationHistory();
void goForwardInNavigationHistory(); void goForwardInNavigationHistory();
void split(Qt::Orientation orientation); void split(Qt::Orientation orientation);
void split(); void split();
void splitSideBySide(); void splitSideBySide();
void splitNewWindow();
void removeCurrentSplit(); void removeCurrentSplit();
void removeAllSplits(); void removeAllSplits();
void gotoOtherSplit(); void gotoOtherSplit();
@@ -260,11 +264,13 @@ private:
void setCurrentView(Internal::EditorView *view); void setCurrentView(Internal::EditorView *view);
Internal::EditorView *currentEditorView() const; Internal::EditorView *currentEditorView() const;
static Internal::EditorView *viewForEditor(IEditor *editor); static Internal::EditorView *viewForEditor(IEditor *editor);
static Internal::SplitterOrView *findRoot(Internal::EditorView *view);
void closeEditor(IEditor *editor); void closeEditor(IEditor *editor);
void closeDuplicate(IEditor *editor); void closeDuplicate(IEditor *editor);
void closeView(Internal::EditorView *view); void closeView(Internal::EditorView *view);
void emptyView(Internal::EditorView *view); void emptyView(Internal::EditorView *view);
static void splitNewWindow(Internal::EditorView *view);
IEditor *pickUnusedEditor() const; IEditor *pickUnusedEditor() const;
void addDocumentToRecentFiles(IDocument *document); void addDocumentToRecentFiles(IDocument *document);
void switchToPreferedMode(); void switchToPreferedMode();

View File

@@ -78,6 +78,7 @@ EditorView::EditorView(SplitterOrView *parentSplitterOrView, QWidget *parent) :
connect(m_toolBar, SIGNAL(listSelectionActivated(int)), this, SLOT(listSelectionActivated(int))); connect(m_toolBar, SIGNAL(listSelectionActivated(int)), this, SLOT(listSelectionActivated(int)));
connect(m_toolBar, SIGNAL(horizontalSplitClicked()), this, SLOT(splitHorizontally())); connect(m_toolBar, SIGNAL(horizontalSplitClicked()), this, SLOT(splitHorizontally()));
connect(m_toolBar, SIGNAL(verticalSplitClicked()), this, SLOT(splitVertically())); 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, SIGNAL(closeSplitClicked()), this, SLOT(closeSplit()));
tl->addWidget(m_toolBar); tl->addWidget(m_toolBar);
} }
@@ -241,6 +242,10 @@ void EditorView::mousePressEvent(QMouseEvent *e)
if (e->button() != Qt::LeftButton) if (e->button() != Qt::LeftButton)
return; return;
setFocus(Qt::MouseFocusReason); setFocus(Qt::MouseFocusReason);
}
void EditorView::focusInEvent(QFocusEvent *)
{
ICore::editorManager()->setCurrentView(this); ICore::editorManager()->setCurrentView(this);
} }
@@ -313,6 +318,11 @@ void EditorView::splitVertically()
editorManager->updateActions(); editorManager->updateActions();
} }
void EditorView::splitNewWindow()
{
EditorManager::instance()->splitNewWindow(this);
}
void EditorView::closeSplit() void EditorView::closeSplit()
{ {
EditorManager *editorManager = EditorManager::instance(); EditorManager *editorManager = EditorManager::instance();
@@ -511,6 +521,8 @@ SplitterOrView::~SplitterOrView()
{ {
delete m_layout; delete m_layout;
m_layout = 0; m_layout = 0;
if (m_view)
EditorManager::instance()->emptyView(m_view);
delete m_view; delete m_view;
m_view = 0; m_view = 0;
delete m_splitter; delete m_splitter;
@@ -563,8 +575,10 @@ EditorView *SplitterOrView::takeView()
{ {
EditorView *oldView = m_view; EditorView *oldView = m_view;
if (m_view) { if (m_view) {
m_layout->removeWidget(m_view); // the focus update that is triggered by removing should already have 0 parent
// so we do that first
m_view->setParentSplitterOrView(0); m_view->setParentSplitterOrView(0);
m_layout->removeWidget(m_view);
} }
m_view = 0; m_view = 0;
return oldView; return oldView;

View File

@@ -105,12 +105,14 @@ public:
protected: protected:
void paintEvent(QPaintEvent *); void paintEvent(QPaintEvent *);
void mousePressEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e);
void focusInEvent(QFocusEvent *);
private slots: private slots:
void closeView(); void closeView();
void listSelectionActivated(int index); void listSelectionActivated(int index);
void splitHorizontally(); void splitHorizontally();
void splitVertically(); void splitVertically();
void splitNewWindow();
void closeSplit(); void closeSplit();
private: private:

View File

@@ -68,6 +68,7 @@ struct EditorToolBarPrivate {
QToolButton *m_splitButton; QToolButton *m_splitButton;
QAction *m_horizontalSplitAction; QAction *m_horizontalSplitAction;
QAction *m_verticalSplitAction; QAction *m_verticalSplitAction;
QAction *m_splitNewWindowAction;
QToolButton *m_closeSplitButton; QToolButton *m_closeSplitButton;
QWidget *m_activeToolBar; QWidget *m_activeToolBar;
@@ -86,6 +87,7 @@ EditorToolBarPrivate::EditorToolBarPrivate(QWidget *parent, EditorToolBar *q) :
m_splitButton(new QToolButton), m_splitButton(new QToolButton),
m_horizontalSplitAction(new QAction(QIcon(QLatin1String(Constants::ICON_SPLIT_HORIZONTAL)), EditorManager::tr("Split"), parent)), m_horizontalSplitAction(new QAction(QIcon(QLatin1String(Constants::ICON_SPLIT_HORIZONTAL)), EditorManager::tr("Split"), parent)),
m_verticalSplitAction(new QAction(QIcon(QLatin1String(Constants::ICON_SPLIT_VERTICAL)), EditorManager::tr("Split Side by Side"), parent)), m_verticalSplitAction(new QAction(QIcon(QLatin1String(Constants::ICON_SPLIT_VERTICAL)), EditorManager::tr("Split Side by Side"), parent)),
m_splitNewWindowAction(new QAction(EditorManager::tr("Split New Window"), parent)),
m_closeSplitButton(new QToolButton), m_closeSplitButton(new QToolButton),
m_activeToolBar(0), m_activeToolBar(0),
m_toolBarPlaceholder(new QWidget), m_toolBarPlaceholder(new QWidget),
@@ -140,6 +142,7 @@ EditorToolBar::EditorToolBar(QWidget *parent) :
if (Utils::HostOsInfo::isMacHost()) { if (Utils::HostOsInfo::isMacHost()) {
d->m_horizontalSplitAction->setIconVisibleInMenu(false); d->m_horizontalSplitAction->setIconVisibleInMenu(false);
d->m_verticalSplitAction->setIconVisibleInMenu(false); d->m_verticalSplitAction->setIconVisibleInMenu(false);
d->m_splitNewWindowAction->setIconVisibleInMenu(false);
} }
d->m_splitButton->setIcon(QIcon(QLatin1String(Constants::ICON_SPLIT_HORIZONTAL))); d->m_splitButton->setIcon(QIcon(QLatin1String(Constants::ICON_SPLIT_HORIZONTAL)));
@@ -149,6 +152,7 @@ EditorToolBar::EditorToolBar(QWidget *parent) :
QMenu *splitMenu = new QMenu(d->m_splitButton); QMenu *splitMenu = new QMenu(d->m_splitButton);
splitMenu->addAction(d->m_horizontalSplitAction); splitMenu->addAction(d->m_horizontalSplitAction);
splitMenu->addAction(d->m_verticalSplitAction); splitMenu->addAction(d->m_verticalSplitAction);
splitMenu->addAction(d->m_splitNewWindowAction);
d->m_splitButton->setMenu(splitMenu); d->m_splitButton->setMenu(splitMenu);
d->m_closeSplitButton->setAutoRaise(true); d->m_closeSplitButton->setAutoRaise(true);
@@ -179,6 +183,8 @@ EditorToolBar::EditorToolBar(QWidget *parent) :
this, SIGNAL(horizontalSplitClicked()), Qt::QueuedConnection); this, SIGNAL(horizontalSplitClicked()), Qt::QueuedConnection);
connect(d->m_verticalSplitAction, SIGNAL(triggered()), connect(d->m_verticalSplitAction, SIGNAL(triggered()),
this, SIGNAL(verticalSplitClicked()), Qt::QueuedConnection); this, SIGNAL(verticalSplitClicked()), Qt::QueuedConnection);
connect(d->m_splitNewWindowAction, SIGNAL(triggered()),
this, SIGNAL(splitNewWindowClicked()), Qt::QueuedConnection);
connect(d->m_closeSplitButton, SIGNAL(clicked()), connect(d->m_closeSplitButton, SIGNAL(clicked()),
this, SIGNAL(closeSplitClicked()), Qt::QueuedConnection); this, SIGNAL(closeSplitClicked()), Qt::QueuedConnection);

View File

@@ -89,6 +89,7 @@ signals:
void goForwardClicked(); void goForwardClicked();
void horizontalSplitClicked(); void horizontalSplitClicked();
void verticalSplitClicked(); void verticalSplitClicked();
void splitNewWindowClicked();
void closeSplitClicked(); void closeSplitClicked();
void listSelectionActivated(int row); void listSelectionActivated(int row);

View File

@@ -232,8 +232,7 @@ void GeneralSettings::variableHelpDialogCreator(const QString &helpText)
m_dialog->setText(helpText); m_dialog->setText(helpText);
m_dialog->show(); m_dialog->show();
m_dialog->raise(); ICore::raiseWindow(m_dialog);
m_dialog->activateWindow();
return; return;
} }
QMessageBox *mb = new QMessageBox(QMessageBox::Information, QMessageBox *mb = new QMessageBox(QMessageBox::Information,

View File

@@ -519,11 +519,29 @@ QWidget *ICore::mainWindow()
return m_mainwindow; return m_mainwindow;
} }
Utils::AppMainWindow *ICore::appMainWindow()
{
return m_mainwindow;
}
QStatusBar *ICore::statusBar() QStatusBar *ICore::statusBar()
{ {
return m_mainwindow->statusBar(); return m_mainwindow->statusBar();
} }
void ICore::raiseWindow(QWidget *widget)
{
if (!widget)
return;
QWidget *window = widget->window();
if (window == m_mainwindow) {
m_mainwindow->raiseWindow();
} else {
window->raise();
window->activateWindow();
}
}
void ICore::updateAdditionalContexts(const Context &remove, const Context &add) void ICore::updateAdditionalContexts(const Context &remove, const Context &add)
{ {
m_mainwindow->updateAdditionalContexts(remove, add); m_mainwindow->updateAdditionalContexts(remove, add);

View File

@@ -43,6 +43,9 @@ class QWidget;
template <class T> class QList; template <class T> class QList;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Utils {
class AppMainWindow;
}
namespace Core { namespace Core {
class IWizard; class IWizard;
@@ -111,7 +114,10 @@ public:
static QString userResourcePath(); static QString userResourcePath();
static QWidget *mainWindow(); static QWidget *mainWindow();
static Utils::AppMainWindow *appMainWindow();
static QStatusBar *statusBar(); static QStatusBar *statusBar();
/* Raises and activates the window for the widget. This contains workarounds for X11. */
static void raiseWindow(QWidget *widget);
static IContext *currentContextObject(); static IContext *currentContextObject();
// Adds and removes additional active contexts, these contexts are appended // Adds and removes additional active contexts, these contexts are appended

View File

@@ -449,8 +449,7 @@ void MainWindow::openDelayedFiles()
{ {
if (m_filesToOpenDelayed.isEmpty()) if (m_filesToOpenDelayed.isEmpty())
return; return;
activateWindow(); raiseWindow();
raise();
openFiles(m_filesToOpenDelayed, ICore::SwitchMode); openFiles(m_filesToOpenDelayed, ICore::SwitchMode);
m_filesToOpenDelayed.clear(); m_filesToOpenDelayed.clear();
} }

View File

@@ -270,10 +270,10 @@ DebuggerMainWindow::~DebuggerMainWindow()
void DebuggerMainWindow::setCurrentEngine(DebuggerEngine *engine) void DebuggerMainWindow::setCurrentEngine(DebuggerEngine *engine)
{ {
if (d->m_engine) if (d->m_engine)
disconnect(d->m_engine, SIGNAL(raiseWindow()), this, SLOT(raiseDebuggerWindow())); disconnect(d->m_engine, SIGNAL(raiseWindow()), ICore::appMainWindow(), SLOT(raiseWindow()));
d->m_engine = engine; d->m_engine = engine;
if (d->m_engine) if (d->m_engine)
connect(d->m_engine, SIGNAL(raiseWindow()), this, SLOT(raiseDebuggerWindow())); connect(d->m_engine, SIGNAL(raiseWindow()), ICore::appMainWindow(), SLOT(raiseWindow()));
} }
DebuggerLanguages DebuggerMainWindow::activeDebugLanguages() const DebuggerLanguages DebuggerMainWindow::activeDebugLanguages() const
@@ -571,13 +571,6 @@ void DebuggerMainWindow::writeSettings() const
settings->endGroup(); settings->endGroup();
} }
void DebuggerMainWindow::raiseDebuggerWindow()
{
Utils::AppMainWindow *appMainWindow = qobject_cast<Utils::AppMainWindow*>(ICore::mainWindow());
QTC_ASSERT(appMainWindow, return);
appMainWindow->raiseWindow();
}
void DebuggerMainWindow::readSettings() void DebuggerMainWindow::readSettings()
{ {
QSettings *settings = ICore::settings(); QSettings *settings = ICore::settings();

View File

@@ -95,9 +95,6 @@ public:
void readSettings(); void readSettings();
void writeSettings() const; void writeSettings() const;
private slots:
void raiseDebuggerWindow();
private: private:
friend class Internal::DebuggerMainWindowPrivate; friend class Internal::DebuggerMainWindowPrivate;
Internal::DebuggerMainWindowPrivate *d; Internal::DebuggerMainWindowPrivate *d;

View File

@@ -193,7 +193,7 @@ bool ExternalHelpWindow::eventFilter(QObject *obj, QEvent *event)
QKeyEvent *keyEvent = static_cast<QKeyEvent*> (event); QKeyEvent *keyEvent = static_cast<QKeyEvent*> (event);
switch (keyEvent->key()) { switch (keyEvent->key()) {
case Qt::Key_Escape: case Qt::Key_Escape:
Core::ICore::mainWindow()->activateWindow(); Core::ICore::raiseWindow(Core::ICore::mainWindow());
default: default:
break; break;
} }

View File

@@ -729,9 +729,10 @@ void HelpPlugin::showExternalWindow()
doSetupIfNeeded(); doSetupIfNeeded();
m_externalWindow->show(); m_externalWindow->show();
connectExternalHelpWindow(); connectExternalHelpWindow();
m_externalWindow->activateWindow();
if (firstTime) if (firstTime)
Core::ICore::mainWindow()->activateWindow(); Core::ICore::raiseWindow(Core::ICore::mainWindow());
else
Core::ICore::raiseWindow(m_externalWindow);
} }
void HelpPlugin::modeChanged(Core::IMode *mode, Core::IMode *old) void HelpPlugin::modeChanged(Core::IMode *mode, Core::IMode *old)

View File

@@ -38,6 +38,7 @@
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/fileiconprovider.h> #include <coreplugin/fileiconprovider.h>
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
#include <utils/appmainwindow.h>
#include <utils/filterlineedit.h> #include <utils/filterlineedit.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -574,6 +575,7 @@ void LocatorWidget::show(const QString &text, int selectionStart, int selectionL
m_fileLineEdit->setFocus(); m_fileLineEdit->setFocus();
else else
showPopupNow(); showPopupNow();
ICore::raiseWindow(ICore::mainWindow());
if (selectionStart >= 0) { if (selectionStart >= 0) {
m_fileLineEdit->setSelection(selectionStart, selectionLength); m_fileLineEdit->setSelection(selectionStart, selectionLength);