1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #ifndef MIMEDATABASE_H
35 #define MIMEDATABASE_H
37 #include <coreplugin/core_global.h>
38 #include <QtCore/QStringList>
39 #include <QtCore/QSharedDataPointer>
40 #include <QtCore/QSharedPointer>
41 #include <QtCore/QByteArray>
42 #include <QtCore/QMutex>
43 #include <QtCore/QFileInfo>
44 #include <QtCore/QPair>
56 class MimeDatabasePrivate;
59 class BaseMimeTypeParser;
60 class FileMatchContext;
63 /* Magic (file contents) matcher interface. */
64 class CORE_EXPORT IMagicMatcher
66 Q_DISABLE_COPY(IMagicMatcher)
70 typedef QSharedPointer<IMagicMatcher> IMagicMatcherSharedPointer;
71 typedef QList<IMagicMatcherSharedPointer> IMagicMatcherList;
73 // Check for a match on contents of a file
74 virtual bool matches(const QByteArray &data) const = 0;
75 // Return a priority value from 1..100
76 virtual int priority() const = 0;
77 virtual ~IMagicMatcher() {}
80 /* Utility class: A standard Magic match rule based on contents. Currently there are
81 * implementations for "string" and "byte". (Others like little16, big16, etc. can be
82 * created whenever there is a need.) */
83 class CORE_EXPORT MagicRule
85 Q_DISABLE_COPY(MagicRule)
87 MagicRule(int startPos, int endPos);
90 virtual QString matchType() const = 0;
91 virtual QString matchValue() const = 0;
92 virtual bool matches(const QByteArray &data) const = 0;
97 static QString toOffset(const QPair<int, int> &startEnd);
98 static QPair<int, int> fromOffset(const QString &offset);
101 static const QChar kColon;
103 const int m_startPos;
107 class CORE_EXPORT MagicStringRule : public MagicRule
110 MagicStringRule(const QString &s, int startPos, int endPos);
111 virtual ~MagicStringRule();
113 virtual QString matchType() const;
114 virtual QString matchValue() const;
115 virtual bool matches(const QByteArray &data) const;
117 static const QString kMatchType;
120 const QByteArray m_pattern;
123 class CORE_EXPORT MagicByteRule : public MagicRule
126 MagicByteRule(const QString &s, int startPos, int endPos);
127 virtual ~MagicByteRule();
129 virtual QString matchType() const;
130 virtual QString matchValue() const;
131 virtual bool matches(const QByteArray &data) const;
133 static bool validateByteSequence(const QString &sequence, QList<int> *bytes = 0);
135 static const QString kMatchType;
142 /* Utility class: A Magic matcher that checks a number of rules based on
143 * operator "or". It is used for rules parsed from XML files. */
144 class CORE_EXPORT MagicRuleMatcher : public IMagicMatcher
146 Q_DISABLE_COPY(MagicRuleMatcher)
148 typedef QSharedPointer<MagicRule> MagicRuleSharedPointer;
149 typedef QList<MagicRuleSharedPointer> MagicRuleList;
153 void add(const MagicRuleSharedPointer &rule);
154 void add(const MagicRuleList &ruleList);
155 MagicRuleList magicRules() const;
157 virtual bool matches(const QByteArray &data) const;
159 virtual int priority() const;
160 void setPriority(int p);
162 // Create a list of MagicRuleMatchers from a hash of rules indexed by priorities.
163 static IMagicMatcher::IMagicMatcherList createMatchers(const QHash<int, MagicRuleList> &);
166 MagicRuleList m_list;
170 class CORE_EXPORT MimeGlobPattern
173 static const unsigned MaxWeight = 100;
174 static const unsigned MinWeight = 1;
176 explicit MimeGlobPattern(const QRegExp ®Exp, unsigned weight = MaxWeight);
179 const QRegExp ®Exp() const;
180 unsigned weight() const;
187 /* Mime type data used in Qt Creator. Contains most information from
188 * standard mime type XML database files.
190 * - Only magic of type "string" is supported. In addition, C++ classes
191 * derived from IMagicMatcher can be added to check on contents
192 * - acronyms, language-specific comments
194 * - List of suffixes and preferred suffix (derived from glob patterns).
196 class CORE_EXPORT MimeType
199 typedef IMagicMatcher::IMagicMatcherList IMagicMatcherList;
200 typedef IMagicMatcher::IMagicMatcherSharedPointer IMagicMatcherSharedPointer;
203 MimeType(const MimeType&);
204 MimeType &operator=(const MimeType&);
209 operator bool() const;
211 bool isTopLevel() const;
213 QString type() const;
214 void setType(const QString &type);
216 QStringList aliases() const;
217 void setAliases(const QStringList &);
219 QString comment() const;
220 void setComment(const QString &comment);
222 QString localeComment(const QString &locale = QString() /* en, de...*/) const;
223 void setLocaleComment(const QString &locale, const QString &comment);
225 QList<MimeGlobPattern> globPatterns() const;
226 void setGlobPatterns(const QList<MimeGlobPattern> &);
228 QStringList subClassesOf() const;
229 void setSubClassesOf(const QStringList &);
231 // Extension over standard mime data
232 QStringList suffixes() const;
233 QString preferredSuffix() const;
234 bool setPreferredSuffix(const QString&);
236 // Check for type or one of the aliases
237 bool matchesType(const QString &type) const;
239 // Check glob patterns weights and magic priorities so the highest
240 // value is returned. A 0 (zero) indicates no match.
241 unsigned matchesFile(const QFileInfo &file) const;
243 // Return a filter string usable for a file dialog
244 QString filterString() const;
246 void addMagicMatcher(const IMagicMatcherSharedPointer &matcher);
248 const IMagicMatcherList &magicMatchers() const;
249 void setMagicMatchers(const IMagicMatcherList &matchers);
251 // Convenience for rule-base matchers.
252 IMagicMatcherList magicRuleMatchers() const;
253 void setMagicRuleMatchers(const IMagicMatcherList &matchers);
255 friend QDebug operator<<(QDebug d, const MimeType &mt);
257 static QString formatFilterString(const QString &description,
258 const QList<MimeGlobPattern> &globs);
261 explicit MimeType(const MimeTypeData &d);
262 unsigned matchesFileBySuffix(Internal::FileMatchContext &c) const;
263 unsigned matchesFileByContent(Internal::FileMatchContext &c) const;
264 unsigned matchesData(const QByteArray &data) const;
266 friend class Internal::BaseMimeTypeParser;
267 friend class MimeDatabasePrivate;
268 QSharedDataPointer<MimeTypeData> m_d;
271 /* A Mime data base to which the plugins can add the mime types they handle.
272 * When adding a "text/plain" to it, the mimetype will receive a magic matcher
273 * that checks for text files that do not match the globs by heuristics.
274 * The class is protected by a QMutex and can therefore be accessed by threads.
275 * A good testcase is to run it over '/usr/share/mime/<*>/<*>.xml' on Linux. */
277 class CORE_EXPORT MimeDatabase
279 Q_DISABLE_COPY(MimeDatabase)
281 typedef IMagicMatcher::IMagicMatcherList IMagicMatcherList;
282 typedef IMagicMatcher::IMagicMatcherSharedPointer IMagicMatcherSharedPointer;
287 bool addMimeTypes(const QString &fileName, QString *errorMessage);
288 bool addMimeTypes(QIODevice *device, QString *errorMessage);
289 bool addMimeType(const MimeType &mt);
291 // Returns a mime type or Null one if none found
292 MimeType findByType(const QString &type) const;
294 // Returns a mime type or Null one if none found
295 MimeType findByFile(const QFileInfo &f) const;
297 // Returns a mime type or Null one if none found
298 MimeType findByData(const QByteArray &data) const;
300 // Convenience that mutex-locks the DB and calls a function
301 // of the signature 'void f(const MimeType &, const QFileInfo &, const QString &)'
302 // for each filename of a sequence. This avoids locking the DB for each
304 template <class Iterator, typename Function>
305 inline void findByFile(Iterator i1, const Iterator &i2, Function f) const;
307 // Return all known suffixes
308 QStringList suffixes() const;
309 bool setPreferredSuffix(const QString &typeOrAlias, const QString &suffix);
310 QString preferredSuffixByType(const QString &type) const;
311 QString preferredSuffixByFile(const QFileInfo &f) const;
313 QStringList filterStrings() const;
314 // Return a string with all the possible file filters, for use with file dialogs
315 QString allFiltersString(QString *allFilesFilter = 0) const;
317 QList<MimeGlobPattern> globPatterns() const;
318 void setGlobPatterns(const QString &typeOrAlias, const QList<MimeGlobPattern> &globPatterns);
320 IMagicMatcherList magicMatchers() const;
321 void setMagicMatchers(const QString &typeOrAlias, const IMagicMatcherList &matchers);
323 QList<MimeType> mimeTypes() const;
325 // The mime types from the functions bellow are considered only in regard to
326 // their glob patterns and rule-based magic matchers.
327 void syncUserModifiedMimeTypes();
328 static QList<MimeType> readUserModifiedMimeTypes();
329 static void writeUserModifiedMimeTypes(const QList<MimeType> &mimeTypes);
330 void clearUserModifiedMimeTypes();
332 static QList<MimeGlobPattern> toGlobPatterns(const QStringList &patterns,
333 int weight = MimeGlobPattern::MaxWeight);
334 static QStringList fromGlobPatterns(const QList<MimeGlobPattern> &globPatterns);
336 friend QDebug operator<<(QDebug d, const MimeDatabase &mt);
339 MimeType findByFileUnlocked(const QFileInfo &f) const;
341 MimeDatabasePrivate *m_d;
342 mutable QMutex m_mutex;
345 template <class Iterator, typename Function>
346 void MimeDatabase::findByFile(Iterator i1, const Iterator &i2, Function f) const
349 for ( ; i1 != i2; ++i1) {
350 const QFileInfo fi(*i1);
351 f(findByFileUnlocked(fi), fi, *i1);
358 #endif // MIMEDATABASE_H