kdecore: merge KFolderMimeType into KMimeType

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-06-30 00:09:28 +03:00
parent 8133f7f73a
commit 6a738b1bbe
8 changed files with 128 additions and 280 deletions

View file

@ -92,7 +92,6 @@ set(kdecore_LIB_SRCS
kernel/kcomponentdata.cpp kernel/kcomponentdata.cpp
kernel/kstandarddirs.cpp kernel/kstandarddirs.cpp
kernel/ktoolinvocation.cpp kernel/ktoolinvocation.cpp
services/kfoldermimetype.cpp
services/kmimetypefactory.cpp services/kmimetypefactory.cpp
services/kmimemagicrule.cpp services/kmimemagicrule.cpp
services/kmimetypetrader.cpp services/kmimetypetrader.cpp

View file

@ -1,136 +0,0 @@
/* This file is part of the KDE libraries
* Copyright (C) 1999 Waldo Bastian <bastian@kde.org>
* 2000, 2007 David Faure <faure@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
**/
#include "kfoldermimetype.h"
#include "kmimetype_p.h"
#include <kdesktopfile.h>
#include <kstandarddirs.h>
#include <kconfiggroup.h>
#include <kde_file.h>
#include <QtCore/QFile>
#include <QtCore/QSet>
#include <QtCore/QDirIterator>
class KFolderMimeTypePrivate : public KMimeTypePrivate
{
public:
KFolderMimeTypePrivate(const QString &s)
: KMimeTypePrivate(s)
{
}
QString comment(const KUrl &url = KUrl()) const final;
QString iconName(const KUrl &url) const final;
};
/*******************************************************
*
* KFolderMimeType
*
******************************************************/
KFolderMimeType::KFolderMimeType(const QString &fullpath, const QString &name, const QString &comment)
: KMimeType(*new KFolderMimeTypePrivate(fullpath), name, comment)
{
}
KFolderMimeType::~KFolderMimeType()
{
}
QString KFolderMimeTypePrivate::iconName(const KUrl &_url) const
{
if (_url.isEmpty() || !_url.isLocalFile()) {
return KMimeTypePrivate::iconName(_url);
}
// Stating .directory files can cause long freezes when e.g. /home
// uses autofs for every user's home directory, i.e. opening /home
// in a file dialog will mount every single home directory.
// These non-mounted directories can be identified by having 0 size.
// There are also other directories with 0 size, such as /proc, that may
// be mounted, but those are unlikely to contain .directory (and checking
// this would require KMountPoint from kio).
KDE_struct_stat buff;
if (KDE_stat(QFile::encodeName(_url.toLocalFile()), &buff) == 0
&& S_ISDIR(buff.st_mode) && buff.st_size == 0) {
return KMimeTypePrivate::iconName(_url);
}
KUrl u(_url);
u.addPath(QString::fromLatin1(".directory"));
QString icon;
// using KStandardDirs as this one checks for path being
// a file instead of a directory
if (KGlobal::dirs()->exists(u.toLocalFile())) {
KDesktopFile cfg(u.toLocalFile());
KConfigGroup group = cfg.desktopGroup();
icon = group.readEntry("Icon");
QString empty_icon = group.readEntry("EmptyIcon");
if (!empty_icon.isEmpty()) {
bool isempty = true;
QDirIterator dirIt(_url.toLocalFile(), QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
while (dirIt.hasNext() ) {
dirIt.next();
if (dirIt.fileName() != QLatin1String(".directory")) {
isempty = false;
break;
}
}
if (isempty) {
return empty_icon;
}
}
}
if (icon.isEmpty()) {
return KMimeTypePrivate::iconName(_url);
}
if (icon.startsWith(QLatin1String("./"))) {
// path is relative with respect to the location
// of the .directory file (#73463)
KUrl v(_url);
v.addPath(icon.mid(2));
icon = v.toLocalFile();
}
return icon;
}
QString KFolderMimeTypePrivate::comment(const KUrl &_url) const
{
if (_url.isEmpty() || !_url.isLocalFile()) {
return KMimeTypePrivate::comment(_url);
}
KUrl u(_url);
u.addPath(QString::fromLatin1(".directory"));
const KDesktopFile cfg(u.toLocalFile());
QString comment = cfg.readComment();
if (comment.isEmpty()) {
return KMimeTypePrivate::comment(_url);
}
return comment;
}

View file

@ -1,47 +0,0 @@
/* This file is part of the KDE libraries
* Copyright (C) 1999 Waldo Bastian <bastian@kde.org>
* 2000, 2007 David Faure <faure@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
**/
#ifndef KFOLDERMIMETYPE_H
#define KFOLDERMIMETYPE_H
#include "kmimetype.h"
class KFolderMimeTypePrivate;
/**
* @internal - this header is not installed
*
* Folder mime type. Handles the .directory file inside a folder, which modifies
* the comment and icon for this folder.
* @short Mimetype for a folder (inode/directory)
* @todo merge into KMimeType
*/
class KDECORE_EXPORT KFolderMimeType : public KMimeType
{
Q_DECLARE_PRIVATE(KFolderMimeType)
public:
/** \internal */
KFolderMimeType(const QString &fullpath, const QString &name, const QString &comment);
/** Destructor. */
~KFolderMimeType();
};
#endif

View file

@ -32,19 +32,96 @@
#include <kprotocolinfofactory.h> #include <kprotocolinfofactory.h>
#include <kstandarddirs.h> #include <kstandarddirs.h>
#include <kurl.h> #include <kurl.h>
#include <kdesktopfile.h>
#include <kconfiggroup.h>
#include <QtCore/qfile.h> #include <QFile>
#include <QtCore/qhash.h> #include <QHash>
#include <QtCore/qbuffer.h> #include <QBuffer>
#include <QtCore/qstack.h> #include <QStack>
#include <QXmlStreamReader> #include <QXmlStreamReader>
#include <QDBusInterface> #include <QDBusInterface>
#include <QDBusReply> #include <QDBusReply>
#include <QDirIterator>
extern int servicesDebugArea(); extern int servicesDebugArea();
template class KSharedPtr<KMimeType>; template class KSharedPtr<KMimeType>;
static QString kFolderComment(const KUrl &_url)
{
if (_url.isEmpty() || !_url.isLocalFile()) {
return QString();
}
KUrl u(_url);
u.addPath(QString::fromLatin1(".directory"));
const KDesktopFile cfg(u.toLocalFile());
return cfg.readComment();
}
static QString kFolderIconName(const KUrl &_url)
{
if (_url.isEmpty() || !_url.isLocalFile()) {
return QString();
}
// Stating .directory files can cause long freezes when e.g. /home
// uses autofs for every user's home directory, i.e. opening /home
// in a file dialog will mount every single home directory.
// These non-mounted directories can be identified by having 0 size.
// There are also other directories with 0 size, such as /proc, that may
// be mounted, but those are unlikely to contain .directory (and checking
// this would require KMountPoint from kio).
KDE_struct_stat buff;
if (KDE_stat(QFile::encodeName(_url.toLocalFile()), &buff) == 0
&& S_ISDIR(buff.st_mode) && buff.st_size == 0) {
return QString();
}
KUrl u(_url);
u.addPath(QString::fromLatin1(".directory"));
QString icon;
// using KStandardDirs as this one checks for path being
// a file instead of a directory
if (KGlobal::dirs()->exists(u.toLocalFile())) {
KDesktopFile cfg(u.toLocalFile());
KConfigGroup group = cfg.desktopGroup();
icon = group.readEntry("Icon");
QString empty_icon = group.readEntry("EmptyIcon");
if (!empty_icon.isEmpty()) {
bool isempty = true;
QDirIterator dirIt(_url.toLocalFile(), QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
while (dirIt.hasNext() ) {
dirIt.next();
if (dirIt.fileName() != QLatin1String(".directory")) {
isempty = false;
break;
}
}
if (isempty) {
return empty_icon;
}
}
}
if (icon.isEmpty()) {
return QString();
}
if (icon.startsWith(QLatin1String("./"))) {
// path is relative with respect to the location
// of the .directory file (#73463)
KUrl v(_url);
v.addPath(icon.mid(2));
icon = v.toLocalFile();
}
return icon;
}
KMimeType::Ptr KMimeType::defaultMimeTypePtr() KMimeType::Ptr KMimeType::defaultMimeTypePtr()
{ {
return KMimeTypeRepository::self()->defaultMimeTypePtr(); return KMimeTypeRepository::self()->defaultMimeTypePtr();
@ -381,14 +458,6 @@ bool KMimeType::isBinaryData(const QString &fileName)
return isBufferBinaryData(file.read(32)); return isBufferBinaryData(file.read(32));
} }
KMimeType::KMimeType(KMimeTypePrivate &dd, const QString &name,
const QString &comment)
: d_ptr(&dd)
{
d_ptr->m_strName = name;
d_ptr->m_strComment = comment;
}
KMimeType::KMimeType(const QString &fullpath, const QString &name, KMimeType::KMimeType(const QString &fullpath, const QString &name,
const QString &comment) const QString &comment)
: QSharedData(), : QSharedData(),
@ -398,11 +467,6 @@ KMimeType::KMimeType(const QString &fullpath, const QString &name,
d_ptr->m_strComment = comment; d_ptr->m_strComment = comment;
} }
KMimeType::KMimeType(KMimeTypePrivate &dd)
: QSharedData(),
d_ptr(&dd)
{
}
KMimeType::~KMimeType() KMimeType::~KMimeType()
{ {
@ -466,12 +530,6 @@ QString KMimeType::favIconForUrl(const KUrl &url, bool download)
return QString(); return QString();
} }
QString KMimeType::comment(const KUrl &url) const
{
Q_D(const KMimeType);
return d->comment(url);
}
bool KMimeTypePrivate::inherits(const QString &mime) const bool KMimeTypePrivate::inherits(const QString &mime) const
{ {
QStack<QString> toCheck; QStack<QString> toCheck;
@ -545,13 +603,56 @@ QString KMimeType::name() const
QString KMimeType::iconName(const KUrl &url) const QString KMimeType::iconName(const KUrl &url) const
{ {
Q_D(const KMimeType); Q_D(const KMimeType);
return d->iconName(url);
if (d->m_strName == QLatin1String("inode/directory")) {
const QString folderIconName = kFolderIconName(url);
if (!folderIconName.isEmpty()) {
return folderIconName;
}
}
static QHash<QUrl, QString> iconNameCache;
QString iconNameFromCache = iconNameCache.value(d->m_strName);
if (!iconNameFromCache.isEmpty()) {
return iconNameFromCache;
}
d->ensureXmlDataLoaded();
QString result;
if (!d->m_iconName.isEmpty()) {
result = d->m_iconName;
} else {
// Make default icon name from the mimetype name
// Don't store this in m_iconName, it would make the filetype editor
// write out icon names in every local mimetype definition file.
QString icon = d->m_strName;
const int slashindex = icon.indexOf(QLatin1Char('/'));
if (slashindex != -1) {
icon[slashindex] = QLatin1Char('-');
}
result = icon;
}
iconNameCache.insert(d->m_strName, result);
return result;
}
QString KMimeType::comment(const KUrl &url) const
{
Q_D(const KMimeType);
if (d->m_strName == QLatin1String("inode/directory")) {
const QString folderComment = kFolderComment(url);
if (!folderComment.isEmpty()) {
return folderComment;
}
}
d->ensureXmlDataLoaded();
return d->m_strComment;
} }
QStringList KMimeType::patterns() const QStringList KMimeType::patterns() const
{ {
Q_D(const KMimeType); Q_D(const KMimeType);
return d->patterns(); d->ensureXmlDataLoaded();
return d->m_lstPatterns;
} }
// loads comment, icon, mainPattern, m_lstPatterns // loads comment, icon, mainPattern, m_lstPatterns
@ -669,7 +770,7 @@ int KMimeType::sharedMimeInfoVersion()
QString KMimeType::mainExtension() const QString KMimeType::mainExtension() const
{ {
Q_D(const KMimeType); Q_D(const KMimeType);
Q_FOREACH(const QString &pattern, d->patterns()) { Q_FOREACH(const QString &pattern, patterns()) {
// Skip if if looks like: README or *. or *.* // Skip if if looks like: README or *. or *.*
// or *.JP*G or *.JP? // or *.JP*G or *.JP?
if (pattern.startsWith(QLatin1String("*.")) && if (pattern.startsWith(QLatin1String("*.")) &&
@ -686,32 +787,3 @@ bool KMimeType::matchFileName(const QString &filename, const QString &pattern)
{ {
return KMimeTypeRepository::matchFileName(filename, pattern); return KMimeTypeRepository::matchFileName(filename, pattern);
} }
QString KMimeTypePrivate::iconName(const KUrl &url) const
{
Q_UNUSED(url);
static QHash<QUrl, QString> iconNameCache;
QString iconNameFromCache = iconNameCache.value(m_strName);
if (!iconNameFromCache.isEmpty()) {
return iconNameFromCache;
}
ensureXmlDataLoaded();
QString result;
if (!m_iconName.isEmpty()) {
result = m_iconName;
} else {
// Make default icon name from the mimetype name
// Don't store this in m_iconName, it would make the filetype editor
// write out icon names in every local mimetype definition file.
QString icon = m_strName;
const int slashindex = icon.indexOf(QLatin1Char('/'));
if (slashindex != -1) {
icon[slashindex] = QLatin1Char('-');
}
result = icon;
}
iconNameCache.insert(m_strName, result);
return result;
}

View file

@ -38,7 +38,7 @@ public:
typedef KSharedPtr<KMimeType> Ptr; typedef KSharedPtr<KMimeType> Ptr;
typedef QList<Ptr> List; typedef QList<Ptr> List;
virtual ~KMimeType(); ~KMimeType();
/** /**
* Return the name of the mimetype, e.g. "text/plain". * Return the name of the mimetype, e.g. "text/plain".
@ -414,26 +414,7 @@ protected:
*/ */
KMimeType(const QString &fullpath, const QString &name, const QString &comment); KMimeType(const QString &fullpath, const QString &name, const QString &comment);
/**
* Construct a mimetype from another mimetype's private object
*
* @param dd the private object
*/
KMimeType(KMimeTypePrivate &dd);
/**
* Construct a mimetype based on another mimetype's private object
*
* Allows the name and comment to be overridden.
*
* @param dd the private object
* @param name the name of the mimetype
* @param comment the comment associated with the mimetype
*/
KMimeType(KMimeTypePrivate &dd, const QString &name, const QString &comment);
private: private:
friend class KFolderMimeType;
KMimeTypePrivate* d_ptr; KMimeTypePrivate* d_ptr;
static void checkEssentialMimeTypes(); static void checkEssentialMimeTypes();

View file

@ -30,20 +30,6 @@ public:
{ {
} }
// virtual because reimplemented in KFolderMimeType
virtual QString iconName(const KUrl &url) const;
virtual QString comment(const KUrl &url = KUrl()) const
{
ensureXmlDataLoaded();
return m_strComment;
}
QStringList patterns() const
{
ensureXmlDataLoaded();
return m_lstPatterns;
}
bool inherits(const QString &mime) const; bool inherits(const QString &mime) const;
void ensureXmlDataLoaded() const; void ensureXmlDataLoaded() const;

View file

@ -18,7 +18,6 @@
*/ */
#include "kmimetype.h" #include "kmimetype.h"
#include "kfoldermimetype.h"
#include "kmimetyperepository_p.h" #include "kmimetyperepository_p.h"
#include <kstandarddirs.h> #include <kstandarddirs.h>
#include <ksharedconfig.h> #include <ksharedconfig.h>
@ -87,9 +86,6 @@ KMimeType::Ptr KMimeTypeRepository::findMimeTypeByName(const QString &_name, KMi
return KMimeType::Ptr(); // Not found return KMimeType::Ptr(); // Not found
} }
if (name == QLatin1String("inode/directory")) {
return KMimeType::Ptr(new KFolderMimeType(filename, name, QString() /*comment*/));
}
return KMimeType::Ptr(new KMimeType(filename, name, QString() /*comment*/)); return KMimeType::Ptr(new KMimeType(filename, name, QString() /*comment*/));
} }

View file

@ -885,9 +885,6 @@ QString KFileItem::iconName() const
} }
} }
// KDE5: handle .directory files here too, and get rid of
// KFolderMimeType and the url argument in KMimeType::iconName().
if (delaySlowOperations) if (delaySlowOperations)
d->m_iconName = mime->iconName(); d->m_iconName = mime->iconName();
else else