• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • services
kmimetype.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 * Copyright (C) 1999 Waldo Bastian <bastian@kde.org>
3 * 2000-2007 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#include "kmimetype.h"
21#include "kmimetype_p.h"
22#include "kmimetypefactory.h"
23#include "kmimetyperepository_p.h"
24
25#include <kdebug.h>
26#include <kde_file.h> // KDE::stat
27#include <kdeversion.h> // KDE_MAKE_VERSION
28#include <klocale.h>
29#include <kprotocolinfo.h>
30#include <kprotocolinfofactory.h>
31#include <kstandarddirs.h>
32#include <kurl.h>
33
34#include <QtCore/QFile>
35#include <QtDBus/QtDBus>
36#include <QtCore/QHash>
37#include <QBuffer>
38
39extern int servicesDebugArea();
40
41template class KSharedPtr<KMimeType>;
42
43KMimeType::Ptr KMimeType::defaultMimeTypePtr()
44{
45 return KMimeTypeRepository::self()->defaultMimeTypePtr();
46}
47
48bool KMimeType::isDefault() const
49{
50 return name() == defaultMimeType();
51}
52
53void KMimeType::checkEssentialMimeTypes()
54{
55 KMimeTypeRepository::self()->checkEssentialMimeTypes();
56}
57
58KMimeType::Ptr KMimeType::mimeType(const QString& name, FindByNameOption options)
59{
60 return KMimeTypeRepository::self()->findMimeTypeByName(name, options);
61}
62
63KMimeType::List KMimeType::allMimeTypes()
64{
65 // This could be done faster...
66 KMimeType::List lst;
67 Q_FOREACH(const QString& mimeType, KMimeTypeFactory::self()->allMimeTypes()) {
68 if (!mimeType.startsWith(QLatin1String("x-scheme-handler")))
69 lst.append(KMimeType::mimeType(mimeType));
70 }
71 return lst;
72}
73
74bool KMimeType::isBufferBinaryData(const QByteArray& data)
75{
76 // Check the first 32 bytes (see shared-mime spec)
77 const char* p = data.data();
78 const int end = qMin(32, data.size());
79 for (int i = 0; i < end; ++i) {
80 if ((unsigned char)(p[i]) < 32 && p[i] != 9 && p[i] != 10 && p[i] != 13) // ASCII control character
81 return true;
82 }
83 return false;
84}
85
86static KMimeType::Ptr findFromMode( const QString& path /*only used if is_local_file*/,
87 mode_t mode /*0 if unknown*/,
88 bool is_local_file )
89{
90 if ( is_local_file && (mode == 0 || mode == (mode_t)-1) ) {
91 KDE_struct_stat buff;
92 if ( KDE::stat( path, &buff ) != -1 )
93 mode = buff.st_mode;
94 }
95
96 if ( S_ISDIR( mode ) ) {
97 // KDE4 TODO: use an overlay instead
98#if 0
99 // Special hack for local files. We want to see whether we
100 // are allowed to enter the directory
101 if ( is_local_file )
102 {
103 if ( KDE::access( path, R_OK ) == -1 )
104 return KMimeType::mimeType( "inode/directory-locked" );
105 }
106#endif
107 return KMimeType::mimeType( QLatin1String("inode/directory") );
108 }
109 if ( S_ISCHR( mode ) )
110 return KMimeType::mimeType( QLatin1String("inode/chardevice") );
111 if ( S_ISBLK( mode ) )
112 return KMimeType::mimeType( QLatin1String("inode/blockdevice") );
113 if ( S_ISFIFO( mode ) )
114 return KMimeType::mimeType( QLatin1String("inode/fifo") );
115 if ( S_ISSOCK( mode ) )
116 return KMimeType::mimeType( QLatin1String("inode/socket") );
117#ifdef Q_OS_WIN
118 // FIXME: distinguish between mounted & unmounted
119 int size = path.size();
120 if ( size == 2 || size == 3 ) {
121 //GetDriveTypeW is not defined in wince
122#ifndef _WIN32_WCE
123 unsigned int type = GetDriveTypeW( (LPCWSTR) path.utf16() );
124 switch( type ) {
125 case DRIVE_REMOVABLE:
126 return KMimeType::mimeType( QLatin1String("media/floppy_mounted") );
127 case DRIVE_FIXED:
128 return KMimeType::mimeType( QLatin1String("media/hdd_mounted") );
129 case DRIVE_REMOTE:
130 return KMimeType::mimeType( QLatin1String("media/smb_mounted") );
131 case DRIVE_CDROM:
132 return KMimeType::mimeType( QLatin1String("media/cdrom_mounted") );
133 case DRIVE_RAMDISK:
134 return KMimeType::mimeType( QLatin1String("media/hdd_mounted") );
135 default:
136 break;
137 };
138#else
139 return KMimeType::mimeType( QLatin1String("media/hdd_mounted") );
140#endif
141 }
142#endif
143 // remote executable file? stop here (otherwise findFromContent can do that better for local files)
144 if ( !is_local_file && S_ISREG( mode ) && ( mode & ( S_IXUSR | S_IXGRP | S_IXOTH ) ) )
145 return KMimeType::mimeType( QLatin1String("application/x-executable") );
146
147 return KMimeType::Ptr();
148}
149
150/*
151
152As agreed on the XDG list (and unlike the current shared-mime spec):
153
154Glob-matching should prefer derived mimetype over base mimetype, and longer matches
155over shorter ones. However if two globs of the same length match the file, and the two
156matches are not related in the inheritance tree, then we have a "glob conflict", which
157will be resolved below.
158
159If only one glob matches, use that
160
161If no glob matches, sniff and use that
162
163If several globs matches, and sniffing gives a result we do:
164 if sniffed prio >= 80, use sniffed type
165 for glob_match in glob_matches:
166 if glob_match is subclass or equal to sniffed_type, use glob_match
167
168If several globs matches, and sniffing fails, or doesn't help:
169 fall back to the first glob match
170
171This algorithm only sniffs when there is some uncertainty with the
172extension matching (thus, it's usable for a file manager).
173
174Note: in KDE we want the file views to sniff in a delayed manner.
175So there's also a fast mode which is:
176 if no glob matches, or if more than one glob matches, use default mimetype and mark as "can be refined".
177
178*/
179
180KMimeType::Ptr KMimeType::findByUrlHelper( const KUrl& _url, mode_t mode,
181 bool is_local_file,
182 QIODevice* device,
183 int* accuracy )
184{
185 checkEssentialMimeTypes();
186 const QString path = is_local_file ? _url.toLocalFile() : _url.path();
187
188 if (accuracy)
189 *accuracy = 100;
190
191 // Look at mode first
192 KMimeType::Ptr mimeFromMode = findFromMode( path, mode, is_local_file );
193 if (mimeFromMode)
194 return mimeFromMode;
195
196 // First try to find out by looking at the filename (if there's one)
197 const QString fileName( _url.fileName() );
198 QStringList mimeList;
199 if ( !fileName.isEmpty() && !path.endsWith( QLatin1Char('/') ) ) {
200 // and if we can trust it (e.g. don't trust *.pl over HTTP, could be anything)
201 if ( is_local_file || _url.hasSubUrl() || // Explicitly trust suburls
202 KProtocolInfo::determineMimetypeFromExtension( _url.protocol() ) ) {
203 mimeList = KMimeTypeRepository::self()->findFromFileName( fileName );
204 // Found one glob match exactly: OK, use that.
205 // We disambiguate multiple glob matches by sniffing, below.
206 if ( mimeList.count() == 1 ) {
207 const QString selectedMime = mimeList.at(0);
208 KMimeType::Ptr mime = mimeType(selectedMime);
209 if (!mime) {
210 // #265188 - this can happen when an old globs file is lying around after
211 // the packages xml file was removed.
212 kWarning() << "Glob file refers to" << selectedMime << "but this mimetype does not exist!";
213 mimeList.clear();
214 } else {
215 return mime;
216 }
217 }
218 }
219 }
220
221 if ( device && !device->isOpen() ) {
222 if ( !device->open(QIODevice::ReadOnly) ) {
223 device = 0;
224 }
225 }
226
227 // Try the magic matches (if we can read the data)
228 QByteArray beginning;
229 if ( device ) {
230 int magicAccuracy;
231 KMimeType::Ptr mime = KMimeTypeRepository::self()->findFromContent(device, &magicAccuracy, beginning);
232 // mime can't be 0, except in case of install problems.
233 // However we get magicAccuracy==0 for octet-stream, i.e. no magic match found.
234 //kDebug(servicesDebugArea()) << "findFromContent said" << (mime?mime->name():QString()) << "with accuracy" << magicAccuracy;
235 if (mime && magicAccuracy > 0) {
236
237 // Disambiguate conflicting extensions (if magic found something and the magicrule was <80)
238 if (magicAccuracy < 80 && !mimeList.isEmpty()) {
239 // "for glob_match in glob_matches:"
240 // "if glob_match is subclass or equal to sniffed_type, use glob_match"
241 const QString sniffedMime = mime->name();
242 foreach(const QString &m, mimeList) {
243 KMimeType::Ptr mimeFromPattern = KMimeType::mimeType(m);
244 //kDebug(servicesDebugArea()) << "sniffedMime=" << sniffedMime << "mimeFromPattern=" << mimeFromPattern->name();
245 if (mimeFromPattern && mimeFromPattern->is(sniffedMime)) {
246 // We have magic + pattern pointing to this, so it's a pretty good match
247 if (accuracy)
248 *accuracy = 100;
249 return mimeFromPattern;
250 }
251 }
252 }
253
254 if (accuracy)
255 *accuracy = magicAccuracy;
256 return mime;
257 }
258 }
259
260 // Not a local file, or no magic allowed, or magic found nothing
261
262 // Maybe we had multiple matches from globs?
263 if (!mimeList.isEmpty()) {
264 if (accuracy)
265 *accuracy = 20;
266 // We have to pick one...
267 // At least make this deterministic
268 qSort(mimeList.begin(), mimeList.end());
269 Q_FOREACH(const QString& mimeName, mimeList) {
270 KMimeType::Ptr mime = mimeType(mimeName);
271 if (!mime)
272 kWarning() << "Glob file refers to" << mimeName << "but this mimetype does not exist!";
273 else
274 return mime;
275 }
276 }
277
278 // Find a fallback from the protocol
279 if (accuracy)
280 *accuracy = 10;
281 // ## this breaks with proxying; find a way to move proxying info to kdecore's kprotocolinfo?
282 // ## or hardcode the only case of proxying that we ever had? (ftp-over-http)
283 KProtocolInfo::Ptr prot = KProtocolInfoFactory::self()->findProtocol( _url.protocol() );
284 QString def;
285 if (prot)
286 def = prot->defaultMimeType();
287 if ( !def.isEmpty() && def != defaultMimeType() ) {
288 // The protocol says it always returns a given mimetype (e.g. text/html for "man:")
289 KMimeType::Ptr mime = mimeType( def );
290 if (mime)
291 return mime;
292 }
293 if ( path.endsWith( QLatin1Char('/') ) || path.isEmpty() ) {
294 // We have no filename at all. Maybe the protocol has a setting for
295 // which mimetype this means (e.g. directory).
296 // For HTTP (def==defaultMimeType()) we don't assume anything,
297 // because of redirections (e.g. freshmeat downloads).
298 if ( def.isEmpty() ) {
299 // Assume inode/directory, if the protocol supports listing.
300 KProtocolInfo::Ptr prot = KProtocolInfoFactory::self()->findProtocol( _url.protocol() );
301 if ( prot && prot->supportsListing() ) {
302 KMimeType::Ptr mime = mimeType( QLatin1String("inode/directory") );
303 if (mime) { // only 0 if no mimetypes installed
304 return mime;
305 }
306 } else
307 return defaultMimeTypePtr(); // == 'no idea', e.g. for "data:,foo/"
308 }
309 }
310
311 if (accuracy)
312 *accuracy = 0;
313 return defaultMimeTypePtr();
314}
315
316KMimeType::Ptr KMimeType::findByUrl( const KUrl& url, mode_t mode,
317 bool is_local_file, bool fast_mode,
318 int *accuracy )
319{
320 if ( !is_local_file && url.isLocalFile() )
321 is_local_file = true;
322 if (is_local_file && !fast_mode) {
323 QFile file(url.toLocalFile());
324 return findByUrlHelper(url, mode, is_local_file, &file, accuracy);
325 }
326 return findByUrlHelper(url, mode, is_local_file, 0, accuracy);
327}
328
329KMimeType::Ptr KMimeType::findByPath( const QString& path, mode_t mode,
330 bool fast_mode, int* accuracy )
331{
332 KUrl url;
333 url.setPath(path);
334 return findByUrl(url, mode, true, fast_mode, accuracy);
335}
336
337KMimeType::Ptr KMimeType::findByNameAndContent( const QString& name, const QByteArray& data,
338 mode_t mode, int* accuracy )
339{
340 KUrl url;
341 url.setPath(name);
342 QBuffer buffer(const_cast<QByteArray *>(&data));
343 return findByUrlHelper(url, mode, false, &buffer, accuracy);
344}
345
346KMimeType::Ptr KMimeType::findByNameAndContent( const QString& name, QIODevice* device,
347 mode_t mode, int* accuracy )
348{
349 KUrl url;
350 url.setPath(name);
351 return findByUrlHelper(url, mode, false, device, accuracy);
352}
353
354QString KMimeType::extractKnownExtension(const QString &fileName)
355{
356 QString pattern;
357 KMimeTypeRepository::self()->findFromFileName( fileName, &pattern );
358 return pattern;
359}
360
361KMimeType::Ptr KMimeType::findByContent( const QByteArray &data, int *accuracy )
362{
363 QBuffer buffer(const_cast<QByteArray *>(&data));
364 buffer.open(QIODevice::ReadOnly);
365 QByteArray cache;
366 return KMimeTypeRepository::self()->findFromContent(&buffer, accuracy, cache);
367}
368
369KMimeType::Ptr KMimeType::findByContent( QIODevice* device, int* accuracy )
370{
371 QByteArray cache;
372 return KMimeTypeRepository::self()->findFromContent(device, accuracy, cache);
373}
374
375KMimeType::Ptr KMimeType::findByFileContent( const QString &fileName, int *accuracy )
376{
377 checkEssentialMimeTypes();
378
379 QFile device(fileName);
380 // Look at mode first
381 KMimeType::Ptr mimeFromMode = findFromMode( fileName, 0, true );
382 if (mimeFromMode) {
383 if (accuracy)
384 *accuracy = 100;
385 return mimeFromMode;
386 }
387 if (!device.open(QIODevice::ReadOnly)) {
388 if (accuracy)
389 *accuracy = 0;
390 return KMimeType::defaultMimeTypePtr();
391 }
392
393 QByteArray cache;
394 return KMimeTypeRepository::self()->findFromContent(&device, accuracy, cache);
395}
396
397bool KMimeType::isBinaryData( const QString &fileName )
398{
399 QFile file(fileName);
400 if (!file.open(QIODevice::ReadOnly))
401 return false; // err, whatever
402 const QByteArray data = file.read(32);
403 return isBufferBinaryData(data);
404}
405
406KMimeType::KMimeType( KMimeTypePrivate &dd, const QString& name,
407 const QString& comment )
408 : KServiceType( dd, name, comment )
409{
410}
411
412KMimeType::KMimeType( const QString & fullpath, const QString& name,
413 const QString& comment )
414 : KServiceType( *new KMimeTypePrivate(fullpath), name, comment )
415{
416}
417
418KMimeType::KMimeType( KMimeTypePrivate &dd)
419 : KServiceType(dd)
420{
421}
422
423KMimeType::KMimeType( QDataStream& _str, int offset )
424 : KServiceType( *new KMimeTypePrivate(_str, offset ))
425{
426}
427
428void KMimeTypePrivate::save( QDataStream& _str )
429{
430 KServiceTypePrivate::save( _str );
431 // Warning adding fields here involves a binary incompatible change - update version
432 // number in ksycoca.h. Never remove fields.
433 _str << m_lstPatterns << QString() << QStringList() << m_iconName;
434}
435
436QVariant KMimeTypePrivate::property( const QString& _name ) const
437{
438 if ( _name == QLatin1String("Patterns") )
439 return patterns();
440 if ( _name == QLatin1String("Comment") )
441 return comment();
442 if ( _name == QLatin1String("Icon") )
443 return QVariant( iconName(KUrl()) );
444
445 return KServiceTypePrivate::property( _name );
446}
447
448QStringList KMimeTypePrivate::propertyNames() const
449{
450 QStringList res = KServiceTypePrivate::propertyNames();
451 res.append( QString::fromLatin1("Patterns") );
452 res.append( QString::fromLatin1("Icon") );
453 return res;
454}
455
456KMimeType::~KMimeType()
457{
458}
459
460QString KMimeType::iconNameForUrl( const KUrl & _url, mode_t mode )
461{
462 const KMimeType::Ptr mt = findByUrl( _url, mode, _url.isLocalFile(),
463 false /*HACK*/);
464 if (!mt) {
465 return QString();
466 }
467 static const QString& unknown = KGlobal::staticQString("unknown");
468 const QString mimeTypeIcon = mt->iconName( _url );
469 QString i = mimeTypeIcon;
470
471 // if we don't find an icon, maybe we can use the one for the protocol
472 if ( i == unknown || i.isEmpty() || mt->name() == defaultMimeType()
473 // and for the root of the protocol (e.g. trash:/) the protocol icon has priority over the mimetype icon
474 || _url.path().length() <= 1 )
475 {
476 i = favIconForUrl( _url ); // maybe there is a favicon?
477
478 if ( i.isEmpty() )
479 i = KProtocolInfo::icon( _url.protocol() );
480
481 // root of protocol: if we found nothing, revert to mimeTypeIcon (which is usually "folder")
482 if ( _url.path().length() <= 1 && ( i == unknown || i.isEmpty() ) )
483 i = mimeTypeIcon;
484 }
485 return !i.isEmpty() ? i : unknown;
486}
487
488QString KMimeType::favIconForUrl( const KUrl& url )
489{
490 /* The kded module also caches favicons, for one week, without any way
491 * to clean up the cache meanwhile.
492 * On the other hand, this QHash will get cleaned up after 5000 request
493 * (a selection in konsole of 80 chars generates around 500 requests)
494 * or by simply restarting the application (or the whole desktop,
495 * more likely, for the case of konqueror or konsole).
496 */
497 static QHash<QUrl, QString> iconNameCache;
498 static int autoClearCache = 0;
499 const QString notFound = QLatin1String("NOTFOUND");
500
501 if (url.isLocalFile()
502 || !url.protocol().startsWith(QLatin1String("http"))
503 || !KMimeTypeRepository::self()->useFavIcons())
504 return QString();
505
506 QString iconNameFromCache = iconNameCache.value(url, notFound);
507 if ( iconNameFromCache != notFound ) {
508 if ( (++autoClearCache) < 5000 ) {
509 return iconNameFromCache;
510 }
511 else {
512 iconNameCache.clear();
513 autoClearCache = 0;
514 }
515 }
516
517 QDBusInterface kded( QString::fromLatin1("org.kde.kded"),
518 QString::fromLatin1("/modules/favicons"),
519 QString::fromLatin1("org.kde.FavIcon") );
520 QDBusReply<QString> result = kded.call( QString::fromLatin1("iconForUrl"), url.url() );
521 iconNameCache.insert(url, result.value());
522 return result; // default is QString()
523}
524
525QString KMimeType::comment( const KUrl &url) const
526{
527 Q_D(const KMimeType);
528 return d->comment(url);
529}
530
531#ifndef KDE_NO_DEPRECATED
532QString KMimeType::parentMimeType() const
533{
534 const QStringList parents = parentMimeTypes();
535 if (!parents.isEmpty())
536 return parents.first();
537 return QString();
538}
539#endif
540
541bool KMimeTypePrivate::inherits(const QString& mime) const
542{
543 QStack<QString> toCheck;
544 toCheck.push(m_strName);
545 while (!toCheck.isEmpty()) {
546 const QString current = toCheck.pop();
547 if (current == mime)
548 return true;
549 Q_FOREACH(const QString& parent, KMimeTypeRepository::self()->parents(current)) {
550 toCheck.push(parent);
551 }
552 }
553 return false;
554}
555
556bool KMimeType::is( const QString& mimeTypeName ) const
557{
558 Q_D(const KMimeType);
559 if (name() == mimeTypeName)
560 return true;
561 const QString mime = KMimeTypeRepository::self()->canonicalName(mimeTypeName);
562 return d->inherits(mime);
563}
564
565QStringList KMimeType::parentMimeTypes() const
566{
567 Q_D(const KMimeType);
568 return KMimeTypeRepository::self()->parents(d->m_strName);
569}
570
571static void collectParentMimeTypes(const QString& mime, QStringList& allParents)
572{
573 QStringList parents = KMimeTypeRepository::self()->parents(mime);
574 Q_FOREACH(const QString& parent, parents) {
575 // I would use QSet, but since order matters I better not
576 if (!allParents.contains(parent))
577 allParents.append(parent);
578 }
579 // We want a breadth-first search, so that the least-specific parent (octet-stream) is last
580 // This means iterating twice, unfortunately.
581 Q_FOREACH(const QString& parent, parents) {
582 collectParentMimeTypes(parent, allParents);
583 }
584}
585
586QStringList KMimeType::allParentMimeTypes() const
587{
588 Q_D(const KMimeType);
589 QStringList allParents;
590 const QString canonical = KMimeTypeRepository::self()->resolveAlias(name());
591 if (!canonical.isEmpty())
592 allParents.append(canonical);
593 collectParentMimeTypes(d->m_strName, allParents);
594 return allParents;
595}
596
597QString KMimeType::defaultMimeType()
598{
599 static const QString & s_strDefaultMimeType =
600 KGlobal::staticQString( "application/octet-stream" );
601 return s_strDefaultMimeType;
602}
603
604QString KMimeType::iconName( const KUrl& url) const
605{
606 Q_D(const KMimeType);
607 return d->iconName(url);
608}
609
610QStringList KMimeType::patterns() const
611{
612 Q_D(const KMimeType);
613 return d->patterns();
614}
615
616// loads comment, icon, mainPattern, m_lstPatterns
617void KMimeTypePrivate::ensureXmlDataLoaded() const
618{
619 if (m_xmlDataLoaded)
620 return;
621
622 m_xmlDataLoaded = true;
623
624 const QString file = m_strName + QLatin1String(".xml");
625 const QStringList mimeFiles = KGlobal::dirs()->findAllResources("xdgdata-mime", file);
626 if (mimeFiles.isEmpty()) {
627 kWarning() << "No file found for" << file << ", even though the file appeared in a directory listing.";
628 kWarning() << "Either it was just removed, or the directory doesn't have executable permission...";
629 kWarning() << KGlobal::dirs()->resourceDirs("xdgdata-mime");
630 return;
631 }
632
633 QString comment;
634 QString mainPattern;
635 const QStringList languageList = KGlobal::locale()->languageList();
636 QString preferredLanguage = languageList.first();
637 QMap<QString, QString> commentsByLanguage;
638
639 QListIterator<QString> mimeFilesIter(mimeFiles);
640 mimeFilesIter.toBack();
641 while (mimeFilesIter.hasPrevious()) { // global first, then local.
642 const QString fullPath = mimeFilesIter.previous();
643 QFile qfile(fullPath);
644 if (!qfile.open(QFile::ReadOnly))
645 continue;
646
647 QXmlStreamReader xml(&qfile);
648 if (xml.readNextStartElement()) {
649 if (xml.name() != "mime-type") {
650 continue;
651 }
652 const QString name = xml.attributes().value(QLatin1String("type")).toString();
653 if (name.isEmpty())
654 continue;
655 if (name != m_strName) {
656 kWarning() << "Got name" << name << "in file" << file << "expected" << m_strName;
657 }
658
659 while (xml.readNextStartElement()) {
660 const QStringRef tag = xml.name();
661 if (tag == "comment") {
662 QString lang = xml.attributes().value(QLatin1String("xml:lang")).toString();
663 const QString text = xml.readElementText();
664 if (lang.isEmpty()) {
665 lang = QLatin1String("en_US");
666 }
667 if (lang == preferredLanguage) {
668 comment = text;
669 } else {
670 commentsByLanguage.insert(lang, text);
671 }
672 continue; // we called readElementText, so we're at the EndElement already.
673 } else if (tag == "icon") { // as written out by shared-mime-info >= 0.40
674 m_iconName = xml.attributes().value(QLatin1String("name")).toString();
675 } else if (tag == "glob-deleteall") { // as written out by shared-mime-info >= 0.70
676 mainPattern.clear();
677 m_lstPatterns.clear();
678 } else if (tag == "glob") { // as written out by shared-mime-info >= 0.70
679 const QString pattern = xml.attributes().value(QLatin1String("pattern")).toString();
680 if (mainPattern.isEmpty() && pattern.startsWith(QLatin1Char('*'))) {
681 mainPattern = pattern;
682 }
683 if (!m_lstPatterns.contains(pattern))
684 m_lstPatterns.append(pattern);
685 }
686 xml.skipCurrentElement();
687 }
688 if (xml.name() != "mime-type") {
689 kFatal() << "Programming error in KMimeType XML loading, please create a bug report on http://bugs.kde.org and attach the file" << fullPath;
690 }
691 }
692 }
693
694 if (comment.isEmpty()) {
695 Q_FOREACH(const QString& lang, languageList) {
696 const QString comm = commentsByLanguage.value(lang);
697 if (!comm.isEmpty()) {
698 comment = comm;
699 break;
700 }
701 const int pos = lang.indexOf(QLatin1Char('_'));
702 if (pos != -1) {
703 // "pt_BR" not found? try just "pt"
704 const QString shortLang = lang.left(pos);
705 const QString comm = commentsByLanguage.value(shortLang);
706 if (!comm.isEmpty()) {
707 comment = comm;
708 break;
709 }
710 }
711 }
712 if (comment.isEmpty()) {
713 kWarning() << "Missing <comment> field in" << file;
714 }
715 }
716 m_strComment = comment;
717
718 const bool globsInXml = (KMimeType::sharedMimeInfoVersion() >= KDE_MAKE_VERSION(0, 70, 0));
719 if (globsInXml) {
720 if (!mainPattern.isEmpty() && m_lstPatterns.first() != mainPattern) {
721 // ensure it's first in the list of patterns
722 m_lstPatterns.removeAll(mainPattern);
723 m_lstPatterns.prepend(mainPattern);
724 }
725 } else {
726 // Fallback: get the patterns from the globs file
727 m_lstPatterns = KMimeTypeRepository::self()->patternsForMimetype(m_strName);
728 }
729}
730
731QString KMimeType::userSpecifiedIconName() const
732{
733 Q_D(const KMimeType);
734 d->ensureXmlDataLoaded();
735 return d->m_iconName;
736}
737
738int KMimeType::sharedMimeInfoVersion()
739{
740 return KMimeTypeRepository::self()->sharedMimeInfoVersion();
741}
742
743QString KMimeType::mainExtension() const
744{
745 Q_D(const KMimeType);
746
747#if 1 // HACK START - can be removed once shared-mime-info >= 0.70 is used/required.
748 // The idea was: first usable pattern from m_lstPatterns.
749 // But update-mime-database makes a mess of the order of the patterns,
750 // because it uses a hash internally.
751 static const struct { const char* mime; const char* extension; } s_hardcodedMimes[] = {
752 { "text/plain", ".txt" } };
753 if (d->m_lstPatterns.count() > 1) {
754 const QByteArray me = name().toLatin1();
755 for (uint i = 0; i < sizeof(s_hardcodedMimes)/sizeof(*s_hardcodedMimes); ++i) {
756 if (me == s_hardcodedMimes[i].mime)
757 return QString::fromLatin1(s_hardcodedMimes[i].extension);
758 }
759 }
760#endif // HACK END
761
762 Q_FOREACH(const QString& pattern, patterns()) {
763 // Skip if if looks like: README or *. or *.*
764 // or *.JP*G or *.JP?
765 if (pattern.startsWith(QLatin1String("*.")) &&
766 pattern.length() > 2 &&
767 pattern.indexOf(QLatin1Char('*'), 2) < 0 && pattern.indexOf(QLatin1Char('?'), 2) < 0) {
768 return pattern.mid(1);
769 }
770 }
771 // TODO we should also look into the parent mimetype's patterns, no?
772 return QString();
773}
774
775bool KMimeType::matchFileName( const QString &filename, const QString &pattern )
776{
777 return KMimeTypeRepository::matchFileName( filename, pattern );
778}
779
780int KMimeTypePrivate::serviceOffersOffset() const
781{
782 return KMimeTypeFactory::self()->serviceOffersOffset(name());
783}
784
785QString KMimeTypePrivate::iconName(const KUrl &) const
786{
787 static QHash<QUrl, QString> iconNameCache;
788 QString iconNameFromCache = iconNameCache.value(m_strName);
789 if (!iconNameFromCache.isEmpty())
790 return iconNameFromCache;
791
792 ensureXmlDataLoaded();
793 QString result;
794 if (!m_iconName.isEmpty()) {
795 result = m_iconName;
796 } else {
797 // Make default icon name from the mimetype name
798 // Don't store this in m_iconName, it would make the filetype editor
799 // write out icon names in every local mimetype definition file.
800 QString icon = m_strName;
801 const int slashindex = icon.indexOf(QLatin1Char('/'));
802 if (slashindex != -1) {
803 icon[slashindex] = QLatin1Char('-');
804 }
805 result = icon;
806 }
807 iconNameCache.insert(m_strName, result);
808 return result;
809}
KLocale::languageList
QStringList languageList() const
Returns the language codes selected by user, ordered by decreasing priority.
Definition: klocale.cpp:439
KMimeTypeFactory::self
static KMimeTypeFactory * self()
Definition: kmimetypefactory.cpp:41
KMimeTypeFactory::serviceOffersOffset
int serviceOffersOffset(const QString &mimeTypeName)
Returns the offset into the service offers for a given mimetype.
Definition: kmimetypefactory.cpp:55
KMimeTypePrivate
Definition: kmimetype_p.h:25
KMimeTypePrivate::iconName
virtual QString iconName(const KUrl &) const
Definition: kmimetype.cpp:785
KMimeTypePrivate::m_lstPatterns
QStringList m_lstPatterns
Definition: kmimetype_p.h:61
KMimeTypePrivate::property
virtual QVariant property(const QString &name) const
Definition: kmimetype.cpp:436
KMimeTypePrivate::comment
virtual QString comment(const KUrl &=KUrl()) const
Definition: kmimetype_p.h:42
KMimeTypePrivate::inherits
bool inherits(const QString &mime) const
Definition: kmimetype.cpp:541
KMimeTypePrivate::ensureXmlDataLoaded
void ensureXmlDataLoaded() const
Definition: kmimetype.cpp:617
KMimeTypePrivate::patterns
QStringList patterns() const
Definition: kmimetype_p.h:48
KMimeTypePrivate::serviceOffersOffset
virtual int serviceOffersOffset() const
Definition: kmimetype.cpp:780
KMimeTypePrivate::m_xmlDataLoaded
bool m_xmlDataLoaded
Definition: kmimetype_p.h:63
KMimeTypePrivate::save
virtual void save(QDataStream &s)
Definition: kmimetype.cpp:428
KMimeTypePrivate::propertyNames
virtual QStringList propertyNames() const
Definition: kmimetype.cpp:448
KMimeTypePrivate::m_iconName
QString m_iconName
Definition: kmimetype_p.h:62
KMimeTypeRepository::parents
QStringList parents(const QString &mime)
Returns the list of parents for a given mimetype.
Definition: kmimetyperepository.cpp:294
KMimeTypeRepository::sharedMimeInfoVersion
int sharedMimeInfoVersion()
Definition: kmimetyperepository.cpp:783
KMimeTypeRepository::resolveAlias
QString resolveAlias(const QString &mime)
Check if mime is an alias, and return the canonical name for it if it is, otherwise empty.
Definition: kmimetyperepository.cpp:85
KMimeTypeRepository::findMimeTypeByName
KMimeType::Ptr findMimeTypeByName(const QString &_name, KMimeType::FindByNameOption options=KMimeType::DontResolveAlias)
Creates a KMimeType.
Definition: kmimetyperepository.cpp:59
KMimeTypeRepository::patternsForMimetype
QStringList patternsForMimetype(const QString &mimeType)
Return the patterns (globs) for a given mimetype TEMPORARY method, it will go away once we can requir...
Definition: kmimetyperepository.cpp:599
KMimeTypeRepository::checkEssentialMimeTypes
void checkEssentialMimeTypes()
This function makes sure that vital mime types are installed.
Definition: kmimetyperepository.cpp:616
KMimeTypeRepository::matchFileName
static bool matchFileName(const QString &filename, const QString &pattern)
Definition: kmimetyperepository.cpp:98
KMimeTypeRepository::canonicalName
QString canonicalName(const QString &mime)
Resolve mime if it's an alias, and return it otherwise.
Definition: kmimetyperepository.cpp:90
KMimeTypeRepository::defaultMimeTypePtr
KMimeType::Ptr defaultMimeTypePtr()
Definition: kmimetyperepository.cpp:662
KMimeTypeRepository::self
static KMimeTypeRepository * self()
Definition: kmimetyperepository.cpp:35
KMimeType
Represent a mime type, like "text/plain", and the data that is associated with it.
Definition: kmimetype.h:47
KMimeType::parentMimeTypes
QStringList parentMimeTypes() const
If this mimetype is a subclass of one or more other mimetypes, return the list of those mimetypes.
Definition: kmimetype.cpp:565
KMimeType::findByContent
static Ptr findByContent(const QByteArray &data, int *accuracy=0)
Tries to find out the MIME type of a data chunk by looking for certain magic numbers and characterist...
Definition: kmimetype.cpp:361
KMimeType::userSpecifiedIconName
QString userSpecifiedIconName() const
Returns the user-specified icon for this mimetype.
Definition: kmimetype.cpp:731
KMimeType::is
bool is(const QString &mimeTypeName) const
Do not use name()=="somename" anymore, to check for a given mimetype.
Definition: kmimetype.cpp:556
KMimeType::isBufferBinaryData
static bool isBufferBinaryData(const QByteArray &data)
Returns whether a buffer has an internal format that is not human readable.
Definition: kmimetype.cpp:74
KMimeType::favIconForUrl
static QString favIconForUrl(const KUrl &url)
Return the "favicon" (see http://www.favicon.com) for the given url, if available.
Definition: kmimetype.cpp:488
KMimeType::FindByNameOption
FindByNameOption
Definition: kmimetype.h:105
KMimeType::sharedMimeInfoVersion
static int sharedMimeInfoVersion()
Returns the version of the installed update-mime-database program (from freedesktop....
Definition: kmimetype.cpp:738
KMimeType::defaultMimeType
static QString defaultMimeType()
Returns the name of the default mimetype.
Definition: kmimetype.cpp:597
KMimeType::isDefault
bool isDefault() const
Return true if this mimetype is the default mimetype.
Definition: kmimetype.cpp:48
KMimeType::findByNameAndContent
static Ptr findByNameAndContent(const QString &name, const QByteArray &data, mode_t mode=0, int *accuracy=0)
Tries to find out the MIME type of filename/url and a data chunk.
Definition: kmimetype.cpp:337
KMimeType::iconNameForUrl
static QString iconNameForUrl(const KUrl &url, mode_t mode=0)
Return the filename of the icon associated with the mimetype, for a given url.
Definition: kmimetype.cpp:460
KMimeType::findByFileContent
static Ptr findByFileContent(const QString &fileName, int *accuracy=0)
Tries to find out the MIME type of a file by looking for certain magic numbers and characteristic str...
Definition: kmimetype.cpp:375
KMimeType::mimeType
static Ptr mimeType(const QString &name, FindByNameOption options=ResolveAliases)
Retrieve a pointer to the mime type name.
Definition: kmimetype.cpp:58
KMimeType::Ptr
KSharedPtr< KMimeType > Ptr
Definition: kmimetype.h:50
KMimeType::matchFileName
static bool matchFileName(const QString &filename, const QString &pattern)
Returns true if the given filename matches the given pattern.
Definition: kmimetype.cpp:775
KMimeType::parentMimeType
QString parentMimeType() const
If this mimetype is a subclass of another mimetype, return the name of the parent.
Definition: kmimetype.cpp:532
KMimeType::findByPath
static Ptr findByPath(const QString &path, mode_t mode=0, bool fast_mode=false, int *accuracy=0)
Finds a KMimeType with the given url.
Definition: kmimetype.cpp:329
KMimeType::~KMimeType
virtual ~KMimeType()
Definition: kmimetype.cpp:456
KMimeType::extractKnownExtension
static QString extractKnownExtension(const QString &fileName)
Determines the extension from a filename (or full path) using the mimetype database.
Definition: kmimetype.cpp:354
KMimeType::patterns
QStringList patterns() const
Retrieve the list of patterns associated with the MIME Type.
Definition: kmimetype.cpp:610
KMimeType::allMimeTypes
static List allMimeTypes()
Get all the mimetypes.
Definition: kmimetype.cpp:63
KMimeType::findByUrl
static Ptr findByUrl(const KUrl &url, mode_t mode=0, bool is_local_file=false, bool fast_mode=false, int *accuracy=0)
Finds a KMimeType with the given url.
Definition: kmimetype.cpp:316
KMimeType::allParentMimeTypes
QStringList allParentMimeTypes() const
Return all parent mimetypes of this mimetype, direct or indirect.
Definition: kmimetype.cpp:586
KMimeType::defaultMimeTypePtr
static KMimeType::Ptr defaultMimeTypePtr()
Returns the default mimetype.
Definition: kmimetype.cpp:43
KMimeType::mainExtension
QString mainExtension() const
Return the primary extension associated with this mimetype, if any.
Definition: kmimetype.cpp:743
KMimeType::KMimeType
KMimeType(QDataStream &str, int offset)
Definition: kmimetype.cpp:423
KMimeType::iconName
QString iconName(const KUrl &url=KUrl()) const
Return the filename of the icon associated with the mimetype.
Definition: kmimetype.cpp:604
KMimeType::isBinaryData
static bool isBinaryData(const QString &fileName)
Returns whether a file has an internal format that is not human readable.
Definition: kmimetype.cpp:397
KProtocolInfoFactory::self
static KProtocolInfoFactory * self()
The instance of the KProtocolInfoFactory.
Definition: kprotocolinfofactory.cpp:119
KProtocolInfoFactory::findProtocol
KProtocolInfo::Ptr findProtocol(const QString &protocol)
Definition: kprotocolinfofactory.cpp:91
KProtocolInfo::determineMimetypeFromExtension
static bool determineMimetypeFromExtension(const QString &protocol)
Returns whether mimetypes can be determined based on extension for this protocol.
Definition: kprotocolinfo.cpp:328
KProtocolInfo::icon
static QString icon(const QString &protocol)
Returns the name of the icon, associated with the specified protocol.
Definition: kprotocolinfo.cpp:287
KServiceTypePrivate::propertyNames
virtual QStringList propertyNames() const
Definition: kservicetype.cpp:169
KServiceTypePrivate::save
virtual void save(QDataStream &)
Definition: kservicetype.cpp:117
KServiceTypePrivate::m_strName
QString m_strName
Definition: kservicetype_p.h:69
KServiceTypePrivate::property
virtual QVariant property(const QString &name) const
Definition: kservicetype.cpp:154
KServiceTypePrivate::name
virtual QString name() const
Definition: kservicetype_p.h:49
KServiceTypePrivate::m_strComment
QString m_strComment
Definition: kservicetype_p.h:70
KServiceType
A service type is, well, a type of service, where a service is an application or plugin.
Definition: kservicetype.h:44
KServiceType::comment
QString comment() const
Returns the descriptive comment associated, if any.
Definition: kservicetype.cpp:232
KSharedPtr
Can be used to control the lifetime of an object that has derived QSharedData.
Definition: ksharedptr.h:64
KStandardDirs::findAllResources
QStringList findAllResources(const char *type, const QString &filter=QString(), SearchOptions options=NoSearchOptions) const
Tries to find all resources with the specified type.
Definition: kstandarddirs.cpp:900
KStandardDirs::resourceDirs
QStringList resourceDirs(const char *type) const
This function is used internally by almost all other function as it serves and fills the directories ...
Definition: kstandarddirs.cpp:1069
KSycocaEntry::name
QString name() const
Definition: ksycocaentry.cpp:157
KUrl
Represents and parses a URL.
Definition: kurl.h:112
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
Returns the URL as string, with all escape sequences intact, encoded in a given charset.
Definition: kurl.cpp:1035
KUrl::path
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
Definition: kurl.cpp:873
KUrl::isLocalFile
bool isLocalFile() const
Checks whether the file is local.
Definition: kurl.cpp:924
KUrl::setPath
void setPath(const QString &path)
Definition: kurl.cpp:1772
KUrl::fileName
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
Returns the filename of the path.
Definition: kurl.cpp:1283
KUrl::protocol
QString protocol() const
Returns the protocol for the URL (i.e., file, http, etc.), lowercased.
Definition: kurl.cpp:672
KUrl::hasSubUrl
bool hasSubUrl() const
Checks whether the URL has any sub URLs.
Definition: kurl.cpp:1030
KUrl::toLocalFile
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
Definition: kurl.cpp:885
QHash
Definition: ksycocafactory.h:28
QIODevice
QList< Ptr >
QMap
QStringList
QString
QVariant
kFatal
static QDebug kFatal(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
Definition: kdebug.h:198
kWarning
#define kWarning
Definition: kdebug.h:322
kdebug.h
klocale.h
servicesDebugArea
int servicesDebugArea()
Definition: kservice.cpp:47
findFromMode
static KMimeType::Ptr findFromMode(const QString &path, mode_t mode, bool is_local_file)
Definition: kmimetype.cpp:86
collectParentMimeTypes
static void collectParentMimeTypes(const QString &mime, QStringList &allParents)
Definition: kmimetype.cpp:571
kmimetype.h
kmimetype_p.h
kmimetypefactory.h
kmimetyperepository_p.h
kprotocolinfo.h
kprotocolinfofactory.h
kstandarddirs.h
kurl.h
KDE::stat
int stat(const QString &path, KDE_struct_stat *buf)
Definition: kde_file_win.cpp:175
KDE::access
int access(const QString &path, int mode)
Definition: kde_file_win.cpp:123
KGlobal::staticQString
const QString & staticQString(const char *str)
Creates a static QString.
Definition: kglobal.cpp:271
KGlobal::dirs
KStandardDirs * dirs()
Returns the application standard dirs object.
KGlobal::locale
KLocale * locale()
Returns the global locale object.
Definition: kglobal.cpp:170
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal