Mimetypes v3: Re-implement adding mime types from plugin data

We get mime data specifications in text from from the plugin meta data.
Add mime providers for these.
An obvious example is application/vnd.google.android.android_manifest.
Disable automatic, time-based update of mime providers, and instead
explicitly force reloading them.

Change-Id: I07e3399ca76b1913d79b92375f679ca729c594b7
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
Eike Ziller
2022-02-25 10:04:49 +01:00
parent 3922db8ca9
commit 5f70f5e336
5 changed files with 73 additions and 10 deletions

View File

@@ -85,10 +85,14 @@ int mime_secondsBetweenChecks = 5;
bool MimeDatabasePrivate::shouldCheck() bool MimeDatabasePrivate::shouldCheck()
{ {
#if 0
if (m_lastCheck.isValid() && m_lastCheck.elapsed() < mime_secondsBetweenChecks * 1000) if (m_lastCheck.isValid() && m_lastCheck.elapsed() < mime_secondsBetweenChecks * 1000)
return false; return false;
m_lastCheck.start(); m_lastCheck.start();
return true; return true;
#endif
// Qt Creator forces reload manually
return m_forceLoad;
} }
#if defined(Q_OS_UNIX) && !defined(Q_OS_NACL) && !defined(Q_OS_INTEGRITY) #if defined(Q_OS_UNIX) && !defined(Q_OS_NACL) && !defined(Q_OS_INTEGRITY)
@@ -108,7 +112,23 @@ void MimeDatabasePrivate::loadProviders()
Providers currentProviders; Providers currentProviders;
std::swap(m_providers, currentProviders); std::swap(m_providers, currentProviders);
m_providers.reserve(mimeDirs.size() + (needInternalDB ? 1 : 0)); m_providers.reserve(m_additionalData.size() + mimeDirs.size() + (needInternalDB ? 1 : 0));
// added for Qt Creator: additional mime data
for (auto dataIt = m_additionalData.cbegin(); dataIt != m_additionalData.cend(); ++dataIt) {
// Check if we already have a provider for this data
const QString id = dataIt.key();
const auto it = std::find_if(currentProviders.begin(), currentProviders.end(),
[id](const std::unique_ptr<MimeProviderBase> &prov) {
return prov && prov->directory() == id;
});
std::unique_ptr<MimeProviderBase> provider;
if (it != currentProviders.end())
provider = std::move(*it); // take provider out of the vector
provider.reset(new MimeXMLProvider(this, id, dataIt.value()));
m_providers.push_back(std::move(provider));
}
for (const QString &mimeDir : mimeDirs) { for (const QString &mimeDir : mimeDirs) {
const QString cacheFile = mimeDir + QStringLiteral("/mime.cache"); const QString cacheFile = mimeDir + QStringLiteral("/mime.cache");
@@ -168,11 +188,14 @@ const MimeDatabasePrivate::Providers &MimeDatabasePrivate::providers()
#endif #endif
if (m_providers.empty()) { if (m_providers.empty()) {
loadProviders(); loadProviders();
m_lastCheck.start(); // Qt Creator forces reload manually
// m_lastCheck.start();
} else { } else {
if (shouldCheck()) if (shouldCheck())
loadProviders(); loadProviders();
} }
// Qt Creator forces reload manually
m_forceLoad = false;
return m_providers; return m_providers;
} }
@@ -851,4 +874,14 @@ QList<MimeType> MimeDatabase::allMimeTypes() const
\value MatchContent The file content is used to look for a match \value MatchContent The file content is used to look for a match
*/ */
// added for Qt Creator
void MimeDatabasePrivate::addMimeData(const QString &id, const QByteArray &data)
{
if (m_additionalData.contains(id))
qWarning("Overwriting data in mime database, id '%s'", qPrintable(id));
m_additionalData.insert(id, data);
m_forceLoad = true;
}
} // namespace Utils } // namespace Utils

View File

