OSDN Git Service

It's 2011 now.
[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
45 QT_BEGIN_NAMESPACE
46 class QIODevice;
47 class QRegExp;
48 class QDebug;
49 class QFileInfo;
50 QT_END_NAMESPACE
51
52 namespace Core {
53
54 class MimeTypeData;
55 class MimeDatabasePrivate;
56
57 namespace Internal {
58     class BaseMimeTypeParser;
59     class FileMatchContext;
60 }
61
62 /* Magic (file contents) matcher interface. */
63 class CORE_EXPORT IMagicMatcher
64 {
65     Q_DISABLE_COPY(IMagicMatcher)
66 protected:
67     IMagicMatcher() {}
68 public:
69     // Check for a match on contents of a file
70     virtual bool matches(const QByteArray &data) const = 0;
71     // Return a priority value from 1..100
72     virtual int priority() const = 0;
73     virtual ~IMagicMatcher() {}
74 };
75
76 /* Utility class: A standard Magic match rule based on contents. Currently there are
77  * implementations for "string" and "byte". (Others like little16, big16, etc. can be
78  * created whenever there is a need.) */
79 class CORE_EXPORT MagicRule
80 {
81     Q_DISABLE_COPY(MagicRule)
82 public:
83     MagicRule(int startPos, int endPos);
84     virtual ~MagicRule();
85
86     virtual bool matches(const QByteArray &data) const = 0;
87
88 protected:
89     int startPos() const;
90     int endPos() const;
91
92 private:
93     const int m_startPos;
94     const int m_endPos;
95 };
96
97 class CORE_EXPORT MagicStringRule : public MagicRule
98 {
99 public:
100     MagicStringRule(const QString &s, int startPos, int endPos);
101     virtual ~MagicStringRule();
102
103     virtual bool matches(const QByteArray &data) const;
104
105 private:
106     const QByteArray m_pattern;
107 };
108
109 class CORE_EXPORT MagicByteRule : public MagicRule
110 {
111 public:
112     MagicByteRule(const QString &s, int startPos, int endPos);
113     virtual ~MagicByteRule();
114
115     virtual bool matches(const QByteArray &data) const;
116
117 private:
118     QList<int> m_bytes;
119     int m_bytesSize;
120 };
121
122 /* Utility class: A Magic matcher that checks a number of rules based on
123  * operator "or". It is used for rules parsed from XML files. */
124 class CORE_EXPORT MagicRuleMatcher : public IMagicMatcher
125 {
126     Q_DISABLE_COPY(MagicRuleMatcher)
127 public:
128     typedef  QSharedPointer<MagicRule> MagicRuleSharedPointer;
129
130     MagicRuleMatcher();
131     void add(const MagicRuleSharedPointer &rule);
132     virtual bool matches(const QByteArray &data) const;
133
134     virtual int priority() const;
135     void setPriority(int p);
136
137 private:
138     typedef QList<MagicRuleSharedPointer> MagicRuleList;
139     MagicRuleList m_list;
140     int m_priority;
141 };
142
143 class CORE_EXPORT MimeGlobPattern
144 {
145 public:
146     static const unsigned MaxWeight = 100;
147     static const unsigned MinWeight = 1;
148
149     explicit MimeGlobPattern(const QRegExp &regExp, unsigned weight = MaxWeight);
150     ~MimeGlobPattern();
151
152     const QRegExp &regExp() const;
153     unsigned weight() const;
154
155 private:
156     QRegExp m_regExp;
157     int m_weight;
158 };
159
160 /* Mime type data used in Qt Creator. Contains most information from
161  * standard mime type XML database files.
162  * Omissions:
163  * - Only magic of type "string" is supported. In addition, C++ classes
164  *   derived from IMagicMatcher can be added to check on contents
165  * - acronyms, language-specific comments
166  * Extensions:
167  * - List of suffixes and preferred suffix (derived from glob patterns).
168  */
169 class CORE_EXPORT MimeType
170 {
171 public:
172     MimeType();
173     MimeType(const MimeType&);
174     MimeType &operator=(const MimeType&);
175     ~MimeType();
176
177     void clear();
178     bool isNull() const;
179     operator bool() const;
180
181     bool isTopLevel() const;
182
183     QString type() const;
184     void setType(const QString &type);
185
186     QStringList aliases() const;
187     void setAliases(const QStringList &);
188
189     QString comment() const;
190     void setComment(const QString &comment);
191
192     QString localeComment(const QString &locale = QString() /* en, de...*/) const;
193     void setLocaleComment(const QString &locale, const QString &comment);
194
195     QList<MimeGlobPattern> globPatterns() const;
196     void setGlobPatterns(const QList<MimeGlobPattern> &);
197
198     QStringList subClassesOf() const;
199     void setSubClassesOf(const QStringList &);
200
201     // Extension over standard mime data
202     QStringList suffixes() const;
203     void setSuffixes(const QStringList &);
204
205     // Extension over standard mime data
206     QString preferredSuffix() const;
207     bool setPreferredSuffix(const QString&);
208
209     // Check for type or one of the aliases
210     bool matchesType(const QString &type) const;
211
212     // Check glob patterns weights and magic priorities so the highest
213     // value is returned. A 0 (zero) indicates no match.
214     unsigned matchesFile(const QFileInfo &file) const;
215
216     // Return a filter string usable for a file dialog
217     QString filterString() const;
218
219     // Add magic matcher
220     void addMagicMatcher(const QSharedPointer<IMagicMatcher> &matcher);
221
222     friend QDebug operator<<(QDebug d, const MimeType &mt);
223
224     static QString formatFilterString(const QString &description, const QList<MimeGlobPattern> &globs);
225
226 private:
227     explicit MimeType(const MimeTypeData &d);
228     unsigned matchesFileBySuffix(Internal::FileMatchContext &c) const;
229     unsigned matchesFileByContent(Internal::FileMatchContext &c) const;
230
231     friend class Internal::BaseMimeTypeParser;
232     friend class MimeDatabasePrivate;
233     QSharedDataPointer<MimeTypeData> m_d;
234 };
235
236 /* A Mime data base to which the plugins can add the mime types they handle.
237  * When adding a "text/plain" to it, the mimetype will receive a magic matcher
238  * that checks for text files that do not match the globs by heuristics.
239  * The class is protected by a QMutex and can therefore be accessed by threads.
240  * A good testcase is to run it over '/usr/share/mime/<*>/<*>.xml' on Linux. */
241
242 class CORE_EXPORT MimeDatabase
243 {
244     Q_DISABLE_COPY(MimeDatabase)
245 public:
246     MimeDatabase();
247
248     ~MimeDatabase();
249
250     bool addMimeTypes(const QString &fileName, QString *errorMessage);
251     bool addMimeTypes(QIODevice *device, QString *errorMessage);
252     bool addMimeType(const  MimeType &mt);
253
254     // Returns a mime type or Null one if none found
255     MimeType findByType(const QString &type) const;
256
257     // Returns a mime type or Null one if none found
258     MimeType findByFile(const QFileInfo &f) const;
259     // Convenience that mutex-locks the DB and calls a function
260     // of the signature 'void f(const MimeType &, const QFileInfo &, const QString &)'
261     // for each filename of a sequence. This avoids locking the DB for each
262     // single file.
263     template <class Iterator, typename Function>
264         inline void findByFile(Iterator i1, const Iterator &i2, Function f) const;
265
266     // Convenience
267     QString preferredSuffixByType(const QString &type) const;
268     QString preferredSuffixByFile(const QFileInfo &f) const;
269
270     // Return all known suffixes
271     QStringList suffixes() const;
272     bool setPreferredSuffix(const QString &typeOrAlias, const QString &suffix);
273
274     QStringList filterStrings() const;
275
276     friend QDebug operator<<(QDebug d, const MimeDatabase &mt);
277
278     // returns a string with all the possible file filters, for use with file dialogs
279     QString allFiltersString(QString *allFilesFilter = 0) const;
280 private:
281     MimeType findByFileUnlocked(const QFileInfo &f) const;
282
283     MimeDatabasePrivate *m_d;
284     mutable QMutex m_mutex;
285 };
286
287 template <class Iterator, typename Function>
288     void MimeDatabase::findByFile(Iterator i1, const Iterator &i2, Function f) const
289 {
290     m_mutex.lock();
291     for ( ; i1 != i2; ++i1) {
292         const QFileInfo fi(*i1);
293         f(findByFileUnlocked(fi), fi, *i1);
294     }
295     m_mutex.unlock();
296 }
297
298 } // namespace Core
299
300 #endif // MIMEDATABASE_H