forked from qt-creator/qt-creator
Allow changing the default editor for mime types
Double-clicking or clicking on the selected item shows a combo box with all editor types that can handle that mime type. Modified handlers are shown in italic, and a new button resets all handlers to the default. Change-Id: I4083c31e3867eb2a2a47adc85e4bd20f3d57be9a Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -224,7 +224,8 @@ HEADERS += corejsextensions.h \
|
|||||||
coreicons.h \
|
coreicons.h \
|
||||||
editormanager/documentmodel_p.h \
|
editormanager/documentmodel_p.h \
|
||||||
diffservice.h \
|
diffservice.h \
|
||||||
menubarfilter.h
|
menubarfilter.h \
|
||||||
|
editormanager/ieditorfactory_p.h
|
||||||
|
|
||||||
FORMS += dialogs/newdialog.ui \
|
FORMS += dialogs/newdialog.ui \
|
||||||
dialogs/saveitemsdialog.ui \
|
dialogs/saveitemsdialog.ui \
|
||||||
|
@@ -229,7 +229,7 @@ Project {
|
|||||||
"editorview.cpp", "editorview.h",
|
"editorview.cpp", "editorview.h",
|
||||||
"editorwindow.cpp", "editorwindow.h",
|
"editorwindow.cpp", "editorwindow.h",
|
||||||
"ieditor.cpp", "ieditor.h",
|
"ieditor.cpp", "ieditor.h",
|
||||||
"ieditorfactory.cpp", "ieditorfactory.h",
|
"ieditorfactory.cpp", "ieditorfactory.h", "ieditorfactory_p.h",
|
||||||
"iexternaleditor.cpp", "iexternaleditor.h",
|
"iexternaleditor.cpp", "iexternaleditor.h",
|
||||||
"openeditorsview.cpp", "openeditorsview.h",
|
"openeditorsview.cpp", "openeditorsview.h",
|
||||||
"openeditorswindow.cpp", "openeditorswindow.h",
|
"openeditorswindow.cpp", "openeditorswindow.h",
|
||||||
|
@@ -72,7 +72,7 @@ void FilePropertiesDialog::refresh()
|
|||||||
|
|
||||||
m_ui->mimeType->setText(Utils::mimeTypeForFile(fileInfo).name());
|
m_ui->mimeType->setText(Utils::mimeTypeForFile(fileInfo).name());
|
||||||
|
|
||||||
const Core::EditorFactoryList factories = Core::IEditorFactory::editorFactories(m_fileName);
|
const Core::EditorFactoryList factories = Core::IEditorFactory::preferredEditorFactories(m_fileName);
|
||||||
m_ui->defaultEditor->setText(!factories.isEmpty() ? factories.at(0)->displayName() : tr("Undefined"));
|
m_ui->defaultEditor->setText(!factories.isEmpty() ? factories.at(0)->displayName() : tr("Undefined"));
|
||||||
|
|
||||||
m_ui->owner->setText(fileInfo.owner());
|
m_ui->owner->setText(fileInfo.owner());
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
#include <coreplugin/diffservice.h>
|
#include <coreplugin/diffservice.h>
|
||||||
#include <coreplugin/documentmanager.h>
|
#include <coreplugin/documentmanager.h>
|
||||||
#include <coreplugin/editormanager/ieditorfactory.h>
|
#include <coreplugin/editormanager/ieditorfactory.h>
|
||||||
|
#include <coreplugin/editormanager/ieditorfactory_p.h>
|
||||||
#include <coreplugin/editormanager/iexternaleditor.h>
|
#include <coreplugin/editormanager/iexternaleditor.h>
|
||||||
#include <coreplugin/editortoolbar.h>
|
#include <coreplugin/editortoolbar.h>
|
||||||
#include <coreplugin/fileutils.h>
|
#include <coreplugin/fileutils.h>
|
||||||
@@ -121,6 +122,7 @@ static const char autoSuspendMinDocumentCountKey[] = "EditorManager/AutoSuspendM
|
|||||||
static const char warnBeforeOpeningBigTextFilesKey[] = "EditorManager/WarnBeforeOpeningBigTextFiles";
|
static const char warnBeforeOpeningBigTextFilesKey[] = "EditorManager/WarnBeforeOpeningBigTextFiles";
|
||||||
static const char bigTextFileSizeLimitKey[] = "EditorManager/BigTextFileSizeLimitInMB";
|
static const char bigTextFileSizeLimitKey[] = "EditorManager/BigTextFileSizeLimitInMB";
|
||||||
static const char fileSystemCaseSensitivityKey[] = "Core/FileSystemCaseSensitivity";
|
static const char fileSystemCaseSensitivityKey[] = "Core/FileSystemCaseSensitivity";
|
||||||
|
static const char preferredEditorFactoriesKey[] = "EditorManager/PreferredEditorFactories";
|
||||||
|
|
||||||
static const char scratchBufferKey[] = "_q_emScratchBuffer";
|
static const char scratchBufferKey[] = "_q_emScratchBuffer";
|
||||||
|
|
||||||
@@ -936,12 +938,11 @@ void EditorManagerPrivate::showPopupOrSelectDocument()
|
|||||||
Id EditorManagerPrivate::getOpenWithEditorId(const QString &fileName, bool *isExternalEditor)
|
Id EditorManagerPrivate::getOpenWithEditorId(const QString &fileName, bool *isExternalEditor)
|
||||||
{
|
{
|
||||||
// Collect editors that can open the file
|
// Collect editors that can open the file
|
||||||
const Utils::MimeType mt = Utils::mimeTypeForFile(fileName);
|
|
||||||
QList<Id> allEditorIds;
|
QList<Id> allEditorIds;
|
||||||
QStringList allEditorDisplayNames;
|
QStringList allEditorDisplayNames;
|
||||||
QList<Id> externalEditorIds;
|
QList<Id> externalEditorIds;
|
||||||
// Built-in
|
// Built-in
|
||||||
const EditorFactoryList editors = IEditorFactory::editorFactories(mt);
|
const EditorFactoryList editors = IEditorFactory::preferredEditorFactories(fileName);
|
||||||
const int size = editors.size();
|
const int size = editors.size();
|
||||||
allEditorDisplayNames.reserve(size);
|
allEditorDisplayNames.reserve(size);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
@@ -949,6 +950,7 @@ Id EditorManagerPrivate::getOpenWithEditorId(const QString &fileName, bool *isEx
|
|||||||
allEditorDisplayNames.push_back(editors.at(i)->displayName());
|
allEditorDisplayNames.push_back(editors.at(i)->displayName());
|
||||||
}
|
}
|
||||||
// External editors
|
// External editors
|
||||||
|
const Utils::MimeType mt = Utils::mimeTypeForFile(fileName);
|
||||||
const ExternalEditorList exEditors = IExternalEditor::externalEditors(mt);
|
const ExternalEditorList exEditors = IExternalEditor::externalEditors(mt);
|
||||||
const int esize = exEditors.size();
|
const int esize = exEditors.size();
|
||||||
for (int i = 0; i < esize; i++) {
|
for (int i = 0; i < esize; i++) {
|
||||||
@@ -971,6 +973,39 @@ Id EditorManagerPrivate::getOpenWithEditorId(const QString &fileName, bool *isEx
|
|||||||
return selectedId;
|
return selectedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QMap<QString, QVariant> toMap(const QHash<Utils::MimeType, IEditorFactory *> &hash)
|
||||||
|
{
|
||||||
|
QMap<QString, QVariant> map;
|
||||||
|
auto it = hash.begin();
|
||||||
|
const auto end = hash.end();
|
||||||
|
while (it != end) {
|
||||||
|
map.insert(it.key().name(), it.value()->id().toSetting());
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QHash<Utils::MimeType, IEditorFactory *> fromMap(const QMap<QString, QVariant> &map)
|
||||||
|
{
|
||||||
|
const EditorFactoryList factories = IEditorFactory::allEditorFactories();
|
||||||
|
QHash<Utils::MimeType, IEditorFactory *> hash;
|
||||||
|
auto it = map.begin();
|
||||||
|
const auto end = map.end();
|
||||||
|
while (it != end) {
|
||||||
|
const Utils::MimeType mimeType = Utils::mimeTypeForName(it.key());
|
||||||
|
if (mimeType.isValid()) {
|
||||||
|
const Id factoryId = Id::fromSetting(it.value());
|
||||||
|
IEditorFactory *factory = Utils::findOrDefault(factories,
|
||||||
|
Utils::equal(&IEditorFactory::id,
|
||||||
|
factoryId));
|
||||||
|
if (factory)
|
||||||
|
hash.insert(mimeType, factory);
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
void EditorManagerPrivate::saveSettings()
|
void EditorManagerPrivate::saveSettings()
|
||||||
{
|
{
|
||||||
ICore::settingsDatabase()->setValue(documentStatesKey, d->m_editorStates);
|
ICore::settingsDatabase()->setValue(documentStatesKey, d->m_editorStates);
|
||||||
@@ -992,6 +1027,7 @@ void EditorManagerPrivate::saveSettings()
|
|||||||
qsettings->remove(fileSystemCaseSensitivityKey);
|
qsettings->remove(fileSystemCaseSensitivityKey);
|
||||||
else
|
else
|
||||||
qsettings->setValue(fileSystemCaseSensitivityKey, sensitivity);
|
qsettings->setValue(fileSystemCaseSensitivityKey, sensitivity);
|
||||||
|
qsettings->setValue(preferredEditorFactoriesKey, toMap(userPreferredEditorFactories()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorManagerPrivate::readSettings()
|
void EditorManagerPrivate::readSettings()
|
||||||
@@ -1023,6 +1059,9 @@ void EditorManagerPrivate::readSettings()
|
|||||||
else
|
else
|
||||||
HostOsInfo::setOverrideFileNameCaseSensitivity(sensitivity);
|
HostOsInfo::setOverrideFileNameCaseSensitivity(sensitivity);
|
||||||
}
|
}
|
||||||
|
const QHash<Utils::MimeType, IEditorFactory *> preferredEditorFactories = fromMap(
|
||||||
|
qs->value(preferredEditorFactoriesKey).toMap());
|
||||||
|
setUserPreferredEditorFactories(preferredEditorFactories);
|
||||||
|
|
||||||
SettingsDatabase *settings = ICore::settingsDatabase();
|
SettingsDatabase *settings = ICore::settingsDatabase();
|
||||||
if (settings->contains(documentStatesKey)) {
|
if (settings->contains(documentStatesKey)) {
|
||||||
@@ -1127,7 +1166,7 @@ EditorFactoryList EditorManagerPrivate::findFactories(Id editorId, const QString
|
|||||||
|
|
||||||
EditorFactoryList factories;
|
EditorFactoryList factories;
|
||||||
if (!editorId.isValid()) {
|
if (!editorId.isValid()) {
|
||||||
factories = IEditorFactory::editorFactories(fileName);
|
factories = IEditorFactory::preferredEditorFactories(fileName);
|
||||||
} else {
|
} else {
|
||||||
// Find by editor id
|
// Find by editor id
|
||||||
IEditorFactory *factory = Utils::findOrDefault(IEditorFactory::allEditorFactories(),
|
IEditorFactory *factory = Utils::findOrDefault(IEditorFactory::allEditorFactories(),
|
||||||
@@ -2467,8 +2506,8 @@ void EditorManager::populateOpenWithMenu(QMenu *menu, const QString &fileName)
|
|||||||
|
|
||||||
menu->clear();
|
menu->clear();
|
||||||
|
|
||||||
|
const EditorFactoryList factories = IEditorFactory::preferredEditorFactories(fileName);
|
||||||
const Utils::MimeType mt = Utils::mimeTypeForFile(fileName);
|
const Utils::MimeType mt = Utils::mimeTypeForFile(fileName);
|
||||||
const EditorFactoryList factories = IEditorFactory::editorFactories(mt);
|
|
||||||
const ExternalEditorList extEditors = IExternalEditor::externalEditors(mt);
|
const ExternalEditorList extEditors = IExternalEditor::externalEditors(mt);
|
||||||
const bool anyMatches = !factories.empty() || !extEditors.empty();
|
const bool anyMatches = !factories.empty() || !extEditors.empty();
|
||||||
if (anyMatches) {
|
if (anyMatches) {
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "ieditorfactory.h"
|
#include "ieditorfactory.h"
|
||||||
|
#include "ieditorfactory_p.h"
|
||||||
#include "editormanager.h"
|
#include "editormanager.h"
|
||||||
#include "editormanager_p.h"
|
#include "editormanager_p.h"
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@
|
|||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
static QList<IEditorFactory *> g_editorFactories;
|
static QList<IEditorFactory *> g_editorFactories;
|
||||||
|
static QHash<Utils::MimeType, IEditorFactory *> g_userPreferredEditorFactories;
|
||||||
|
|
||||||
IEditorFactory::IEditorFactory(QObject *parent)
|
IEditorFactory::IEditorFactory(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
@@ -52,7 +54,11 @@ const EditorFactoryList IEditorFactory::allEditorFactories()
|
|||||||
return g_editorFactories;
|
return g_editorFactories;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EditorFactoryList IEditorFactory::editorFactories(const Utils::MimeType &mimeType)
|
/*!
|
||||||
|
Returns all available editors for this \a mimeType in the default order
|
||||||
|
(editors ordered by mime type hierarchy).
|
||||||
|
*/
|
||||||
|
const EditorFactoryList IEditorFactory::defaultEditorFactories(const Utils::MimeType &mimeType)
|
||||||
{
|
{
|
||||||
EditorFactoryList rc;
|
EditorFactoryList rc;
|
||||||
const EditorFactoryList allFactories = IEditorFactory::allEditorFactories();
|
const EditorFactoryList allFactories = IEditorFactory::allEditorFactories();
|
||||||
@@ -60,19 +66,45 @@ const EditorFactoryList IEditorFactory::editorFactories(const Utils::MimeType &m
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EditorFactoryList IEditorFactory::editorFactories(const QString &fileName)
|
/*!
|
||||||
|
Returns the available editors for \a fileName in order of preference.
|
||||||
|
That is the default order for the file's MIME type but with a user overridden default
|
||||||
|
editor first, and if the file is a too large text file, with the binary editor as the
|
||||||
|
very first.
|
||||||
|
*/
|
||||||
|
const EditorFactoryList IEditorFactory::preferredEditorFactories(const QString &fileName)
|
||||||
{
|
{
|
||||||
const QFileInfo fileInfo(fileName);
|
const QFileInfo fileInfo(fileName);
|
||||||
// Find by mime type
|
// default factories by mime type
|
||||||
Utils::MimeType mimeType = Utils::mimeTypeForFile(fileInfo);
|
const Utils::MimeType mimeType = Utils::mimeTypeForFile(fileInfo);
|
||||||
|
EditorFactoryList factories = defaultEditorFactories(mimeType);
|
||||||
|
const auto factories_moveToFront = [&factories](IEditorFactory *f) {
|
||||||
|
factories.removeAll(f);
|
||||||
|
factories.prepend(f);
|
||||||
|
};
|
||||||
|
// user preferred factory to front
|
||||||
|
IEditorFactory *userPreferred = Internal::userPreferredEditorFactories().value(mimeType);
|
||||||
|
if (userPreferred)
|
||||||
|
factories_moveToFront(userPreferred);
|
||||||
// open text files > 48 MB in binary editor
|
// open text files > 48 MB in binary editor
|
||||||
if (fileInfo.size() > EditorManager::maxTextFileSize()
|
if (fileInfo.size() > EditorManager::maxTextFileSize()
|
||||||
&& mimeType.inherits("text/plain")) {
|
&& mimeType.inherits("text/plain")) {
|
||||||
mimeType = Utils::mimeTypeForName("application/octet-stream");
|
const Utils::MimeType binary = Utils::mimeTypeForName("application/octet-stream");
|
||||||
|
const EditorFactoryList binaryEditors = defaultEditorFactories(binary);
|
||||||
|
if (!binaryEditors.isEmpty())
|
||||||
|
factories_moveToFront(binaryEditors.first());
|
||||||
}
|
}
|
||||||
|
return factories;
|
||||||
return IEditorFactory::editorFactories(mimeType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QHash<Utils::MimeType, Core::IEditorFactory *> Core::Internal::userPreferredEditorFactories()
|
||||||
|
{
|
||||||
|
return g_userPreferredEditorFactories;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Internal::setUserPreferredEditorFactories(const QHash<Utils::MimeType, IEditorFactory *> &factories)
|
||||||
|
{
|
||||||
|
g_userPreferredEditorFactories = factories;
|
||||||
|
}
|
||||||
|
|
||||||
} // Core
|
} // Core
|
||||||
|
@@ -49,8 +49,8 @@ public:
|
|||||||
~IEditorFactory() override;
|
~IEditorFactory() override;
|
||||||
|
|
||||||
static const EditorFactoryList allEditorFactories();
|
static const EditorFactoryList allEditorFactories();
|
||||||
static const EditorFactoryList editorFactories(const Utils::MimeType &mimeType);
|
static const EditorFactoryList defaultEditorFactories(const Utils::MimeType &mimeType);
|
||||||
static const EditorFactoryList editorFactories(const QString &fileName);
|
static const EditorFactoryList preferredEditorFactories(const QString &fileName);
|
||||||
|
|
||||||
QString displayName() const { return m_displayName; }
|
QString displayName() const { return m_displayName; }
|
||||||
void setDisplayName(const QString &displayName) { m_displayName = displayName; }
|
void setDisplayName(const QString &displayName) { m_displayName = displayName; }
|
||||||
|
42
src/plugins/coreplugin/editormanager/ieditorfactory_p.h
Normal file
42
src/plugins/coreplugin/editormanager/ieditorfactory_p.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2018 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utils/mimetypes/mimetype.h>
|
||||||
|
|
||||||
|
#include <QHash>
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
|
||||||
|
class IEditorFactory;
|
||||||
|
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
QHash<Utils::MimeType, IEditorFactory *> userPreferredEditorFactories();
|
||||||
|
void setUserPreferredEditorFactories(const QHash<Utils::MimeType, IEditorFactory *> &factories);
|
||||||
|
|
||||||
|
} // Internal
|
||||||
|
} // Core
|
@@ -30,6 +30,7 @@
|
|||||||
#include "ui_mimetypesettingspage.h"
|
#include "ui_mimetypesettingspage.h"
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/editormanager/ieditorfactory.h>
|
#include <coreplugin/editormanager/ieditorfactory.h>
|
||||||
|
#include <coreplugin/editormanager/ieditorfactory_p.h>
|
||||||
#include <coreplugin/editormanager/iexternaleditor.h>
|
#include <coreplugin/editormanager/iexternaleditor.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
static const char kModifiedMimeTypesFile[] = "/mimetypes/modifiedmimetypes.xml";
|
static const char kModifiedMimeTypesFile[] = "/mimetypes/modifiedmimetypes.xml";
|
||||||
@@ -66,6 +68,18 @@ static const char matchMaskAttributeC[] = "mask";
|
|||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class MimeEditorDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QWidget *createEditor(QWidget *parent,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const final;
|
||||||
|
void setEditorData(QWidget *editor, const QModelIndex &index) const final;
|
||||||
|
void setModelData(QWidget *editor,
|
||||||
|
QAbstractItemModel *model,
|
||||||
|
const QModelIndex &index) const final;
|
||||||
|
};
|
||||||
|
|
||||||
class UserMimeType
|
class UserMimeType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -81,6 +95,10 @@ class MimeTypeSettingsModel : public QAbstractTableModel
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum class Role {
|
||||||
|
DefaultHandler = Qt::UserRole
|
||||||
|
};
|
||||||
|
|
||||||
MimeTypeSettingsModel(QObject *parent = nullptr)
|
MimeTypeSettingsModel(QObject *parent = nullptr)
|
||||||
: QAbstractTableModel(parent) {}
|
: QAbstractTableModel(parent) {}
|
||||||
|
|
||||||
@@ -89,13 +107,18 @@ public:
|
|||||||
QVariant headerData(int section, Qt::Orientation orientation,
|
QVariant headerData(int section, Qt::Orientation orientation,
|
||||||
int role = Qt::DisplayRole) const override;
|
int role = Qt::DisplayRole) const override;
|
||||||
QVariant data(const QModelIndex &modelIndex, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &modelIndex, int role = Qt::DisplayRole) const override;
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) final;
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const final;
|
||||||
|
|
||||||
void load();
|
void load();
|
||||||
|
|
||||||
QString handlerForMimeType(const Utils::MimeType &mimeType) const;
|
QList<IEditorFactory *> handlersForMimeType(const Utils::MimeType &mimeType) const;
|
||||||
|
IEditorFactory *defaultHandlerForMimeType(const Utils::MimeType &mimeType) const;
|
||||||
|
void resetUserDefaults();
|
||||||
|
|
||||||
QList<Utils::MimeType> m_mimeTypes;
|
QList<Utils::MimeType> m_mimeTypes;
|
||||||
mutable QHash<Utils::MimeType, QString> m_handlersByMimeType;
|
mutable QHash<Utils::MimeType, QList<IEditorFactory *>> m_handlersByMimeType;
|
||||||
|
QHash<Utils::MimeType, IEditorFactory *> m_userDefault;
|
||||||
};
|
};
|
||||||
|
|
||||||
int MimeTypeSettingsModel::rowCount(const QModelIndex &) const
|
int MimeTypeSettingsModel::rowCount(const QModelIndex &) const
|
||||||
@@ -127,18 +150,61 @@ QVariant MimeTypeSettingsModel::data(const QModelIndex &modelIndex, int role) co
|
|||||||
const int column = modelIndex.column();
|
const int column = modelIndex.column();
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
const Utils::MimeType &type = m_mimeTypes.at(modelIndex.row());
|
const Utils::MimeType &type = m_mimeTypes.at(modelIndex.row());
|
||||||
if (column == 0)
|
if (column == 0) {
|
||||||
return type.name();
|
return type.name();
|
||||||
else
|
} else {
|
||||||
return handlerForMimeType(type);
|
IEditorFactory *defaultHandler = defaultHandlerForMimeType(type);
|
||||||
|
return defaultHandler ? defaultHandler->displayName() : QString();
|
||||||
|
}
|
||||||
|
} else if (role == Qt::EditRole) {
|
||||||
|
return qVariantFromValue(handlersForMimeType(m_mimeTypes.at(modelIndex.row())));
|
||||||
|
} else if (role == int(Role::DefaultHandler)) {
|
||||||
|
return qVariantFromValue(defaultHandlerForMimeType(m_mimeTypes.at(modelIndex.row())));
|
||||||
|
} else if (role == Qt::FontRole) {
|
||||||
|
if (column == 1) {
|
||||||
|
const Utils::MimeType &type = m_mimeTypes.at(modelIndex.row());
|
||||||
|
if (m_userDefault.contains(type)) {
|
||||||
|
QFont font = QGuiApplication::font();
|
||||||
|
font.setItalic(true);
|
||||||
|
return font;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MimeTypeSettingsModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
if (role != int(Role::DefaultHandler) || index.column() != 1)
|
||||||
|
return false;
|
||||||
|
auto factory = value.value<IEditorFactory *>();
|
||||||
|
QTC_ASSERT(factory, return false);
|
||||||
|
const int row = index.row();
|
||||||
|
QTC_ASSERT(row >= 0 && row < m_mimeTypes.size(), return false);
|
||||||
|
const Utils::MimeType mimeType = m_mimeTypes.at(row);
|
||||||
|
const QList<IEditorFactory *> handlers = handlersForMimeType(mimeType);
|
||||||
|
QTC_ASSERT(handlers.contains(factory), return false);
|
||||||
|
if (handlers.first() == factory) // selection is the default anyhow
|
||||||
|
m_userDefault.remove(mimeType);
|
||||||
|
else
|
||||||
|
m_userDefault.insert(mimeType, factory);
|
||||||
|
emit dataChanged(index, index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags MimeTypeSettingsModel::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (index.column() == 0 || handlersForMimeType(m_mimeTypes.at(index.row())).size() < 2)
|
||||||
|
return QAbstractTableModel::flags(index);
|
||||||
|
return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeTypeSettingsModel::load()
|
void MimeTypeSettingsModel::load()
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_mimeTypes = Utils::allMimeTypes();
|
m_mimeTypes = Utils::allMimeTypes();
|
||||||
|
m_userDefault = Core::Internal::userPreferredEditorFactories();
|
||||||
Utils::sort(m_mimeTypes, [](const Utils::MimeType &a, const Utils::MimeType &b) {
|
Utils::sort(m_mimeTypes, [](const Utils::MimeType &a, const Utils::MimeType &b) {
|
||||||
return a.name().compare(b.name(), Qt::CaseInsensitive) < 0;
|
return a.name().compare(b.name(), Qt::CaseInsensitive) < 0;
|
||||||
});
|
});
|
||||||
@@ -146,16 +212,29 @@ void MimeTypeSettingsModel::load()
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MimeTypeSettingsModel::handlerForMimeType(const Utils::MimeType &mimeType) const
|
QList<IEditorFactory *> MimeTypeSettingsModel::handlersForMimeType(
|
||||||
|
const Utils::MimeType &mimeType) const
|
||||||
{
|
{
|
||||||
if (!m_handlersByMimeType.contains(mimeType)) {
|
if (!m_handlersByMimeType.contains(mimeType))
|
||||||
const QList<IEditorFactory *> factories = IEditorFactory::editorFactories(mimeType);
|
m_handlersByMimeType.insert(mimeType, IEditorFactory::defaultEditorFactories(mimeType));
|
||||||
const QString value = factories.isEmpty() ? "" : factories.front()->displayName();
|
|
||||||
m_handlersByMimeType.insert(mimeType, value);
|
|
||||||
}
|
|
||||||
return m_handlersByMimeType.value(mimeType);
|
return m_handlersByMimeType.value(mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IEditorFactory *MimeTypeSettingsModel::defaultHandlerForMimeType(const Utils::MimeType &mimeType) const
|
||||||
|
{
|
||||||
|
if (m_userDefault.contains(mimeType))
|
||||||
|
return m_userDefault.value(mimeType);
|
||||||
|
const QList<IEditorFactory *> handlers = handlersForMimeType(mimeType);
|
||||||
|
return handlers.isEmpty() ? nullptr : handlers.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeTypeSettingsModel::resetUserDefaults()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_userDefault.clear();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
// MimeTypeSettingsPrivate
|
// MimeTypeSettingsPrivate
|
||||||
class MimeTypeSettingsPrivate : public QObject
|
class MimeTypeSettingsPrivate : public QObject
|
||||||
{
|
{
|
||||||
@@ -197,6 +276,7 @@ public:
|
|||||||
QString m_filterPattern;
|
QString m_filterPattern;
|
||||||
Ui::MimeTypeSettingsPage m_ui;
|
Ui::MimeTypeSettingsPage m_ui;
|
||||||
QPointer<QWidget> m_widget;
|
QPointer<QWidget> m_widget;
|
||||||
|
MimeEditorDelegate m_delegate;
|
||||||
};
|
};
|
||||||
|
|
||||||
const QChar MimeTypeSettingsPrivate::kSemiColon(QLatin1Char(';'));
|
const QChar MimeTypeSettingsPrivate::kSemiColon(QLatin1Char(';'));
|
||||||
@@ -225,6 +305,7 @@ void MimeTypeSettingsPrivate::configureUi(QWidget *w)
|
|||||||
connect(m_ui.filterLineEdit, &QLineEdit::textChanged,
|
connect(m_ui.filterLineEdit, &QLineEdit::textChanged,
|
||||||
this, &MimeTypeSettingsPrivate::setFilterPattern);
|
this, &MimeTypeSettingsPrivate::setFilterPattern);
|
||||||
m_ui.mimeTypesTreeView->setModel(m_filterModel);
|
m_ui.mimeTypesTreeView->setModel(m_filterModel);
|
||||||
|
m_ui.mimeTypesTreeView->setItemDelegate(&m_delegate);
|
||||||
|
|
||||||
new Utils::HeaderViewStretcher(m_ui.mimeTypesTreeView->header(), 1);
|
new Utils::HeaderViewStretcher(m_ui.mimeTypesTreeView->header(), 1);
|
||||||
|
|
||||||
@@ -243,6 +324,8 @@ void MimeTypeSettingsPrivate::configureUi(QWidget *w)
|
|||||||
this, &MimeTypeSettingsPrivate::editMagicHeader);
|
this, &MimeTypeSettingsPrivate::editMagicHeader);
|
||||||
connect(m_ui.resetButton, &QPushButton::clicked,
|
connect(m_ui.resetButton, &QPushButton::clicked,
|
||||||
this, &MimeTypeSettingsPrivate::resetMimeTypes);
|
this, &MimeTypeSettingsPrivate::resetMimeTypes);
|
||||||
|
connect(m_ui.resetHandlersButton, &QPushButton::clicked,
|
||||||
|
m_model, &MimeTypeSettingsModel::resetUserDefaults);
|
||||||
connect(m_ui.magicHeadersTreeWidget, &QTreeWidget::itemSelectionChanged,
|
connect(m_ui.magicHeadersTreeWidget, &QTreeWidget::itemSelectionChanged,
|
||||||
this, &MimeTypeSettingsPrivate::updatePatternEditAndMagicButtons);
|
this, &MimeTypeSettingsPrivate::updatePatternEditAndMagicButtons);
|
||||||
|
|
||||||
@@ -576,6 +659,7 @@ QWidget *MimeTypeSettings::widget()
|
|||||||
void MimeTypeSettings::apply()
|
void MimeTypeSettings::apply()
|
||||||
{
|
{
|
||||||
MimeTypeSettingsPrivate::applyUserModifiedMimeTypes(d->m_pendingModifiedMimeTypes);
|
MimeTypeSettingsPrivate::applyUserModifiedMimeTypes(d->m_pendingModifiedMimeTypes);
|
||||||
|
Core::Internal::setUserPreferredEditorFactories(d->m_model->m_userDefault);
|
||||||
d->m_pendingModifiedMimeTypes.clear();
|
d->m_pendingModifiedMimeTypes.clear();
|
||||||
d->m_model->load();
|
d->m_model->load();
|
||||||
}
|
}
|
||||||
@@ -593,6 +677,39 @@ void MimeTypeSettings::restoreSettings()
|
|||||||
MimeTypeSettingsPrivate::applyUserModifiedMimeTypes(mimetypes);
|
MimeTypeSettingsPrivate::applyUserModifiedMimeTypes(mimetypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget *MimeEditorDelegate::createEditor(QWidget *parent,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(option)
|
||||||
|
Q_UNUSED(index)
|
||||||
|
return new QComboBox(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeEditorDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
auto box = static_cast<QComboBox *>(editor);
|
||||||
|
const auto factories = index.model()->data(index, Qt::EditRole).value<QList<IEditorFactory *>>();
|
||||||
|
for (IEditorFactory *factory : factories)
|
||||||
|
box->addItem(factory->displayName(), qVariantFromValue(factory));
|
||||||
|
int currentIndex = factories.indexOf(
|
||||||
|
index.model()
|
||||||
|
->data(index, int(MimeTypeSettingsModel::Role::DefaultHandler))
|
||||||
|
.value<IEditorFactory *>());
|
||||||
|
if (QTC_GUARD(currentIndex != -1))
|
||||||
|
box->setCurrentIndex(currentIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeEditorDelegate::setModelData(QWidget *editor,
|
||||||
|
QAbstractItemModel *model,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
auto box = static_cast<QComboBox *>(editor);
|
||||||
|
model->setData(index,
|
||||||
|
box->currentData(Qt::UserRole),
|
||||||
|
int(MimeTypeSettingsModel::Role::DefaultHandler));
|
||||||
|
}
|
||||||
|
|
||||||
} // Internal
|
} // Internal
|
||||||
} // Core
|
} // Core
|
||||||
|
|
||||||
|
@@ -27,24 +27,7 @@
|
|||||||
<string>Registered MIME Types</string>
|
<string>Registered MIME Types</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="0" colspan="2">
|
<item row="2" column="2">
|
||||||
<widget class="QLineEdit" name="filterLineEdit">
|
|
||||||
<property name="placeholderText">
|
|
||||||
<string>Filter</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QPushButton" name="resetButton">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Reset all to default.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Reset All</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
@@ -57,8 +40,18 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" colspan="2">
|
<item row="0" column="0" colspan="3">
|
||||||
|
<widget class="QLineEdit" name="filterLineEdit">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Filter</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="3">
|
||||||
<widget class="QTreeView" name="mimeTypesTreeView">
|
<widget class="QTreeView" name="mimeTypesTreeView">
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
|
||||||
|
</property>
|
||||||
<property name="rootIsDecorated">
|
<property name="rootIsDecorated">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
@@ -67,6 +60,23 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QPushButton" name="resetButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Reset all to default.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Reset MIME Types</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QPushButton" name="resetHandlersButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reset Handlers</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QGroupBox" name="detailsGroupBox">
|
<widget class="QGroupBox" name="detailsGroupBox">
|
||||||
|
Reference in New Issue
Block a user