Simplify Open with... menu handling

In the light of lambdas we can get rid of some complexity.

Change-Id: Id28b52c42d7c34526c93785723387b6c44c0cd52
Reviewed-by: Daniel Teske <daniel.teske@theqtcompany.com>
Reviewed-by: Nikita Baryshnikov <nib952051@gmail.com>
Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
This commit is contained in:
Eike Ziller
2015-05-19 15:15:36 +02:00
parent 832aa7851c
commit 2e4a86a87c
7 changed files with 53 additions and 87 deletions

View File

@@ -118,14 +118,6 @@ static bool saveModifiedFilesHelper(const QList<IDocument *> &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<EditorView *> views;
QList<IEditor *> 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<IEditorFactory*> 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<OpenWithEntry>(data);
if (entry.editorFactory) {
// close any open editors that have this file open
// remember the views to open new editors in there
QList<EditorView *> views;
QList<IEditor *> 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) {