diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp index 73b035eda34..dd70c122beb 100644 --- a/src/plugins/coreplugin/documentmanager.cpp +++ b/src/plugins/coreplugin/documentmanager.cpp @@ -118,14 +118,6 @@ static bool saveModifiedFilesHelper(const QList &documents, namespace Internal { -struct OpenWithEntry -{ - OpenWithEntry() : editorFactory(0), externalEditor(0) {} - IEditorFactory *editorFactory; - IExternalEditor *externalEditor; - QString fileName; -}; - struct FileStateItem { QDateTime modified; @@ -210,8 +202,6 @@ DocumentManagerPrivate::DocumentManagerPrivate() : } // namespace Internal } // namespace Core -Q_DECLARE_METATYPE(Core::Internal::OpenWithEntry) - namespace Core { using namespace Internal; @@ -1385,6 +1375,44 @@ void DocumentManager::notifyFilesChangedInternally(const QStringList &files) emit m_instance->filesChangedInternally(files); } +static void openEditorWith(const QString &fileName, Core::Id editorId) +{ + // close any open editors that have this file open + // remember the views to open new editors in there + QList views; + QList editorsOpenForFile + = DocumentModel::editorsForFilePath(fileName); + foreach (IEditor *openEditor, editorsOpenForFile) { + EditorView *view = EditorManagerPrivate::viewForEditor(openEditor); + if (view && view->currentEditor() == openEditor) // visible + views.append(view); + } + if (!EditorManager::closeEditors(editorsOpenForFile)) // don't open if cancel was pressed + return; + + if (views.isEmpty()) { + EditorManager::openEditor(fileName, editorId); + } else { + if (EditorView *currentView = EditorManagerPrivate::currentEditorView()) { + if (views.removeOne(currentView)) + views.prepend(currentView); // open editor in current view first + } + EditorManager::OpenEditorFlags flags; + foreach (EditorView *view, views) { + IEditor *editor = EditorManagerPrivate::openEditor(view, fileName, editorId, flags); + // Do not change the current editor after opening the first one. That + // * prevents multiple updates of focus etc which are not necessary + // * lets us control which editor is made current by putting the current editor view + // to the front (if that was in the list in the first place) + flags |= EditorManager::DoNotChangeCurrentEditor; + // do not try to open more editors if this one failed, or editor type does not + // support duplication anyhow + if (!editor || !editor->duplicateSupported()) + break; + } + } +} + void DocumentManager::populateOpenWithMenu(QMenu *menu, const QString &fileName) { typedef QList EditorFactoryList; @@ -1403,75 +1431,32 @@ void DocumentManager::populateOpenWithMenu(QMenu *menu, const QString &fileName) if (anyMatches) { // Add all suitable editors foreach (IEditorFactory *editorFactory, factories) { + Core::Id editorId = editorFactory->id(); // Add action to open with this very editor factory QString const actionTitle = editorFactory->displayName(); - QAction * const action = menu->addAction(actionTitle); - OpenWithEntry entry; - entry.editorFactory = editorFactory; - entry.fileName = fileName; - action->setData(qVariantFromValue(entry)); + QAction *action = menu->addAction(actionTitle); + // Below we need QueuedConnection because otherwise, if a qrc file + // is inside of a qrc file itself, and the qrc editor opens the Open with menu, + // crashes happen, because the editor instance is deleted by openEditorWith + // while the menu is still being processed. + connect(action, &QAction::triggered, EditorManager::instance(), + [fileName, editorId]() { + openEditorWith(fileName, editorId); + }, Qt::QueuedConnection); } // Add all suitable external editors foreach (IExternalEditor *externalEditor, externalEditors) { - QAction * const action = menu->addAction(externalEditor->displayName()); - OpenWithEntry entry; - entry.externalEditor = externalEditor; - entry.fileName = fileName; - action->setData(qVariantFromValue(entry)); + QAction *action = menu->addAction(externalEditor->displayName()); + Core::Id editorId = externalEditor->id(); + connect(action, &QAction::triggered, [fileName, editorId]() { + EditorManager::openExternalEditor(fileName, editorId); + }); } } } menu->setEnabled(anyMatches); } -void DocumentManager::executeOpenWithMenuAction(QAction *action) -{ - QTC_ASSERT(action, return); - const QVariant data = action->data(); - OpenWithEntry entry = qvariant_cast(data); - if (entry.editorFactory) { - // close any open editors that have this file open - // remember the views to open new editors in there - QList views; - QList editorsOpenForFile - = DocumentModel::editorsForFilePath(entry.fileName); - foreach (IEditor *openEditor, editorsOpenForFile) { - EditorView *view = EditorManagerPrivate::viewForEditor(openEditor); - if (view && view->currentEditor() == openEditor) // visible - views.append(view); - } - if (!EditorManager::closeEditors(editorsOpenForFile)) // don't open if cancel was pressed - return; - - if (views.isEmpty()) { - EditorManager::openEditor(entry.fileName, entry.editorFactory->id()); - } else { - if (EditorView *currentView = EditorManagerPrivate::currentEditorView()) { - if (views.removeOne(currentView)) - views.prepend(currentView); // open editor in current view first - } - EditorManager::OpenEditorFlags flags; - foreach (EditorView *view, views) { - IEditor *editor = - EditorManagerPrivate::openEditor(view, entry.fileName, - entry.editorFactory->id(), flags); - // Do not change the current editor after opening the first one. That - // * prevents multiple updates of focus etc which are not necessary - // * lets us control which editor is made current by putting the current editor view - // to the front (if that was in the list in the first place - flags |= EditorManager::DoNotChangeCurrentEditor; - // do not try to open more editors if this one failed, or editor type does not - // support duplication anyhow - if (!editor || !editor->duplicateSupported()) - break; - } - } - return; - } - if (entry.externalEditor) - EditorManager::openExternalEditor(entry.fileName, entry.externalEditor->id()); -} - bool DocumentManager::eventFilter(QObject *obj, QEvent *e) { if (obj == qApp && e->type() == QEvent::ApplicationActivate) { diff --git a/src/plugins/coreplugin/documentmanager.h b/src/plugins/coreplugin/documentmanager.h index 010489b6207..bb49d2b51d2 100644 --- a/src/plugins/coreplugin/documentmanager.h +++ b/src/plugins/coreplugin/documentmanager.h @@ -143,9 +143,6 @@ public: lead to any editors to reload or any other editor manager actions. */ static void notifyFilesChangedInternally(const QStringList &files); -public slots: - static void executeOpenWithMenuAction(QAction *action); - signals: /* Used to notify e.g. the code model to update the given files. Does *not* lead to any editors to reload or any other editor manager actions. */ diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index e2c0e1b9bbc..01fedf0d6fd 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -2085,8 +2085,6 @@ void EditorManager::addNativeDirAndOpenWithActions(QMenu *contextMenu, DocumentM contextMenu->addAction(d->m_openTerminalAction); contextMenu->addAction(d->m_findInDirectoryAction); QMenu *openWith = contextMenu->addMenu(tr("Open With")); - connect(openWith, SIGNAL(triggered(QAction*)), - DocumentManager::instance(), SLOT(executeOpenWithMenuAction(QAction*))); openWith->setEnabled(enabled); if (enabled) DocumentManager::populateOpenWithMenu(openWith, entry->fileName().toString()); diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp index 6a51aa65382..6b2a85b440a 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.cpp +++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp @@ -403,7 +403,6 @@ void FolderNavigationWidget::contextMenuEvent(QContextMenuEvent *ev) TextEditor::FindInFiles::findOnFileSystem(m_fileSystemModel->filePath(current)); return; } - Core::DocumentManager::executeOpenWithMenuAction(action); } void FolderNavigationWidget::setHiddenFilesFilter(bool filter) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 36dc37dac19..f993aff06f0 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -726,9 +726,6 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er dd->m_openWithMenu = openWith->menu(); dd->m_openWithMenu->setTitle(tr("Open With")); - connect(dd->m_openWithMenu, &QMenu::triggered, - DocumentManager::instance(), &DocumentManager::executeOpenWithMenuAction); - // // Separators // diff --git a/src/plugins/resourceeditor/resourceeditorplugin.cpp b/src/plugins/resourceeditor/resourceeditorplugin.cpp index 68937543f15..22de88bc9fb 100644 --- a/src/plugins/resourceeditor/resourceeditorplugin.cpp +++ b/src/plugins/resourceeditor/resourceeditorplugin.cpp @@ -190,8 +190,6 @@ bool ResourceEditorPlugin::initialize(const QStringList &arguments, QString *err folderContextMenu->menu()->insertMenu( folderContextMenu->insertLocation(ProjectExplorer::Constants::G_FOLDER_FILES), m_openWithMenu); - connect(m_openWithMenu, &QMenu::triggered, - Core::DocumentManager::instance(), &Core::DocumentManager::executeOpenWithMenuAction); m_copyPath = new Utils::ParameterAction(QString(), tr("Copy path \"%1\""), Utils::ParameterAction::AlwaysEnabled, this); command = Core::ActionManager::registerAction(m_copyPath, Constants::C_COPY_PATH, projectTreeContext); diff --git a/src/plugins/resourceeditor/resourceeditorw.cpp b/src/plugins/resourceeditor/resourceeditorw.cpp index 247914a6eae..e53df74cccd 100644 --- a/src/plugins/resourceeditor/resourceeditorw.cpp +++ b/src/plugins/resourceeditor/resourceeditorw.cpp @@ -103,14 +103,6 @@ ResourceEditorW::ResourceEditorW(const Core::Context &context, m_renameAction = m_contextMenu->addAction(tr("Rename File..."), this, SLOT(renameCurrentFile())); m_copyFileNameAction = m_contextMenu->addAction(tr("Copy Resource Path to Clipboard"), this, SLOT(copyCurrentResourcePath())); - // Below we need QueuedConnection because otherwise, if this qrc file - // is inside of the qrc file, crashes happen when using "Open With" on it. - // (That is because this editor instance is deleted in executeOpenWithMenuAction - // in that case.) - connect(m_openWithMenu, SIGNAL(triggered(QAction*)), - Core::DocumentManager::instance(), SLOT(executeOpenWithMenuAction(QAction*)), - Qt::QueuedConnection); - connect(m_resourceEditor, SIGNAL(dirtyChanged(bool)), m_resourceDocument, SLOT(dirtyChanged(bool))); connect(m_resourceEditor, SIGNAL(undoStackChanged(bool,bool)), this, SLOT(onUndoStackChanged(bool,bool)));