diff --git a/src/plugins/coreplugin/dialogs/filepropertiesdialog.cpp b/src/plugins/coreplugin/dialogs/filepropertiesdialog.cpp index e2fc4f1c6a5..9f486a5e26b 100644 --- a/src/plugins/coreplugin/dialogs/filepropertiesdialog.cpp +++ b/src/plugins/coreplugin/dialogs/filepropertiesdialog.cpp @@ -73,7 +73,7 @@ void FilePropertiesDialog::refresh() const Utils::MimeType mt = Utils::mimeTypeForFile(fileInfo); m_ui->mimeType->setText(mt.isValid() ? mt.name() : tr("Undefined")); - const Core::EditorManager::EditorFactoryList factories = Core::EditorManager::editorFactories(m_fileName); + const Core::EditorFactoryList factories = Core::IEditorFactory::editorFactories(m_fileName); m_ui->defaultEditor->setText(!factories.isEmpty() ? factories.at(0)->displayName() : tr("Undefined")); m_ui->owner->setText(fileInfo.owner()); diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 5c46d683bc0..c6792c5150f 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -600,7 +600,7 @@ IEditor *EditorManagerPrivate::openEditor(EditorView *view, const QString &fileN realFn = fn; } - EditorManager::EditorFactoryList factories = EditorManagerPrivate::findFactories(Id(), fn); + EditorFactoryList factories = EditorManagerPrivate::findFactories(Id(), fn); if (factories.isEmpty()) { Utils::MimeType mimeType = Utils::mimeTypeForFile(fn); QMessageBox msgbox(QMessageBox::Critical, EditorManager::tr("File Error"), @@ -944,7 +944,7 @@ Id EditorManagerPrivate::getOpenWithEditorId(const QString &fileName, bool *isEx QStringList allEditorDisplayNames; QList externalEditorIds; // Built-in - const EditorManager::EditorFactoryList editors = EditorManager::editorFactories(mt, false); + const EditorFactoryList editors = IEditorFactory::editorFactories(mt, false); const int size = editors.size(); allEditorDisplayNames.reserve(size); for (int i = 0; i < size; i++) { @@ -952,7 +952,7 @@ Id EditorManagerPrivate::getOpenWithEditorId(const QString &fileName, bool *isEx allEditorDisplayNames.push_back(editors.at(i)->displayName()); } // External editors - const EditorManager::ExternalEditorList exEditors = EditorManager::externalEditors(mt, false); + const ExternalEditorList exEditors = IExternalEditor::externalEditors(mt, false); const int esize = exEditors.size(); for (int i = 0; i < esize; i++) { externalEditorIds.push_back(exEditors.at(i)->id()); @@ -1123,14 +1123,14 @@ void EditorManagerPrivate::setBigFileSizeLimit(int limitInMB) d->m_bigFileSizeLimitInMB = limitInMB; } -EditorManager::EditorFactoryList EditorManagerPrivate::findFactories(Id editorId, const QString &fileName) +EditorFactoryList EditorManagerPrivate::findFactories(Id editorId, const QString &fileName) { if (debugEditorManager) qDebug() << Q_FUNC_INFO << editorId.name() << fileName; - EditorManager::EditorFactoryList factories; + EditorFactoryList factories; if (!editorId.isValid()) { - factories = EditorManager::editorFactories(fileName, false); + factories = IEditorFactory::editorFactories(fileName, false); } else { // Find by editor id IEditorFactory *factory = Utils::findOrDefault(IEditorFactory::allEditorFactories(), @@ -2474,8 +2474,8 @@ void EditorManager::populateOpenWithMenu(QMenu *menu, const QString &fileName) const Utils::MimeType mt = Utils::mimeTypeForFile(fileName); if (mt.isValid()) { - const EditorFactoryList factories = editorFactories(mt, false); - const ExternalEditorList extEditors = externalEditors(mt, false); + const EditorFactoryList factories = IEditorFactory::editorFactories(mt, false); + const ExternalEditorList extEditors = IExternalEditor::externalEditors(mt, false); anyMatches = !factories.empty() || !extEditors.empty(); if (anyMatches) { // Add all suitable editors @@ -2576,96 +2576,6 @@ IEditor *EditorManager::activateEditorForDocument(IDocument *document, OpenEdito return EditorManagerPrivate::activateEditorForDocument(EditorManagerPrivate::currentEditorView(), document, flags); } -/* For something that has a 'QStringList mimeTypes' (IEditorFactory - * or IExternalEditor), find the one best matching the mimetype passed in. - * Recurse over the parent classes of the mimetype to find them. */ -template -static void mimeTypeFactoryLookup(const Utils::MimeType &mimeType, - const QList &allFactories, - bool firstMatchOnly, - QList *list) -{ - QSet matches; - // search breadth-first through parent hierarchy, e.g. for hierarchy - // * application/x-ruby - // * application/x-executable - // * application/octet-stream - // * text/plain - QList queue; - QSet seen; - queue.append(mimeType); - seen.insert(mimeType.name()); - while (!queue.isEmpty()) { - Utils::MimeType mt = queue.takeFirst(); - // check for matching factories - foreach (EditorFactoryLike *factory, allFactories) { - if (!matches.contains(factory)) { - foreach (const QString &mimeName, factory->mimeTypes()) { - if (mt.matchesName(mimeName)) { - list->append(factory); - if (firstMatchOnly) - return; - matches.insert(factory); - } - } - } - } - // add parent mime types - QStringList parentNames = mt.parentMimeTypes(); - foreach (const QString &parentName, parentNames) { - const Utils::MimeType parent = Utils::mimeTypeForName(parentName); - if (parent.isValid()) { - int seenSize = seen.size(); - seen.insert(parent.name()); - if (seen.size() != seenSize) // not seen before, so add - queue.append(parent); - } - } - } -} - -EditorManager::EditorFactoryList - EditorManager::editorFactories(const Utils::MimeType &mimeType, bool bestMatchOnly) -{ - EditorFactoryList rc; - const EditorFactoryList allFactories = IEditorFactory::allEditorFactories(); - mimeTypeFactoryLookup(mimeType, allFactories, bestMatchOnly, &rc); - if (debugEditorManager) - qDebug() << Q_FUNC_INFO << mimeType.name() << " returns " << rc; - return rc; -} - -EditorManager::EditorFactoryList - EditorManager::editorFactories(const QString &fileName, bool bestMatchOnly) -{ - const QFileInfo fileInfo(fileName); - // Find by mime type - Utils::MimeType mimeType = Utils::mimeTypeForFile(fileInfo); - if (!mimeType.isValid()) { - qWarning("%s unable to determine mime type of %s. Falling back to text/plain", - Q_FUNC_INFO, fileName.toUtf8().constData()); - mimeType = Utils::mimeTypeForName("text/plain"); - } - // open text files > 48 MB in binary editor - if (fileInfo.size() > EditorManager::maxTextFileSize() - && mimeType.name().startsWith("text")) { - mimeType = Utils::mimeTypeForName("application/octet-stream"); - } - - return EditorManager::editorFactories(mimeType, bestMatchOnly); -} - -EditorManager::ExternalEditorList - EditorManager::externalEditors(const Utils::MimeType &mimeType, bool bestMatchOnly) -{ - ExternalEditorList rc; - const ExternalEditorList allEditors = IExternalEditor::allExternalEditors(); - mimeTypeFactoryLookup(mimeType, allEditors, bestMatchOnly, &rc); - if (debugEditorManager) - qDebug() << Q_FUNC_INFO << mimeType.name() << " returns " << rc; - return rc; -} - IEditor *EditorManager::openEditor(const QString &fileName, Id editorId, OpenEditorFlags flags, bool *newEditor) { diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h index ab5a217e96a..0da42f8be18 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -75,8 +75,6 @@ class CORE_EXPORT EditorManager : public QObject Q_OBJECT public: - typedef QList EditorFactoryList; - typedef QList ExternalEditorList; typedef std::function WindowTitleHandler; static EditorManager *instance(); @@ -151,10 +149,6 @@ public: const std::function &function = nullptr); static void hideEditorStatusBar(const QString &id); - static EditorFactoryList editorFactories(const Utils::MimeType &mimeType, bool bestMatchOnly = true); - static EditorFactoryList editorFactories(const QString &fileName, bool bestMatchOnly = true); - static ExternalEditorList externalEditors(const Utils::MimeType &mimeType, bool bestMatchOnly = true); - static bool isAutoSaveFile(const QString &fileName); static QTextCodec *defaultTextCodec(); diff --git a/src/plugins/coreplugin/editormanager/editormanager_p.h b/src/plugins/coreplugin/editormanager/editormanager_p.h index 07c81e9ca37..740c8d5365d 100644 --- a/src/plugins/coreplugin/editormanager/editormanager_p.h +++ b/src/plugins/coreplugin/editormanager/editormanager_p.h @@ -30,8 +30,10 @@ #include "editormanager.h" #include "editorview.h" #include "ieditor.h" +#include "ieditorfactory.h" #include +#include #include #include @@ -185,7 +187,7 @@ private: static OpenEditorsWindow *windowPopup(); static void showPopupOrSelectDocument(); - static EditorManager::EditorFactoryList findFactories(Id editorId, const QString &fileName); + static EditorFactoryList findFactories(Id editorId, const QString &fileName); static IEditor *createEditor(IEditorFactory *factory, const QString &fileName); static void addEditor(IEditor *editor); static void removeEditor(IEditor *editor, bool removeSusependedEntry); @@ -276,5 +278,53 @@ private: QList> m_closeEditorListeners; }; +/* For something that has a 'QStringList mimeTypes' (IEditorFactory + * or IExternalEditor), find the one best matching the mimetype passed in. + * Recurse over the parent classes of the mimetype to find them. */ +template +static void mimeTypeFactoryLookup(const Utils::MimeType &mimeType, + const QList &allFactories, + bool firstMatchOnly, + QList *list) +{ + QSet matches; + // search breadth-first through parent hierarchy, e.g. for hierarchy + // * application/x-ruby + // * application/x-executable + // * application/octet-stream + // * text/plain + QList queue; + QSet seen; + queue.append(mimeType); + seen.insert(mimeType.name()); + while (!queue.isEmpty()) { + Utils::MimeType mt = queue.takeFirst(); + // check for matching factories + foreach (EditorFactoryLike *factory, allFactories) { + if (!matches.contains(factory)) { + foreach (const QString &mimeName, factory->mimeTypes()) { + if (mt.matchesName(mimeName)) { + list->append(factory); + if (firstMatchOnly) + return; + matches.insert(factory); + } + } + } + } + // add parent mime types + QStringList parentNames = mt.parentMimeTypes(); + foreach (const QString &parentName, parentNames) { + const Utils::MimeType parent = Utils::mimeTypeForName(parentName); + if (parent.isValid()) { + int seenSize = seen.size(); + seen.insert(parent.name()); + if (seen.size() != seenSize) // not seen before, so add + queue.append(parent); + } + } + } +} + } // Internal } // Core diff --git a/src/plugins/coreplugin/editormanager/ieditorfactory.cpp b/src/plugins/coreplugin/editormanager/ieditorfactory.cpp index b32b6036bc8..3526ffb458a 100644 --- a/src/plugins/coreplugin/editormanager/ieditorfactory.cpp +++ b/src/plugins/coreplugin/editormanager/ieditorfactory.cpp @@ -24,9 +24,14 @@ ****************************************************************************/ #include "ieditorfactory.h" +#include "editormanager.h" +#include "editormanager_p.h" +#include #include +#include + namespace Core { static QList g_editorFactories; @@ -42,9 +47,37 @@ IEditorFactory::~IEditorFactory() g_editorFactories.removeOne(this); } -const QList IEditorFactory::allEditorFactories() +const EditorFactoryList IEditorFactory::allEditorFactories() { return g_editorFactories; } +const EditorFactoryList IEditorFactory::editorFactories(const Utils::MimeType &mimeType, bool bestMatchOnly) +{ + EditorFactoryList rc; + const EditorFactoryList allFactories = IEditorFactory::allEditorFactories(); + Internal::mimeTypeFactoryLookup(mimeType, allFactories, bestMatchOnly, &rc); + return rc; +} + +const EditorFactoryList IEditorFactory::editorFactories(const QString &fileName, bool bestMatchOnly) +{ + const QFileInfo fileInfo(fileName); + // Find by mime type + Utils::MimeType mimeType = Utils::mimeTypeForFile(fileInfo); + if (!mimeType.isValid()) { + qWarning("%s unable to determine mime type of %s. Falling back to text/plain", + Q_FUNC_INFO, fileName.toUtf8().constData()); + mimeType = Utils::mimeTypeForName("text/plain"); + } + // open text files > 48 MB in binary editor + if (fileInfo.size() > EditorManager::maxTextFileSize() + && mimeType.name().startsWith("text")) { + mimeType = Utils::mimeTypeForName("application/octet-stream"); + } + + return IEditorFactory::editorFactories(mimeType, bestMatchOnly); +} + + } // Core diff --git a/src/plugins/coreplugin/editormanager/ieditorfactory.h b/src/plugins/coreplugin/editormanager/ieditorfactory.h index d7600adf71d..1ea6121705d 100644 --- a/src/plugins/coreplugin/editormanager/ieditorfactory.h +++ b/src/plugins/coreplugin/editormanager/ieditorfactory.h @@ -28,12 +28,17 @@ #include #include +#include + #include #include namespace Core { class IEditor; +class IEditorFactory; + +using EditorFactoryList = QList; class CORE_EXPORT IEditorFactory : public QObject { @@ -43,7 +48,11 @@ public: IEditorFactory(QObject *parent = nullptr); ~IEditorFactory() override; - static const QList allEditorFactories(); + static const EditorFactoryList allEditorFactories(); + static const EditorFactoryList editorFactories(const Utils::MimeType &mimeType, + bool bestMatchOnly = true); + static const EditorFactoryList editorFactories(const QString &fileName, + bool bestMatchOnly = true); QString displayName() const { return m_displayName; } void setDisplayName(const QString &displayName) { m_displayName = displayName; } diff --git a/src/plugins/coreplugin/editormanager/iexternaleditor.cpp b/src/plugins/coreplugin/editormanager/iexternaleditor.cpp index 246003162f8..a802f913c98 100644 --- a/src/plugins/coreplugin/editormanager/iexternaleditor.cpp +++ b/src/plugins/coreplugin/editormanager/iexternaleditor.cpp @@ -25,6 +25,8 @@ #include "iexternaleditor.h" +#include "editormanager_p.h" + namespace Core { /*! @@ -66,9 +68,18 @@ IExternalEditor::~IExternalEditor() g_externalEditors.removeOne(this); } -const QList IExternalEditor::allExternalEditors() +const ExternalEditorList IExternalEditor::allExternalEditors() { return g_externalEditors; } +const ExternalEditorList IExternalEditor::externalEditors(const Utils::MimeType &mimeType, + bool bestMatchOnly) +{ + ExternalEditorList rc; + const ExternalEditorList allEditors = IExternalEditor::allExternalEditors(); + Internal::mimeTypeFactoryLookup(mimeType, allEditors, bestMatchOnly, &rc); + return rc; +} + } // Core diff --git a/src/plugins/coreplugin/editormanager/iexternaleditor.h b/src/plugins/coreplugin/editormanager/iexternaleditor.h index 712af48eb82..d593a4a45a4 100644 --- a/src/plugins/coreplugin/editormanager/iexternaleditor.h +++ b/src/plugins/coreplugin/editormanager/iexternaleditor.h @@ -27,11 +27,16 @@ #include +#include + #include namespace Core { class Id; +class IExternalEditor; + +using ExternalEditorList = QList; class CORE_EXPORT IExternalEditor : public QObject { @@ -41,7 +46,9 @@ public: explicit IExternalEditor(QObject *parent = nullptr); ~IExternalEditor() override; - static const QList allExternalEditors(); + static const ExternalEditorList allExternalEditors(); + static const ExternalEditorList externalEditors(const Utils::MimeType &mimeType, + bool bestMatchOnly = true); virtual QStringList mimeTypes() const = 0; virtual Id id() const = 0; diff --git a/src/plugins/coreplugin/mimetypesettings.cpp b/src/plugins/coreplugin/mimetypesettings.cpp index 2e4272ab876..7e03b85c014 100644 --- a/src/plugins/coreplugin/mimetypesettings.cpp +++ b/src/plugins/coreplugin/mimetypesettings.cpp @@ -144,13 +144,12 @@ void MimeTypeSettingsModel::load() foreach (const Utils::MimeType &mimeType, m_mimeTypes) { QString value; - const QList factories = - EditorManager::editorFactories(mimeType); + const QList factories = IEditorFactory::editorFactories(mimeType); if (!factories.isEmpty()) { value = factories.front()->displayName(); } else { - const QList externalEditors = - EditorManager::externalEditors(mimeType); + const QList externalEditors = IExternalEditor::externalEditors( + mimeType); if (!externalEditors.isEmpty()) value = externalEditors.front()->displayName(); else