OSDN Git Service

32a457f388b8941f1263cd003dab64692e4b23b8
[qt-creator-jp/qt-creator-jp.git] / src / plugins / coreplugin / mimedatabase.h
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
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
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
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.
24 **
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.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #ifndef MIMEDATABASE_H
35 #define MIMEDATABASE_H
36
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>
45
46 QT_BEGIN_NAMESPACE
47 class QIODevice;
48 class QRegExp;
49 class QDebug;
50 class QFileInfo;
51 QT_END_NAMESPACE
52
53 namespace Core {
54
55 class MimeTypeData;
56 class MimeDatabasePrivate;
57
58 namespace Internal {
59     class BaseMimeTypeParser;
60     class FileMatchContext;
61 }
62
63 /* Magic (file contents) matcher interface. */
64 class CORE_EXPORT IMagicMatcher
65 {
66     Q_DISABLE_COPY(IMagicMatcher)
67 protected:
68     IMagicMatcher() {}
69 public:
70     typedef QSharedPointer<IMagicMatcher> IMagicMatcherSharedPointer;
71     typedef QList<IMagicMatcherSharedPointer> IMagicMatcherList;
72
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() {}
78 };
79
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
84 {
85     Q_DISABLE_COPY(MagicRule)
86 public:
87     MagicRule(int startPos, int endPos);
88     virtual ~MagicRule();
89
90     virtual QString matchType() const = 0;
91     virtual QString matchValue() const = 0;
92     virtual bool matches(const QByteArray &data) const = 0;
93
94     int startPos() const;
95     int endPos() const;
96
97     static QString toOffset(const QPair<int, int> &startEnd);
98     static QPair<int, int> fromOffset(const QString &offset);
99
100 private:
101     static const QChar kColon;
102
103     const int m_startPos;
104     const int m_endPos;
105 };
106
107 class CORE_EXPORT MagicStringRule : public MagicRule
108 {
109 public:
110     MagicStringRule(const QString &s, int startPos, int endPos);
111     virtual ~MagicStringRule();
112
113     virtual QString matchType() const;
114     virtual QString matchValue() const;
115     virtual bool matches(const QByteArray &data) const;
116
117     static const QString kMatchType;
118
119 private:
120     const QByteArray m_pattern;
121 };
122
123 class CORE_EXPORT MagicByteRule : public MagicRule
124 {
125 public:
126     MagicByteRule(const QString &s, int startPos, int endPos);
127     virtual ~MagicByteRule();
128
129     virtual QString matchType() const;
130     virtual QString matchValue() const;
131     virtual bool matches(const QByteArray &data) const;
132
133     static bool validateByteSequence(const QString &sequence, QList<int> *bytes = 0);
134
135     static const QString kMatchType;
136
137 private:
138     int m_bytesSize;
139     QList<int> m_bytes;
140 };
141
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
145 {
146     Q_DISABLE_COPY(MagicRuleMatcher)
147 public:
148     typedef QSharedPointer<MagicRule> MagicRuleSharedPointer;
149     typedef QList<MagicRuleSharedPointer> MagicRuleList;
150
151     MagicRuleMatcher();
152
153     void add(const MagicRuleSharedPointer &rule);
154     void add(const MagicRuleList &ruleList);
155     MagicRuleList magicRules() const;
156
157     virtual bool matches(const QByteArray &data) const;
158
159     virtual int priority() const;
160     void setPriority(int p);
161
162     // Create a list of MagicRuleMatchers from a hash of rules indexed by priorities.
163     static IMagicMatcher::IMagicMatcherList createMatchers(const QHash<int, MagicRuleList> &);
164
165 private:
166     MagicRuleList m_list;
167     int m_priority;
168 };
169
170 class CORE_EXPORT MimeGlobPattern
171 {
172 public:
173     static const unsigned MaxWeight = 100;
174     static const unsigned MinWeight = 1;
175
176     explicit MimeGlobPattern(const QRegExp &regExp, unsigned weight = MaxWeight);
177     ~MimeGlobPattern();
178
179     const QRegExp &regExp() const;
180     unsigned weight() const;
181
182 private:
183     QRegExp m_regExp;
184     int m_weight;
185 };
186
187 /* Mime type data used in Qt Creator. Contains most information from
188  * standard mime type XML database files.
189  * Omissions:
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
193  * Extensions:
194  * - List of suffixes and preferred suffix (derived from glob patterns).
195  */
196 class CORE_EXPORT MimeType
197 {
198 public:
199     typedef IMagicMatcher::IMagicMatcherList IMagicMatcherList;
200     typedef IMagicMatcher::IMagicMatcherSharedPointer IMagicMatcherSharedPointer;
201
202     MimeType();
203     MimeType(const MimeType&);
204     MimeType &operator=(const MimeType&);
205     ~MimeType();
206
207     void clear();
208     bool isNull() const;
209     operator bool() const;
210
211     bool isTopLevel() const;
212
213     QString type() const;
214     void setType(const QString &type);
215
216     QStringList aliases() const;
217     void setAliases(const QStringList &);
218
219     QString comment() const;
220     void setComment(const QString &comment);
221
222     QString localeComment(const QString &locale = QString() /* en, de...*/) const;
223     void setLocaleComment(const QString &locale, const QString &comment);
224
225     QList<MimeGlobPattern> globPatterns() const;
226     void setGlobPatterns(const QList<MimeGlobPattern> &);
227
228     QStringList subClassesOf() const;
229     void setSubClassesOf(const QStringList &);
230
231     // Extension over standard mime data
232     QStringList suffixes() const;
233     QString preferredSuffix() const;
234     bool setPreferredSuffix(const QString&);
235
236     // Check for type or one of the aliases
237     bool matchesType(const QString &type) const;
238
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;
242
243     // Return a filter string usable for a file dialog
244     QString filterString() const;
245
246     void addMagicMatcher(const IMagicMatcherSharedPointer &matcher);
247
248     const IMagicMatcherList &magicMatchers() const;
249     void setMagicMatchers(const IMagicMatcherList &matchers);
250
251     // Convenience for rule-base matchers.
252     IMagicMatcherList magicRuleMatchers() const;
253     void setMagicRuleMatchers(const IMagicMatcherList &matchers);
254
255     friend QDebug operator<<(QDebug d, const MimeType &mt);
256
257     static QString formatFilterString(const QString &description,
258                                       const QList<MimeGlobPattern> &globs);
259
260 private:
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;
265
266     friend class Internal::BaseMimeTypeParser;
267     friend class MimeDatabasePrivate;
268     QSharedDataPointer<MimeTypeData> m_d;
269 };
270
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. */
276
277 class CORE_EXPORT MimeDatabase
278 {
279     Q_DISABLE_COPY(MimeDatabase)
280 public:
281     typedef IMagicMatcher::IMagicMatcherList IMagicMatcherList;
282     typedef IMagicMatcher::IMagicMatcherSharedPointer IMagicMatcherSharedPointer;
283
284     MimeDatabase();
285     ~MimeDatabase();
286
287     bool addMimeTypes(const QString &fileName, QString *errorMessage);
288     bool addMimeTypes(QIODevice *device, QString *errorMessage);
289     bool addMimeType(const  MimeType &mt);
290
291     // Returns a mime type or Null one if none found
292     MimeType findByType(const QString &type) const;
293
294     // Returns a mime type or Null one if none found
295     MimeType findByFile(const QFileInfo &f) const;
296
297     // Returns a mime type or Null one if none found
298     MimeType findByData(const QByteArray &data) const;
299
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
303     // single file.
304     template <class Iterator, typename Function>
305     inline void findByFile(Iterator i1, const Iterator &i2, Function f) const;
306
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;
312
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;
316
317     QList<MimeGlobPattern> globPatterns() const;
318     void setGlobPatterns(const QString &typeOrAlias, const QList<MimeGlobPattern> &globPatterns);
319
320     IMagicMatcherList magicMatchers() const;
321     void setMagicMatchers(const QString &typeOrAlias, const IMagicMatcherList &matchers);
322
323     QList<MimeType> mimeTypes() const;
324
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();
331
332     static QList<MimeGlobPattern> toGlobPatterns(const QStringList &patterns,
333                                                  int weight = MimeGlobPattern::MaxWeight);
334     static QStringList fromGlobPatterns(const QList<MimeGlobPattern> &globPatterns);
335
336     friend QDebug operator<<(QDebug d, const MimeDatabase &mt);
337
338 private:
339     MimeType findByFileUnlocked(const QFileInfo &f) const;
340
341     MimeDatabasePrivate *m_d;
342     mutable QMutex m_mutex;
343 };
344
345 template <class Iterator, typename Function>
346     void MimeDatabase::findByFile(Iterator i1, const Iterator &i2, Function f) const
347 {
348     m_mutex.lock();
349     for ( ; i1 != i2; ++i1) {
350         const QFileInfo fi(*i1);
351         f(findByFileUnlocked(fi), fi, *i1);
352     }
353     m_mutex.unlock();
354 }
355
356 } // namespace Core
357
358 #endif // MIMEDATABASE_H