27 #include <kdeversion.h>
34 #include <QtCore/QFile>
35 #include <QtDBus/QtDBus>
52 void KMimeType::checkEssentialMimeTypes()
67 if (!mimeType.startsWith(QLatin1String(
"x-scheme-handler")))
76 const char* p = data.data();
77 const int end = qMin(32, data.size());
78 for (
int i = 0; i < end; ++i) {
79 if ((
unsigned char)(p[i]) < 32 && p[i] != 9 && p[i] != 10 && p[i] != 13)
89 if ( is_local_file && (mode == 0 || mode == (mode_t)-1) ) {
95 if ( S_ISDIR( mode ) ) {
108 if ( S_ISCHR( mode ) )
110 if ( S_ISBLK( mode ) )
112 if ( S_ISFIFO( mode ) )
114 if ( S_ISSOCK( mode ) )
118 int size = path.size();
119 if ( size == 2 || size == 3 ) {
122 unsigned int type = GetDriveTypeW( (LPCWSTR) path.utf16() );
124 case DRIVE_REMOVABLE:
143 if ( !is_local_file && S_ISREG( mode ) && ( mode & ( S_IXUSR | S_IXGRP | S_IXOTH ) ) )
184 checkEssentialMimeTypes();
198 if ( !fileName.isEmpty() && !path.endsWith( QLatin1Char(
'/') ) ) {
200 if ( is_local_file || _url.
hasSubUrl() ||
205 if ( mimeList.count() == 1 ) {
206 const QString selectedMime = mimeList.at(0);
211 kWarning() <<
"Glob file refers to" << selectedMime <<
"but this mimetype does not exist!";
220 if ( device && !device->isOpen() ) {
221 if ( !device->open(QIODevice::ReadOnly) ) {
227 QByteArray beginning;
234 if (mime && magicAccuracy > 0) {
237 if (magicAccuracy < 80 && !mimeList.isEmpty()) {
240 const QString sniffedMime = mime->name();
241 foreach(
const QString &m, mimeList) {
244 if (mimeFromPattern && mimeFromPattern->is(sniffedMime)) {
248 return mimeFromPattern;
254 *accuracy = magicAccuracy;
262 if (!mimeList.isEmpty()) {
267 qSort(mimeList.begin(), mimeList.end());
268 Q_FOREACH(
const QString& mimeName, mimeList) {
271 kWarning() <<
"Glob file refers to" << mimeName <<
"but this mimetype does not exist!";
285 def = prot->defaultMimeType();
292 if ( path.endsWith( QLatin1Char(
'/') ) || path.isEmpty() ) {
297 if ( def.isEmpty() ) {
300 if ( prot && prot->supportsListing() ) {
316 bool is_local_file,
bool fast_mode,
320 is_local_file =
true;
321 if (is_local_file && !fast_mode) {
323 return findByUrlHelper(url, mode, is_local_file, &file, accuracy);
325 return findByUrlHelper(url, mode, is_local_file, 0, accuracy);
329 bool fast_mode,
int* accuracy )
333 return findByUrl(url, mode,
true, fast_mode, accuracy);
337 mode_t mode,
int* accuracy )
341 QBuffer buffer(const_cast<QByteArray *>(&data));
342 return findByUrlHelper(url, mode,
false, &buffer, accuracy);
346 mode_t mode,
int* accuracy )
350 return findByUrlHelper(url, mode,
false, device, accuracy);
362 QBuffer buffer(const_cast<QByteArray *>(&data));
363 buffer.open(QIODevice::ReadOnly);
376 checkEssentialMimeTypes();
378 QFile device(fileName);
386 if (!device.open(QIODevice::ReadOnly)) {
398 QFile file(fileName);
399 if (!file.open(QIODevice::ReadOnly))
401 const QByteArray data = file.read(32);
437 if ( _name == QLatin1String(
"Patterns") )
439 if ( _name == QLatin1String(
"Icon") )
448 res.append( QString::fromLatin1(
"Patterns") );
449 res.append( QString::fromLatin1(
"Icon") );
471 || _url.
path().length() <= 1 )
479 if ( _url.
path().length() <= 1 && ( i == unknown || i.isEmpty() ) )
482 return !i.isEmpty() ? i : unknown;
488 || !url.
protocol().startsWith(QLatin1String(
"http"))
492 QDBusInterface kded( QString::fromLatin1(
"org.kde.kded"),
493 QString::fromLatin1(
"/modules/favicons"),
494 QString::fromLatin1(
"org.kde.FavIcon") );
495 QDBusReply<QString> result = kded.call( QString::fromLatin1(
"iconForUrl"), url.
url() );
502 return d->comment(url);
505 #ifndef KDE_NO_DEPRECATED
509 if (!parents.isEmpty())
510 return parents.first();
517 QStack<QString> toCheck;
519 while (!toCheck.isEmpty()) {
520 const QString current = toCheck.pop();
524 toCheck.push(parent);
533 if (
name() == mimeTypeName)
536 return d->inherits(mime);
548 Q_FOREACH(
const QString& parent, parents) {
550 if (!allParents.contains(parent))
551 allParents.append(parent);
555 Q_FOREACH(
const QString& parent, parents) {
565 if (!canonical.isEmpty())
566 allParents.append(canonical);
573 static const QString & s_strDefaultMimeType =
575 return s_strDefaultMimeType;
581 return d->iconName(url);
587 d->ensureXmlDataLoaded();
588 return d->m_lstPatterns;
601 if (mimeFiles.isEmpty()) {
602 kWarning() <<
"No file found for" << file <<
", even though the file appeared in a directory listing.";
603 kWarning() <<
"Either it was just removed, or the directory doesn't have executable permission...";
611 QString preferredLanguage = languageList.first();
614 QListIterator<QString> mimeFilesIter(mimeFiles);
615 mimeFilesIter.toBack();
616 while (mimeFilesIter.hasPrevious()) {
617 const QString fullPath = mimeFilesIter.previous();
618 QFile qfile(fullPath);
619 if (!qfile.open(QFile::ReadOnly))
622 QXmlStreamReader xml(&qfile);
623 if (xml.readNextStartElement()) {
624 if (xml.name() !=
"mime-type") {
627 const QString name = xml.attributes().value(QLatin1String(
"type")).toString();
631 kWarning() <<
"Got name" << name <<
"in file" << file <<
"expected" <<
m_strName;
634 while (xml.readNextStartElement()) {
635 const QStringRef tag = xml.name();
636 if (tag ==
"comment") {
637 QString lang = xml.attributes().value(QLatin1String(
"xml:lang")).toString();
638 const QString text = xml.readElementText();
639 if (lang.isEmpty()) {
640 lang = QLatin1String(
"en_US");
642 if (lang == preferredLanguage) {
645 commentsByLanguage.insert(lang, text);
648 }
else if (tag ==
"icon") {
649 m_iconName = xml.attributes().value(QLatin1String(
"name")).toString();
650 }
else if (tag ==
"glob-deleteall") {
653 }
else if (tag ==
"glob") {
654 const QString pattern = xml.attributes().value(QLatin1String(
"pattern")).toString();
655 if (mainPattern.isEmpty() && pattern.startsWith(QLatin1Char(
'*'))) {
656 mainPattern = pattern;
661 xml.skipCurrentElement();
663 if (xml.name() !=
"mime-type") {
664 kFatal() <<
"Programming error in KMimeType XML loading, please create a bug report on http://bugs.kde.org and attach the file" << fullPath;
669 if (comment.isEmpty()) {
670 Q_FOREACH(
const QString& lang, languageList) {
671 const QString comm = commentsByLanguage.value(lang);
672 if (!comm.isEmpty()) {
676 const int pos = lang.indexOf(QLatin1Char(
'_'));
679 const QString shortLang = lang.left(pos);
680 const QString comm = commentsByLanguage.value(shortLang);
681 if (!comm.isEmpty()) {
687 if (comment.isEmpty()) {
688 kWarning() <<
"Missing <comment> field in" << file;
695 if (!mainPattern.isEmpty() &&
m_lstPatterns.first() != mainPattern) {
709 d->ensureXmlDataLoaded();
710 return d->m_iconName;
722 #if 1 // HACK START - can be removed once shared-mime-info >= 0.70 is used/required.
726 static const struct {
const char* mime;
const char* extension; } s_hardcodedMimes[] = {
727 {
"text/plain",
".txt" } };
728 if (d->m_lstPatterns.count() > 1) {
729 const QByteArray me =
name().toLatin1();
730 for (uint i = 0; i <
sizeof(s_hardcodedMimes)/
sizeof(*s_hardcodedMimes); ++i) {
731 if (me == s_hardcodedMimes[i].mime)
732 return QString::fromLatin1(s_hardcodedMimes[i].extension);
740 if (pattern.startsWith(QLatin1String(
"*.")) &&
741 pattern.length() > 2 &&
742 pattern.indexOf(QLatin1Char(
'*'), 2) < 0 && pattern.indexOf(QLatin1Char(
'?'), 2) < 0) {
743 return pattern.mid(1);