summaryrefslogtreecommitdiffstats
path: root/src/corelib/mimetypes/qmimetype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/mimetypes/qmimetype.cpp')
-rw-r--r--src/corelib/mimetypes/qmimetype.cpp506
1 files changed, 506 insertions, 0 deletions
diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp
new file mode 100644
index 0000000000..77592880a0
--- /dev/null
+++ b/src/corelib/mimetypes/qmimetype.cpp
@@ -0,0 +1,506 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmimetype.h"
+
+#include "qmimetype_p.h"
+#include "qmimedatabase_p.h"
+#include "qmimeprovider_p.h"
+
+#include "qmimeglobpattern_p.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QLocale>
+
+QT_BEGIN_NAMESPACE
+
+bool qt_isQMimeTypeDebuggingActivated (false);
+
+#ifndef QT_NO_DEBUG_OUTPUT
+#define DBG() if (qt_isQMimeTypeDebuggingActivated) qDebug() << static_cast<const void *>(this) << Q_FUNC_INFO
+#else
+#define DBG() if (0) qDebug() << static_cast<const void *>(this) << Q_FUNC_INFO
+#endif
+
+QMimeTypePrivate::QMimeTypePrivate()
+ : name()
+ //, comment()
+ , localeComments()
+ , genericIconName()
+ , iconName()
+ , globPatterns()
+{}
+
+QMimeTypePrivate::QMimeTypePrivate(const QMimeType &other)
+ : name(other.d->name)
+ //, comment(other.d->comment)
+ , localeComments(other.d->localeComments)
+ , genericIconName(other.d->genericIconName)
+ , iconName(other.d->iconName)
+ , globPatterns(other.d->globPatterns)
+{}
+
+void QMimeTypePrivate::clear()
+{
+ name.clear();
+ //comment.clear();
+ localeComments.clear();
+ genericIconName.clear();
+ iconName.clear();
+ globPatterns.clear();
+}
+
+/*!
+ \fn bool QMimeTypePrivate::operator==(const QMimeTypePrivate &other) const;
+ Returns true if \a other equals this QMimeTypePrivate object, otherwise returns false.
+ */
+bool QMimeTypePrivate::operator==(const QMimeTypePrivate &other) const
+{
+ DBG();
+ if (name == other.name &&
+ //comment == other.comment &&
+ localeComments == other.localeComments &&
+ genericIconName == other.genericIconName &&
+ iconName == other.iconName &&
+ globPatterns == other.globPatterns) {
+ return true;
+ }
+
+ DBG() << name << other.name << (name == other.name);
+ //DBG() << comment << other.comment << (comment == other.comment);
+ DBG() << localeComments << other.localeComments << (localeComments == other.localeComments);
+ DBG() << genericIconName << other.genericIconName << (genericIconName == other.genericIconName);
+ DBG() << iconName << other.iconName << (iconName == other.iconName);
+ DBG() << globPatterns << other.globPatterns << (globPatterns == other.globPatterns);
+ return false;
+}
+
+void QMimeTypePrivate::addGlobPattern(const QString &pattern)
+{
+ globPatterns.append(pattern);
+}
+
+/*!
+ \class QMimeType
+ \brief The QMimeType class describes types of file or data, represented by a MIME type string.
+
+ \since 5.0
+
+ For instance a file named "readme.txt" has the MIME type "text/plain".
+ The MIME type can be determined from the file name, or from the file
+ contents, or from both. MIME type determination can also be done on
+ buffers of data not coming from files.
+
+ Determining the MIME type of a file can be useful to make sure your
+ application supports it. It is also useful in file-manager-like applications
+ or widgets, in order to display an appropriate icon() for the file, or even
+ the descriptive comment() in detailed views.
+
+ To check if a file has the expected MIME type, you should use inherits()
+ rather than a simple string comparison based on the name(). This is because
+ MIME types can inherit from each other: for instance a C source file is
+ a specific type of plain text file, so text/x-csrc inherits text/plain.
+
+ \sa QMimeDatabase
+ */
+
+/*!
+ \fn QMimeType::QMimeType();
+ Constructs this QMimeType object initialized with default property values that indicate an invalid MIME type.
+ */
+QMimeType::QMimeType() :
+ d(new QMimeTypePrivate())
+{
+ DBG() << "name():" << name();
+ //DBG() << "aliases():" << aliases();
+ //DBG() << "comment():" << comment();
+ DBG() << "genericIconName():" << genericIconName();
+ DBG() << "iconName():" << iconName();
+ DBG() << "globPatterns():" << globPatterns();
+ DBG() << "suffixes():" << suffixes();
+ DBG() << "preferredSuffix():" << preferredSuffix();
+}
+
+/*!
+ \fn QMimeType::QMimeType(const QMimeType &other);
+ Constructs this QMimeType object as a copy of \a other.
+ */
+QMimeType::QMimeType(const QMimeType &other) :
+ d(other.d)
+{
+ DBG() << "name():" << name();
+ //DBG() << "aliases():" << aliases();
+ //DBG() << "comment():" << comment();
+ DBG() << "genericIconName():" << genericIconName();
+ DBG() << "iconName():" << iconName();
+ DBG() << "globPatterns():" << globPatterns();
+ DBG() << "suffixes():" << suffixes();
+ DBG() << "preferredSuffix():" << preferredSuffix();
+}
+
+/*!
+ \fn QMimeType &QMimeType::operator=(const QMimeType &other);
+ Assigns the data of \a other to this QMimeType object, and returns a reference to this object.
+ */
+QMimeType &QMimeType::operator=(const QMimeType &other)
+{
+ if (d != other.d)
+ d = other.d;
+ return *this;
+}
+
+#ifdef Q_COMPILER_RVALUE_REFS
+/*!
+ \fn QMimeType::QMimeType(QMimeType &&other);
+ Constructs this QMimeType object by moving the data of the rvalue reference \a other.
+ */
+QMimeType::QMimeType(QMimeType &&other) :
+ d(std::move(other.d))
+{
+ DBG() << "name():" << name();
+ //DBG() << "aliases():" << aliases();
+ //DBG() << "comment():" << comment();
+ DBG() << "genericIconName():" << genericIconName();
+ DBG() << "iconName():" << iconName();
+ DBG() << "globPatterns():" << globPatterns();
+ DBG() << "suffixes():" << suffixes();
+ DBG() << "preferredSuffix():" << preferredSuffix();
+}
+#endif
+
+/*!
+ \fn QMimeType::QMimeType(const QMimeTypePrivate &dd);
+ Assigns the data of the QMimeTypePrivate \a dd to this QMimeType object, and returns a reference to this object.
+ */
+QMimeType::QMimeType(const QMimeTypePrivate &dd) :
+ d(new QMimeTypePrivate(dd))
+{
+ DBG() << "name():" << name();
+ //DBG() << "aliases():" << aliases();
+ //DBG() << "comment():" << comment();
+ DBG() << "genericIconName():" << genericIconName();
+ DBG() << "iconName():" << iconName();
+ DBG() << "globPatterns():" << globPatterns();
+ DBG() << "suffixes():" << suffixes();
+ DBG() << "preferredSuffix():" << preferredSuffix();
+}
+
+/*!
+ \fn void QMimeType::swap(QMimeType &other);
+ Swaps QMimeType \a other with this QMimeType object.
+
+ This operation is very fast and never fails.
+
+ The swap() method helps with the implementation of assignment
+ operators in an exception-safe way. For more information consult
+ \l {http://en.wikibooks.org/wiki/More_C++_Idioms/Copy-and-swap}
+ {More C++ Idioms - Copy-and-swap}.
+ */
+
+/*!
+ \fn QMimeType::~QMimeType();
+ Destroys the QMimeType object, and releases the d pointer.
+ */
+QMimeType::~QMimeType()
+{
+ DBG() << "name():" << name();
+ //DBG() << "aliases():" << aliases();
+ //DBG() << "comment():" << comment();
+ DBG() << "genericIconName():" << genericIconName();
+ DBG() << "iconName():" << iconName();
+ DBG() << "globPatterns():" << globPatterns();
+ DBG() << "suffixes():" << suffixes();
+ DBG() << "preferredSuffix():" << preferredSuffix();
+}
+
+/*!
+ \fn bool QMimeType::operator==(const QMimeType &other) const;
+ Returns true if \a other equals this QMimeType object, otherwise returns false.
+ */
+bool QMimeType::operator==(const QMimeType &other) const
+{
+ return d == other.d || *d == *other.d;
+}
+
+/*!
+ \fn bool QMimeType::operator!=(const QMimeType &other) const;
+ Returns true if \a other does not equal this QMimeType object, otherwise returns false.
+ */
+
+/*!
+ \fn bool QMimeType::isValid() const;
+ Returns true if the QMimeType object contains valid data, otherwise returns false.
+ A valid MIME type has a non-empty name().
+ The invalid MIME type is the default-constructed QMimeType.
+ */
+bool QMimeType::isValid() const
+{
+ return !d->name.isEmpty();
+}
+
+/*!
+ \fn bool QMimeType::isDefault() const;
+ Returns true if this MIME type is the default MIME type which
+ applies to all files: application/octet-stream.
+ */
+bool QMimeType::isDefault() const
+{
+ return d->name == QMimeDatabasePrivate::instance()->defaultMimeType();
+}
+
+/*!
+ \fn QString QMimeType::name() const;
+ Returns the name of the MIME type.
+ */
+QString QMimeType::name() const
+{
+ return d->name;
+}
+
+/*!
+ Returns the description of the MIME type to be displayed on user interfaces.
+
+ The system language (QLocale::system().name()) is used to select the appropriate translation.
+ Another language can be specified by setting the \a localeName argument.
+ */
+QString QMimeType::comment() const
+{
+ QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
+
+ QStringList languageList;
+ languageList << QLocale::system().name();
+ languageList << QLocale::system().uiLanguages();
+ Q_FOREACH (const QString &lang, languageList) {
+ const QString comm = d->localeComments.value(lang);
+ if (!comm.isEmpty())
+ return comm;
+ const int pos = lang.indexOf(QLatin1Char('_'));
+ if (pos != -1) {
+ // "pt_BR" not found? try just "pt"
+ const QString shortLang = lang.left(pos);
+ const QString commShort = d->localeComments.value(shortLang);
+ if (!commShort.isEmpty())
+ return commShort;
+ }
+ }
+
+ // Use the mimetype name as fallback
+ return d->name;
+}
+
+/*!
+ \fn QString QMimeType::genericIconName() const;
+ Returns the file name of a generic icon that represents the MIME type.
+
+ This should be used if the icon returned by iconName() cannot be found on
+ the system. It is used for categories of similar types (like spreadsheets
+ or archives) that can use a common icon.
+ The freedesktop.org Icon Naming Specification lists a set of such icon names.
+
+ The icon name can be given to QIcon::fromTheme() in order to load the icon.
+ */
+QString QMimeType::genericIconName() const
+{
+ QMimeDatabasePrivate::instance()->provider()->loadGenericIcon(*d);
+ if (d->genericIconName.isEmpty()) {
+ // From the spec:
+ // If the generic icon name is empty (not specified by the mimetype definition)
+ // then the mimetype is used to generate the generic icon by using the top-level
+ // media type (e.g. "video" in "video/ogg") and appending "-x-generic"
+ // (i.e. "video-x-generic" in the previous example).
+ QString group = name();
+ const int slashindex = group.indexOf(QLatin1Char('/'));
+ if (slashindex != -1)
+ group = group.left(slashindex);
+ return group + QLatin1String("-x-generic");
+ }
+ return d->genericIconName;
+}
+
+/*!
+ \fn QString QMimeType::iconName() const;
+ Returns the file name of an icon image that represents the MIME type.
+
+ The icon name can be given to QIcon::fromTheme() in order to load the icon.
+ */
+QString QMimeType::iconName() const
+{
+ QMimeDatabasePrivate::instance()->provider()->loadIcon(*d);
+ if (d->iconName.isEmpty()) {
+ // Make default icon name from the mimetype name
+ d->iconName = name();
+ const int slashindex = d->iconName.indexOf(QLatin1Char('/'));
+ if (slashindex != -1)
+ d->iconName[slashindex] = QLatin1Char('-');
+ }
+ return d->iconName;
+}
+
+/*!
+ \fn QStringList QMimeType::globPatterns() const;
+ Returns the list of glob matching patterns.
+ */
+QStringList QMimeType::globPatterns() const
+{
+ QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
+ return d->globPatterns;
+}
+
+/*!
+ A type is a subclass of another type if any instance of the first type is
+ also an instance of the second. For example, all image/svg+xml files are also
+ text/xml, text/plain and application/octet-stream files. Subclassing is about
+ the format, rather than the category of the data (for example, there is no
+ 'generic spreadsheet' class that all spreadsheets inherit from).
+ Conversely, the parent mimetype of image/svg+xml is text/xml.
+
+ A mimetype can have multiple parents. For instance application/x-perl
+ has two parents: application/x-executable and text/plain. This makes
+ it possible to both execute perl scripts, and to open them in text editors.
+*/
+QStringList QMimeType::parentMimeTypes() const
+{
+ return QMimeDatabasePrivate::instance()->provider()->parents(d->name);
+}
+
+static void collectParentMimeTypes(const QString &mime, QStringList &allParents)
+{
+ QStringList parents = QMimeDatabasePrivate::instance()->provider()->parents(mime);
+ foreach (const QString &parent, parents) {
+ // I would use QSet, but since order matters I better not
+ if (!allParents.contains(parent))
+ allParents.append(parent);
+ }
+ // We want a breadth-first search, so that the least-specific parent (octet-stream) is last
+ // This means iterating twice, unfortunately.
+ foreach (const QString &parent, parents) {
+ collectParentMimeTypes(parent, allParents);
+ }
+}
+
+/*!
+ Return all the parent mimetypes of this mimetype, direct and indirect.
+ This includes the parent(s) of its parent(s), etc.
+
+ For instance, for image/svg+xml the list would be:
+ application/xml, text/plain, application/octet-stream.
+
+ Note that application/octet-stream is the ultimate parent for all types
+ of files (but not directories).
+*/
+QStringList QMimeType::allAncestors() const
+{
+ QStringList allParents;
+ collectParentMimeTypes(d->name, allParents);
+ return allParents;
+}
+
+/*!
+ \fn QStringList QMimeType::suffixes() const;
+ Returns the known suffixes for the MIME type.
+ */
+QStringList QMimeType::suffixes() const
+{
+ QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
+
+ QStringList result;
+ foreach (const QString &pattern, d->globPatterns) {
+ // Not a simple suffix if if looks like: README or *. or *.* or *.JP*G or *.JP?
+ if (pattern.startsWith(QLatin1String("*.")) &&
+ pattern.length() > 2 &&
+ pattern.indexOf(QLatin1Char('*'), 2) < 0 && pattern.indexOf(QLatin1Char('?'), 2) < 0) {
+ const QString suffix = pattern.mid(2);
+ result.append(suffix);
+ }
+ }
+
+ return result;
+}
+
+/*!
+ \fn QString QMimeType::preferredSuffix() const;
+ Returns the preferred suffix for the MIME type.
+ */
+QString QMimeType::preferredSuffix() const
+{
+ const QStringList suffixList = suffixes();
+ return suffixList.isEmpty() ? QString() : suffixList.at(0);
+}
+
+/*!
+ \fn QString QMimeType::filterString() const;
+ Returns a filter string usable for a file dialog.
+*/
+QString QMimeType::filterString() const
+{
+ QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
+ QString filter;
+
+ if (!d->globPatterns.empty()) {
+ filter += comment() + QLatin1String(" (");
+ for (int i = 0; i < d->globPatterns.size(); ++i) {
+ if (i != 0)
+ filter += QLatin1Char(' ');
+ filter += d->globPatterns.at(i);
+ }
+ filter += QLatin1Char(')');
+ }
+
+ return filter;
+}
+
+/*!
+ \fn bool QMimeType::inherits(const QString &mimeTypeName) const;
+ Returns true if this mimetype is \a mimeTypeName,
+ or inherits \a mimeTypeName (see parentMimeTypes()),
+ or \a mimeTypeName is an alias for this mimetype.
+ */
+bool QMimeType::inherits(const QString &mimeTypeName) const
+{
+ if (d->name == mimeTypeName)
+ return true;
+ return QMimeDatabasePrivate::instance()->inherits(d->name, mimeTypeName);
+}
+
+#undef DBG
+
+QT_END_NAMESPACE