kdecore: deal with KMimeType TODO

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-06-29 19:49:18 +03:00
parent 63a5c48126
commit 5290bf44e0
12 changed files with 116 additions and 192 deletions

View file

@ -30,15 +30,10 @@
class KFolderMimeTypePrivate : public KMimeTypePrivate class KFolderMimeTypePrivate : public KMimeTypePrivate
{ {
public: public:
K_SYCOCATYPE( KST_KFolderMimeType, KMimeTypePrivate )
KFolderMimeTypePrivate(const QString &s) KFolderMimeTypePrivate(const QString &s)
: KMimeTypePrivate(s) : KMimeTypePrivate(s)
{} {
}
KFolderMimeTypePrivate(QDataStream& str, int offset)
: KMimeTypePrivate(str, offset)
{}
QString comment(const KUrl &url = KUrl()) const final; QString comment(const KUrl &url = KUrl()) const final;
QString iconName(const KUrl &url) const final; QString iconName(const KUrl &url) const final;
@ -51,13 +46,8 @@ public:
* *
******************************************************/ ******************************************************/
KFolderMimeType::KFolderMimeType( const QString& fullpath, const QString& name, const QString& comment ) KFolderMimeType::KFolderMimeType(const QString &fullpath, const QString &name, const QString &comment)
: KMimeType(*new KFolderMimeTypePrivate(fullpath), name, comment ) : KMimeType(*new KFolderMimeTypePrivate(fullpath), name, comment)
{
}
KFolderMimeType::KFolderMimeType( QDataStream& str, int offset )
: KMimeType( *new KFolderMimeTypePrivate(str, offset))
{ {
} }
@ -65,68 +55,69 @@ KFolderMimeType::~KFolderMimeType()
{ {
} }
QString KFolderMimeTypePrivate::iconName( const KUrl& _url ) const QString KFolderMimeTypePrivate::iconName(const KUrl &_url) const
{ {
if ( _url.isEmpty() || !_url.isLocalFile() ) if (_url.isEmpty() || !_url.isLocalFile()) {
return KMimeTypePrivate::iconName( _url ); 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() ) // Stating .directory files can cause long freezes when e.g. /home
return KMimeTypePrivate::iconName( _url ); // 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);
}
if ( icon.startsWith( QLatin1String( "./" ) ) ) { KUrl u(_url);
// path is relative with respect to the location u.addPath(QString::fromLatin1(".directory"));
// of the .directory file (#73463)
KUrl v( _url );
v.addPath( icon.mid( 2 ) );
icon = v.toLocalFile();
}
return icon; 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 QString KFolderMimeTypePrivate::comment(const KUrl &_url) const
{ {
if ( _url.isEmpty() || !_url.isLocalFile() ) if ( _url.isEmpty() || !_url.isLocalFile() )
return KMimeTypePrivate::comment( _url ); return KMimeTypePrivate::comment( _url );

View file

@ -30,17 +30,15 @@ class KFolderMimeTypePrivate;
* Folder mime type. Handles the .directory file inside a folder, which modifies * Folder mime type. Handles the .directory file inside a folder, which modifies
* the comment and icon for this folder. * the comment and icon for this folder.
* @short Mimetype for a folder (inode/directory) * @short Mimetype for a folder (inode/directory)
* @todo merge into KMimeType
*/ */
class KDECORE_EXPORT KFolderMimeType : public KMimeType class KDECORE_EXPORT KFolderMimeType : public KMimeType
{ {
Q_DECLARE_PRIVATE( KFolderMimeType ) Q_DECLARE_PRIVATE(KFolderMimeType)
public: public:
/** \internal */ /** \internal */
KFolderMimeType( const QString& fullpath, const QString& name, const QString& comment ); KFolderMimeType(const QString &fullpath, const QString &name, const QString &comment);
/** \internal */
KFolderMimeType( QDataStream& str, int offset );
/** Destructor. */ /** Destructor. */
~KFolderMimeType(); ~KFolderMimeType();

View file

@ -382,62 +382,34 @@ bool KMimeType::isBinaryData(const QString &fileName)
KMimeType::KMimeType(KMimeTypePrivate &dd, const QString &name, KMimeType::KMimeType(KMimeTypePrivate &dd, const QString &name,
const QString &comment) const QString &comment)
: KServiceType(dd, name, 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)
: KServiceType(*new KMimeTypePrivate(fullpath), name, comment) : QSharedData(),
d_ptr(new KMimeTypePrivate(fullpath))
{ {
d_ptr->m_strName = name;
d_ptr->m_strComment = comment;
} }
KMimeType::KMimeType(KMimeTypePrivate &dd) KMimeType::KMimeType(KMimeTypePrivate &dd)
: KServiceType(dd) : QSharedData(),
d_ptr(&dd)
{ {
} }
KMimeType::KMimeType(QDataStream &str, int offset)
: KServiceType(*new KMimeTypePrivate(str, offset))
{
}
void KMimeTypePrivate::save(QDataStream &str)
{
KServiceTypePrivate::save(str);
// Warning adding fields here involves a binary incompatible change - update version
// number in ksycoca.h. Never remove fields.
str << m_lstPatterns << QString() << QStringList() << m_iconName;
}
QVariant KMimeTypePrivate::property(const QString &name) const
{
if (name == QLatin1String("Patterns")) {
return patterns();
} else if (name == QLatin1String("Comment")) {
return comment();
} else if (name == QLatin1String("Icon")) {
return QVariant(iconName(KUrl()));
}
return KServiceTypePrivate::property(name);
}
QStringList KMimeTypePrivate::propertyNames() const
{
QStringList res = KServiceTypePrivate::propertyNames();
res.append(QString::fromLatin1("Patterns"));
res.append(QString::fromLatin1("Icon"));
return res;
}
KMimeType::~KMimeType() KMimeType::~KMimeType()
{ {
} }
QString KMimeType::iconNameForUrl(const KUrl &_url, mode_t mode) QString KMimeType::iconNameForUrl(const KUrl &_url, mode_t mode)
{ {
const KMimeType::Ptr mt = findByUrl(_url, mode, _url.isLocalFile(), const KMimeType::Ptr mt = findByUrl(_url, mode, _url.isLocalFile(), false /*HACK*/);
false /*HACK*/);
if (!mt) { if (!mt) {
return QString(); return QString();
} }
@ -561,7 +533,13 @@ QString KMimeType::defaultMimeType()
return QString::fromLatin1("application/octet-stream"); return QString::fromLatin1("application/octet-stream");
} }
QString KMimeType::iconName( const KUrl& url) const QString KMimeType::name() const
{
Q_D(const KMimeType);
return d->m_strName;
}
QString KMimeType::iconName(const KUrl &url) const
{ {
Q_D(const KMimeType); Q_D(const KMimeType);
return d->iconName(url); return d->iconName(url);
@ -722,11 +700,6 @@ bool KMimeType::matchFileName(const QString &filename, const QString &pattern)
return KMimeTypeRepository::matchFileName(filename, pattern); return KMimeTypeRepository::matchFileName(filename, pattern);
} }
int KMimeTypePrivate::serviceOffersOffset() const
{
return KMimeTypeFactory::self()->serviceOffersOffset(name());
}
QString KMimeTypePrivate::iconName(const KUrl &url) const QString KMimeTypePrivate::iconName(const KUrl &url) const
{ {
Q_UNUSED(url); Q_UNUSED(url);

View file

@ -21,7 +21,7 @@
#define KMIMETYPE_H #define KMIMETYPE_H
#include <kurl.h> #include <kurl.h>
#include <kservicetype.h> #include <ksharedptr.h>
class KMimeTypePrivate; class KMimeTypePrivate;
@ -31,12 +31,9 @@ class KMimeTypePrivate;
* *
* The starting point you need is often the static methods. * The starting point you need is often the static methods.
* *
* KMimeType inherits KServiceType because "text/plain" can be used to find
* services (apps and components) "which can open text/plain".
*
* @see KServiceType * @see KServiceType
*/ */
class KDECORE_EXPORT KMimeType : public KServiceType // TODO KDE5: drop kservicetype inheritance, inherit kshared class KDECORE_EXPORT KMimeType : public QSharedData
{ {
Q_DECLARE_PRIVATE(KMimeType) Q_DECLARE_PRIVATE(KMimeType)
public: public:
@ -45,6 +42,8 @@ public:
virtual ~KMimeType(); virtual ~KMimeType();
QString name() const;
/** /**
* Return the filename of the icon associated with the mimetype. * Return the filename of the icon associated with the mimetype.
* Use KIconLoader::loadMimeTypeIcon to load the icon. * Use KIconLoader::loadMimeTypeIcon to load the icon.
@ -402,16 +401,8 @@ public:
static int sharedMimeInfoVersion(); static int sharedMimeInfoVersion();
protected: protected:
friend class KMimeTypeRepository; // for KMimeType(QString,QString,QString) friend class KMimeTypeRepository; // for KMimeType(QString,QString,QString)
/**
* @internal Construct a service from a stream.
*
* The stream must already be positionned at the correct offset
*/
KMimeType(QDataStream &str, int offset);
/** /**
* Construct a mimetype and take all information from an XML file. * Construct a mimetype and take all information from an XML file.
* @param fullpath the path to the xml that describes the mime type * @param fullpath the path to the xml that describes the mime type
@ -439,9 +430,8 @@ protected:
KMimeType(KMimeTypePrivate &dd, const QString &name, const QString &comment); KMimeType(KMimeTypePrivate &dd, const QString &name, const QString &comment);
private: private:
// Forbidden nowadays in KMimeType friend class KFolderMimeType;
int offset() const; KMimeTypePrivate* d_ptr;
void save(QDataStream &s);
static void checkEssentialMimeTypes(); static void checkEssentialMimeTypes();
static KMimeType::Ptr findByUrlHelper(const KUrl& url, mode_t mode, static KMimeType::Ptr findByUrlHelper(const KUrl& url, mode_t mode,

View file

@ -16,34 +16,20 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA. * Boston, MA 02110-1301, USA.
**/ **/
#ifndef __kmimetype_p_h__ #ifndef KMIMETYPE_P_H
#define __kmimetype_p_h__ #define KMIMETYPE_P_H
#include "kservicetype_p.h" #include <QStringList>
class KMimeTypePrivate: public KServiceTypePrivate class KMimeTypePrivate
{ {
public: public:
K_SYCOCATYPE( KST_KMimeType, KServiceTypePrivate )
KMimeTypePrivate(const QString &path) KMimeTypePrivate(const QString &path)
: KServiceTypePrivate(path), : m_path(path),
m_xmlDataLoaded(false) m_xmlDataLoaded(false)
{ {
} }
KMimeTypePrivate(QDataStream &str, int offset)
: KServiceTypePrivate(str, offset),
m_xmlDataLoaded(false)
{
}
virtual void save(QDataStream &str);
virtual QVariant property(const QString &name) const;
virtual QStringList propertyNames() const;
virtual QString comment(const KUrl &url = KUrl()) const virtual QString comment(const KUrl &url = KUrl()) const
{ {
ensureXmlDataLoaded(); ensureXmlDataLoaded();
@ -61,11 +47,13 @@ public:
bool inherits(const QString &mime) const; bool inherits(const QString &mime) const;
void ensureXmlDataLoaded() const; void ensureXmlDataLoaded() const;
virtual int serviceOffersOffset() const;
mutable QString m_path;
mutable QString m_strName;
mutable QString m_strComment;
mutable QStringList m_lstPatterns; mutable QStringList m_lstPatterns;
mutable QString m_iconName; // user-specified mutable QString m_iconName; // user-specified
mutable bool m_xmlDataLoaded; mutable bool m_xmlDataLoaded;
}; };
#endif // __kmimetype_p_h__ #endif // KMIMETYPE_P_H

View file

@ -75,28 +75,22 @@ int KMimeTypeFactory::serviceOffersOffset(const QString& mimeTypeName)
KMimeTypeFactory::MimeTypeEntry * KMimeTypeFactory::createEntry(int offset) const KMimeTypeFactory::MimeTypeEntry * KMimeTypeFactory::createEntry(int offset) const
{ {
MimeTypeEntry *newEntry = 0; MimeTypeEntry *newEntry = nullptr;
KSycocaType type; KSycocaType type;
QDataStream *str = KSycoca::self()->findEntry(offset, type); QDataStream *str = KSycoca::self()->findEntry(offset, type);
if (!str) return 0; if (!str) return 0;
switch(type) switch(type) {
{ case KST_KMimeTypeEntry: {
case KST_KMimeTypeEntry: newEntry = new MimeTypeEntry(*str, offset);
newEntry = new MimeTypeEntry(*str, offset); break;
break; }
default: {
// Old, now unused kError(7011) << "KMimeTypeFactory: unexpected object entry in KSycoca database (type=" << int(type) << ")";
case KST_KMimeType: break;
case KST_KFolderMimeType: }
return 0;
default:
kError(7011) << "KMimeTypeFactory: unexpected object entry in KSycoca database (type=" << int(type) << ")";
break;
} }
if (newEntry && !newEntry->isValid()) if (newEntry && !newEntry->isValid()) {
{
kError(7011) << "KMimeTypeFactory: corrupt object in KSycoca database!\n"; kError(7011) << "KMimeTypeFactory: corrupt object in KSycoca database!\n";
delete newEntry; delete newEntry;
newEntry = 0; newEntry = 0;

View file

@ -88,10 +88,10 @@ KMimeType::Ptr KMimeTypeRepository::findMimeTypeByName(const QString &_name, KMi
return KMimeType::Ptr(); // Not found return KMimeType::Ptr(); // Not found
} }
if (name == QLatin1String("inode/directory")) if (name == QLatin1String("inode/directory")) {
return KMimeType::Ptr(new KFolderMimeType(filename, name, QString() /*comment*/)); return KMimeType::Ptr(new KFolderMimeType(filename, name, QString() /*comment*/));
else }
return KMimeType::Ptr(new KMimeType(filename, name, QString() /*comment*/)); return KMimeType::Ptr(new KMimeType(filename, name, QString() /*comment*/));
} }
bool KMimeTypeRepository::checkMimeTypes() bool KMimeTypeRepository::checkMimeTypes()

View file

@ -28,9 +28,9 @@
* To use it, call the macro K_SYCOCATYPE( your_typecode, parent_class ) * To use it, call the macro K_SYCOCATYPE( your_typecode, parent_class )
* at the top of your class definition. * at the top of your class definition.
*/ */
enum KSycocaType { KST_KSycocaEntry = 0, KST_KService = 1, KST_KServiceType = 2, KST_KMimeType = 3, enum KSycocaType { KST_KSycocaEntry = 0, KST_KService = 1, KST_KServiceType = 2,
KST_KFolderMimeType = 4, KST_KMimeTypeEntry = 5 /*internal*/, KST_KMimeTypeEntry = 3 /*internal*/,
KST_KServiceGroup = 6, KST_KProtocolInfo = 7, KST_KServiceSeparator = 8, KST_KServiceGroup = 4, KST_KProtocolInfo = 5, KST_KServiceSeparator = 6,
KST_KCustom = 1000 }; KST_KCustom = 1000 };
/** /**

View file

@ -495,7 +495,6 @@ void KMimeTypeTest::testAllMimeTypes()
//qDebug( "%s", qPrintable( name ) ); //qDebug( "%s", qPrintable( name ) );
QVERIFY( !name.isEmpty() ); QVERIFY( !name.isEmpty() );
QCOMPARE( name.count( '/' ), 1 ); QCOMPARE( name.count( '/' ), 1 );
QVERIFY( mime->isType( KST_KMimeType ) );
const KMimeType::Ptr lookedupMime = KMimeType::mimeType( name ); const KMimeType::Ptr lookedupMime = KMimeType::mimeType( name );
QVERIFY( lookedupMime ); // not null QVERIFY( lookedupMime ); // not null
@ -977,14 +976,4 @@ void KMimeTypeTest::testThreads()
future10.wait(); future10.wait();
} }
void KMimeTypeTest::testProperties()
{
KMimeType::Ptr pngMimeType = KMimeType::mimeType("image/png");
QVariant comment = pngMimeType->property("Comment");
QVariant patterns = pngMimeType->property("Patterns");
QCOMPARE(comment.toString(), pngMimeType->comment());
QCOMPARE(patterns.toStringList(), pngMimeType->patterns());
}
#include "moc_kmimetypetest.cpp" #include "moc_kmimetypetest.cpp"

View file

@ -61,7 +61,6 @@ private Q_SLOTS:
void testHelperProtocols(); void testHelperProtocols();
void testFromThread(); void testFromThread();
void testThreads(); void testThreads();
void testProperties();
private: private:
QList<KMimeMagicRule> m_rules; QList<KMimeMagicRule> m_rules;
QString m_nonKdeApp; QString m_nonKdeApp;

View file

@ -25,14 +25,15 @@
#include "ksycocadict_p.h" #include "ksycocadict_p.h"
#include "ksycocaresourcelist.h" #include "ksycocaresourcelist.h"
#include "kdesktopfile.h" #include "kdesktopfile.h"
#include "kservicetype.h"
#include <kglobal.h> #include <kglobal.h>
#include <kstandarddirs.h> #include <kstandarddirs.h>
#include <klocale.h> #include <klocale.h>
#include <kdebug.h> #include <kdebug.h>
#include <assert.h>
#include <kmimetypefactory.h> #include <kmimetypefactory.h>
#include <assert.h>
KBuildServiceFactory::KBuildServiceFactory( KSycocaFactory *serviceTypeFactory, KBuildServiceFactory::KBuildServiceFactory( KSycocaFactory *serviceTypeFactory,
KBuildMimeTypeFactory *mimeTypeFactory, KBuildMimeTypeFactory *mimeTypeFactory,
KBuildServiceGroupFactory *serviceGroupFactory ) : KBuildServiceGroupFactory *serviceGroupFactory ) :

View file

@ -32,6 +32,7 @@
#include "kfile_export.h" #include "kfile_export.h"
#include "kabstractfilewidget.h" #include "kabstractfilewidget.h"
#include "kconfiggroup.h"
class KJob; class KJob;
class KFileItem; class KFileItem;