1/* This file is part of the KDE libraries
2 * Copyright (C) 1999 Waldo Bastian <bastian@kde.org>
3 * David Faure <faure@kde.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License version 2 as published by the Free Software Foundation;
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 **/
19
20#ifndef __kmimetype_h__
21#define __kmimetype_h__
22
23#include <QtCore/QStringList>
24#include <QtCore/QList>
25
26#include <kurl.h>
27#include <ksycocatype.h>
28#include <kservicetype.h>
29
30#include <sys/types.h>
31#include <sys/stat.h>
32
33class KMimeTypePrivate;
34
35/**
36 * Represent a mime type, like "text/plain", and the data that is associated
37 * with it.
38 *
39 * The starting point you need is often the static methods.
40 *
41 * KMimeType inherits KServiceType because "text/plain" can be used to find
42 * services (apps and components) "which can open text/plain".
43 *
44 * @see KServiceType
45 */
46class KDECORE_EXPORT KMimeType : public KServiceType // TODO KDE5: drop kservicetype inheritance, inherit kshared
47{
48 Q_DECLARE_PRIVATE( KMimeType )
49public:
50 typedef KSharedPtr<KMimeType> Ptr;
51 typedef QList<Ptr> List;
52
53 virtual ~KMimeType();
54
55 /**
56 * Return the filename of the icon associated with the mimetype.
57 * Use KIconLoader::loadMimeTypeIcon to load the icon.
58 *
59 * @param url argument only used for directories, where the icon
60 * can be specified in the .directory file.
61 *
62 * @return The name of the icon associated with this MIME type.
63 */
64 QString iconName( const KUrl &url = KUrl()) const;
65
66 /**
67 * Return the filename of the icon associated with the mimetype, for a given url.
68 * Use KIconLoader::loadMimeTypeIcon to load the icon.
69 * @param url URL for the file
70 * @param mode the mode of the file. The mode may modify the icon
71 * with overlays that show special properties of the
72 * icon. Use 0 for default
73 * @return the name of the icon. The name of a default icon if there is no icon
74 * for the mime type
75 */
76 static QString iconNameForUrl( const KUrl & url, mode_t mode = 0 );
77
78 /**
79 * Return the "favicon" (see http://www.favicon.com) for the given @p url,
80 * if available. Does NOT attempt to download the favicon, it only returns
81 * one that is already available.
82 *
83 * If unavailable, returns QString().
84 * @param url the URL of the favicon
85 * @return the name of the favicon, or QString()
86 */
87 static QString favIconForUrl( const KUrl& url );
88
89 /**
90 * Returns the descriptive comment associated with the MIME type.
91 * The url argument is unused, but provided so that KMimeType derived classes
92 * can use it.
93 *
94 * @return The descriptive comment associated with the MIME type, if any.
95 */
96 QString comment( const KUrl& url = KUrl() ) const;
97
98 /**
99 * Retrieve the list of patterns associated with the MIME Type.
100 * @return a list of file globs that describe the file names
101 * (or, usually, the extensions) of files with this mime type
102 */
103 QStringList patterns() const;
104
105 enum FindByNameOption { DontResolveAlias, ResolveAliases = 1 };
106
107 /**
108 * Retrieve a pointer to the mime type @p name
109 *
110 * @em Very @em important: Don't store the result in a KMimeType* !
111 *
112 * Also note that you get a new KMimeType pointer every time you call this.
113 * Don't ever write code that compares mimetype pointers, compare names instead.
114 *
115 * @param name the name of the mime type
116 * @param options controls how the mime type is searched for
117 * @return the pointer to the KMimeType with the given @p name, or
118 * 0 if not found
119 * @see KServiceType::serviceType
120 */
121 static Ptr mimeType( const QString& name, FindByNameOption options = ResolveAliases );
122
123 /**
124 * Finds a KMimeType with the given @p url.
125 * This function looks at mode_t first.
126 * If that does not help it looks at the extension (and the contents, for local files).
127 * This method is fine for many protocols like ftp, file, fish, zip etc.,
128 * but is not for http (e.g. cgi scripts
129 * make extension-based checking unreliable).
130 * For HTTP you should use KRun instead (to open the URL, in an app
131 * or internally), or a KIO::mimetype() job (to find the mimetype without
132 * downloading), or a KIO::get() job (to find the mimetype and then download).
133 * In fact KRun is the most complete solution, but deriving from it just
134 * for this is a bit cumbersome.
135 *
136 * If no extension matches, then the file contents will be examined if the URL is a local file, or
137 * "application/octet-stream" is returned otherwise.
138 *
139 * @param url Is the right most URL with a filesystem protocol. It
140 * is up to you to find out about that if you have a nested
141 * URL. For example
142 * "http://localhost/mist.gz#gzip:/decompress" would have to
143 * pass the "http://..." URL part, while
144 * "file:/tmp/x.tar#tar:/src/test.gz#gzip:/decompress" would
145 * have to pass the "tar:/..." part of the URL, since gzip is
146 * a filter protocol and not a filesystem protocol.
147 * @param mode the mode of the file (used, for example, to identify
148 * executables)
149 * @param is_local_file true if the file is local; false if not, or if you don't know.
150 * @param fast_mode If set to true no disk access is allowed to
151 * find out the mimetype. The result may be suboptimal, but
152 * it is @em fast.
153 * @param accuracy if set, the accuracy of the result, between 0 and 100.
154 * For instance, when the extension was used to determine the mimetype,
155 * the accuracy is set to 80, as per the shared-mime spec.
156 * Some 'magic' rules (used when !fast_mode) have an accuracy > 80
157 * (and have priority over the filename, others are < 80).
158 *
159 * @return A pointer to the matching mimetype. 0 is never returned.
160 * @em Very @em Important: Don't store the result in a KMimeType* !
161 */
162 static Ptr findByUrl( const KUrl& url, mode_t mode = 0,
163 bool is_local_file = false, bool fast_mode = false,
164 int *accuracy = 0 );
165 /**
166 * Finds a KMimeType with the given @p url.
167 * This function looks at mode_t first.
168 * If that does not help it
169 * looks at the extension. This is fine for FTP, FILE, TAR and
170 * friends, but is not for HTTP ( cgi scripts! ). You should use
171 * KRun instead, but this function returns immediately while
172 * KRun is async. If no extension matches, then
173 * the file contents will be examined if the URL is a local file, or
174 * "application/octet-stream" is returned otherwise.
175 *
176 * Equivalent to
177 * \code
178 * KUrl u(path);
179 * return findByUrl( u, mode, true, fast_mode );
180 * \endcode
181 *
182 * @param path the path to the file (a file name is enough, in fast mode)
183 * @param mode the mode of the file (used, for example, to identify
184 * executables)
185 * @param fast_mode If set to true no disk access is allowed to
186 * find out the mimetype. The result may be suboptimal, but
187 * it is @em fast.
188 * @param accuracy If not a null pointer, *accuracy is set to the
189 * accuracy of the match (which is in the range 0..100)
190 * @return A pointer to the matching mimetype. 0 is never returned.
191 */
192 static Ptr findByPath( const QString& path, mode_t mode = 0,
193 bool fast_mode = false, int* accuracy = 0 );
194
195 /**
196 * Tries to find out the MIME type of a data chunk by looking for
197 * certain magic numbers and characteristic strings in it.
198 *
199 * @param data the data to examine
200 * @param accuracy If not a null pointer, *accuracy is set to the
201 * accuracy of the match (which is in the range 0..100)
202 * @return a pointer to the KMimeType. "application/octet-stream" is
203 * returned if the type can not be found this way.
204 */
205 static Ptr findByContent( const QByteArray &data, int *accuracy=0 );
206
207 /**
208 * Tries to find out the MIME type of filename/url and a data chunk.
209 * Whether to trust the extension or the data depends on the results of both approaches,
210 * and is determined automatically.
211 *
212 * This method is useful for instance in the get() method of kioslaves, and anywhere else
213 * where a filename is associated with some data which is available immediately.
214 *
215 * @param name the filename or url representing this data.
216 * Only used for the extension, not used as a local filename.
217 * @param data the data to examine when the extension isn't conclusive in itself
218 * @param mode the mode of the file (used, for example, to identify executables)
219 * @param accuracy If not a null pointer, *accuracy is set to the
220 * accuracy of the match (which is in the range 0..100)
221 */
222 static Ptr findByNameAndContent( const QString& name, const QByteArray& data,
223 mode_t mode = 0, int *accuracy=0 );
224
225 /**
226 * Tries to find out the MIME type of a data chunk by looking for
227 * certain magic numbers and characteristic strings in it.
228 *
229 * @param device the IO device providing the data to examine
230 * @param accuracy If not a null pointer, *accuracy is set to the
231 * accuracy of the match (which is in the range 0..100)
232 * @return a pointer to the KMimeType. "application/octet-stream" is
233 * returned if the type can not be found this way.
234 * @since 4.4
235 */
236 static Ptr findByContent( QIODevice* device, int* accuracy = 0 );
237
238 /**
239 * Tries to find out the MIME type of filename/url and a data chunk.
240 * Whether to trust the extension or the data depends on the results of both approaches,
241 * and is determined automatically.
242 *
243 * This method is useful for instance in the get() method of kioslaves, and anywhere else
244 * where a filename is associated with some data which is available immediately.
245 *
246 * @param name the filename or url representing this data.
247 * Only used for the extension, not used as a local filename.
248 * @param device the IO device providing the data to examine when the extension isn't conclusive in itself
249 * @param mode the mode of the file (used, for example, to identify executables)
250 * @param accuracy If not a null pointer, *accuracy is set to the
251 * accuracy of the match (which is in the range 0..100)
252 * @return a pointer to the KMimeType. "application/octet-stream" is
253 * returned if the type can not be found this way.
254 * @since 4.4
255 */
256 static Ptr findByNameAndContent( const QString& name, QIODevice* device,
257 mode_t mode = 0, int* accuracy = 0 );
258
259 /**
260 * Tries to find out the MIME type of a file by looking for
261 * certain magic numbers and characteristic strings in it.
262 * This function is similar to the previous one. Note that the
263 * file name is not used for determining the file type, it is just
264 * used for loading the file's contents.
265 *
266 * @param fileName the path to the file
267 * @param accuracy If not a null pointer, *accuracy is set to the
268 * accuracy of the match (which is in the range 0..100)
269 * @return a pointer to the KMimeType, or the default mimetype
270 * (application/octet-stream) if the file cannot be opened.
271 */
272 static Ptr findByFileContent( const QString &fileName, int *accuracy=0 );
273
274 /**
275 * Returns whether a file has an internal format that is not human readable.
276 * This is much more generic than "not mime->is(text/plain)".
277 * Many application file formats (like rtf and postscript) are based on text,
278 * but text that the user should rarely ever see.
279 */
280 static bool isBinaryData( const QString &fileName );
281
282 /**
283 * Returns whether a buffer has an internal format that is not human readable.
284 * This is much more generic than "not mime->is(text/plain)".
285 * Many application file formats (like rtf and postscript) are based on text,
286 * but text that the user should rarely ever see.
287 */
288 static bool isBufferBinaryData( const QByteArray &data );
289
290 /**
291 * Get all the mimetypes.
292 *
293 * Useful for showing the list of
294 * available mimetypes.
295 * More memory consuming than the ones above, don't use unless
296 * really necessary.
297 * @return the list of all existing KMimeTypes
298 */
299 static List allMimeTypes();
300
301 /**
302 * Returns the name of the default mimetype.
303 * Always application/octet-stream, but this method exists
304 * for performance purposes.
305 * @return the name of the default mime type, always
306 * "application/octet-stream"
307 */
308 static QString defaultMimeType();
309
310 /**
311 * Returns the default mimetype.
312 * Always application/octet-stream.
313 * This can be used to check the result of mimeType(name).
314 * @return the "application/octet-stream" mimetype pointer.
315 */
316 static KMimeType::Ptr defaultMimeTypePtr();
317
318 /// Return true if this mimetype is the default mimetype
319 bool isDefault() const;
320
321 /**
322 * If this mimetype is a subclass of another mimetype,
323 * return the name of the parent.
324 *
325 * @return the parent mime type, or QString() if not set
326 *
327 * @deprecated this method does not support multiple inheritance,
328 * which is actually part of the shared-mime-info standard.
329 * Use is(), parentMimeTypes(), or allParentMimeTypes() instead of parentMimeType()
330 */
331#ifndef KDE_NO_DEPRECATED
332 KDE_DEPRECATED QString parentMimeType() const;
333#endif
334
335 /**
336 * If this mimetype is a subclass of one or more other mimetypes,
337 * return the list of those mimetypes.
338 *
339 * For instance a application/javascript is a special kind of text/plain,
340 * so the definition of application/javascript says
341 * sub-class-of type="text/plain"
342 *
343 * Another example: application/x-shellscript is a subclass of two other mimetypes,
344 * application/x-executable and text/plain.
345 *
346 * (Note that this notion doesn't map to the servicetype inheritance mechanism,
347 * since an application that handles the specific type doesn't necessarily handle
348 * the base type. The opposite is true though.)
349 *
350 * @return the list of parent mimetypes
351 * @since 4.1
352 */
353 QStringList parentMimeTypes() const;
354
355 /**
356 * Return all parent mimetypes of this mimetype, direct or indirect.
357 * This includes the parent(s) of its parent(s), etc.
358 * If this mimetype is an alias, the list also contains the canonical
359 * name for this mimetype.
360 *
361 * The usual reason to use this method is to look for a setting which
362 * is stored per mimetype (like PreviewJob does).
363 * @since 4.1
364 */
365 QStringList allParentMimeTypes() const;
366
367 /**
368 * Do not use name()=="somename" anymore, to check for a given mimetype.
369 * For mimetype inheritance to work, use is("somename") instead.
370 * Warning, do not use inherits(), that's the servicetype inheritance concept!
371 * is() also supports mimetype aliases.
372 */
373 bool is( const QString& mimeTypeName ) const;
374
375 /**
376 * Returns the user-specified icon for this mimetype. This is empty most of the time,
377 * you probably want to use iconName() instead. This method is for the mimetype editor.
378 * @since 4.3
379 */
380 QString userSpecifiedIconName() const;
381
382 /**
383 * Return the primary extension associated with this mimetype, if any.
384 * If patterns() returns (*.jpg, *.jpeg) then mainExtension will return ".jpg".
385 * Note that the dot is included.
386 *
387 * If none of the patterns is in *.foo format (for instance
388 * <code>*.jp? or *.* or callgrind.out* </code>)
389 * then mainExtension() returns an empty string.
390 *
391 * @since 4.3
392 */
393 QString mainExtension() const;
394
395 /**
396 * Determines the extension from a filename (or full path) using the mimetype database.
397 * This allows to extract "tar.bz2" for foo.tar.bz2
398 * but still return "txt" for my.doc.with.dots.txt
399 */
400 static QString extractKnownExtension( const QString &fileName );
401
402 /**
403 * Returns true if the given filename matches the given pattern.
404 * @since 4.6.1
405 */
406 static bool matchFileName( const QString &filename, const QString &pattern );
407
408 /**
409 * Returns the version of the installed update-mime-database program
410 * (from freedesktop.org shared-mime-info). This is used by unit tests
411 * and by the code that writes out icon definitions.
412 * @since 4.3
413 * @return -1 on error, otherwise a version number to use like this:
414 * @code
415 * if (version >= KDE_MAKE_VERSION(0, 40, 0)) { ... }
416 * @endcode
417 */
418 static int sharedMimeInfoVersion();
419
420protected:
421
422 friend class KMimeTypeRepository; // for KMimeType(QString,QString,QString)
423
424 /**
425 * @internal Construct a service from a stream.
426 *
427 * The stream must already be positionned at the correct offset
428 */
429 KMimeType( QDataStream& str, int offset );
430
431 /**
432 * Construct a mimetype and take all information from an XML file.
433 * @param fullpath the path to the xml that describes the mime type
434 * @param name the name of the mimetype (usually the end of the path)
435 * @param comment the comment associated with the mimetype
436 */
437 KMimeType( const QString& fullpath, const QString& name, const QString& comment );
438
439 /**
440 * Construct a mimetype from another mimetype's private object
441 *
442 * @param dd the private object
443 */
444 KMimeType( KMimeTypePrivate &dd);
445
446 /**
447 * Construct a mimetype based on another mimetype's private object
448 *
449 * Allows the name and comment to be overridden.
450 *
451 * @param dd the private object
452 * @param name the name of the mimetype
453 * @param comment the comment associated with the mimetype
454 */
455 KMimeType( KMimeTypePrivate &dd, const QString& name, const QString& comment );
456
457private:
458 // Forbidden nowadays in KMimeType
459 int offset() const;
460 void save(QDataStream &s);
461
462 void loadInternal( QDataStream& _str);
463 static void buildDefaultType();
464 static void checkEssentialMimeTypes();
465 static KMimeType::Ptr findByUrlHelper( const KUrl& url, mode_t mode,
466 bool is_local_file, QIODevice* device, int* accuracy );
467};
468
469#endif
470