@@ -104,6 +104,9 @@ public:
QStringList listAliases(const QString &mimeName); QStringList listAliases(const QString &mimeName);
bool mimeInherits(const QString &mime, const QString &parent); bool mimeInherits(const QString &mime, const QString &parent);
// added for Qt Creator
void addMimeData(const QString &id, const QByteArray &data);
private: private:
using Providers = std::vector<std::unique_ptr<MimeProviderBase>>; using Providers = std::vector<std::unique_ptr<MimeProviderBase>>;
const Providers &providers(); const Providers &providers();
@@ -113,6 +116,10 @@ private:
mutable Providers m_providers; mutable Providers m_providers;
QElapsedTimer m_lastCheck; QElapsedTimer m_lastCheck;
// added for Qt Creator
QHash<QString, QByteArray> m_additionalData; // id -> data
bool m_forceLoad = true;
public: public:
const QString m_defaultMimeType; const QString m_defaultMimeType;
QMutex mutex; QMutex mutex;

View File

@@ -863,4 +863,25 @@ void MimeXMLProvider::addMagicMatcher(const MimeMagicRuleMatcher &matcher)
m_magicMatchers.append(matcher); m_magicMatchers.append(matcher);
} }
// added for Qt Creator
MimeXMLProvider::MimeXMLProvider(MimeDatabasePrivate *db,
const QString &directory,
const QByteArray &data)
: MimeProviderBase(db, directory)
{
QString errorMessage;
MimeTypeParser parser(*this);
QByteArray bufferData(data);
QBuffer buffer(&bufferData);
if (!buffer.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning("MimeDatabase: Error creating buffer for data with ID %ls.",
qUtf16Printable(directory));
}
if (!parser.parse(&buffer, directory, &errorMessage)) {
qWarning("MimeDatabase: Error loading data for ID %ls\n%ls",
qUtf16Printable(directory),
qUtf16Printable(errorMessage));
}
}
} // namespace Utils } // namespace Utils

View File

@@ -146,6 +146,8 @@ public:
#endif #endif
MimeXMLProvider(MimeDatabasePrivate *db, InternalDatabaseEnum); MimeXMLProvider(MimeDatabasePrivate *db, InternalDatabaseEnum);
MimeXMLProvider(MimeDatabasePrivate *db, const QString &directory); MimeXMLProvider(MimeDatabasePrivate *db, const QString &directory);
// added for Qt Creator
MimeXMLProvider(MimeDatabasePrivate *db, const QString &directory, const QByteArray &data);
~MimeXMLProvider(); ~MimeXMLProvider();
bool isValid() override; bool isValid() override;

View File

@@ -104,17 +104,17 @@ void setMimeStartupPhase(MimeStartupPhase phase)
d->m_startupPhase = int(phase); d->m_startupPhase = int(phase);
} }
void addMimeTypes(const QString &fileName, const QByteArray &data) void addMimeTypes(const QString &id, const QByteArray &data)
{ {
// auto d = MimeDatabasePrivate::instance(); auto d = MimeDatabasePrivate::instance();
// QMutexLocker locker(&d->mutex); QMutexLocker locker(&d->mutex);
// if (d->m_startupPhase >= MimeDatabase::PluginsDelayedInitializing) if (d->m_startupPhase >= int(MimeStartupPhase::PluginsDelayedInitializing)) {
// qWarning("Adding items from %s to MimeDatabase after initialization time", qWarning("Adding items for ID \"%s\" to MimeDatabase after initialization time",
// qPrintable(fileName)); qPrintable(id));
}
// auto xmlProvider = static_cast<MimeXMLProvider *>(d->provider()); d->addMimeData(id, data);
// xmlProvider->addData(fileName, data);
} }
QMap<int, QList<MimeMagicRule>> magicRulesForMimeType(const MimeType &mimeType) QMap<int, QList<MimeMagicRule>> magicRulesForMimeType(const MimeType &mimeType)