kio: drop the feature to delay MIME type determination

it shall be delayed without the feature (which it was anyway)

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-05-27 17:09:59 +03:00
parent cea5737e95
commit 825763d73f
16 changed files with 62 additions and 432 deletions

View file

@ -53,7 +53,6 @@ set(kdecore_LIB_SRCS
date/ksystemtimezone.cpp date/ksystemtimezone.cpp
io/kdebug.cpp io/kdebug.cpp
io/kdirwatch.cpp io/kdirwatch.cpp
io/kfilesystemtype_p.cpp
io/kmountpoint.cpp io/kmountpoint.cpp
io/kprocess.cpp io/kprocess.cpp
io/ksavefile.cpp io/ksavefile.cpp

View file

@ -1,112 +0,0 @@
/*
This file is part of the KDE libraries
Copyright (c) 2011 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.1 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 "kfilesystemtype_p.h"
#include <QFile>
#include <QDebug>
//#include <errno.h>
inline KFileSystemType::Type kde_typeFromName(const char *name)
{
if (qstrncmp(name, "nfs", 3) == 0
|| qstrncmp(name, "autofs", 6) == 0
|| qstrncmp(name, "cachefs", 7) == 0
|| qstrncmp(name, "fuse.sshfs", 10) == 0
|| qstrncmp(name, "xtreemfs@", 9) == 0) // #178678
return KFileSystemType::Nfs;
if (qstrncmp(name, "cifs", 4) == 0
|| qstrncmp(name, "smbfs", 5) == 0)
return KFileSystemType::Smb;
return KFileSystemType::Other;
}
#if defined(Q_OS_FREEBSD) || defined(Q_OS_DRAGONFLY) || defined(Q_OS_OPENBSD)
# include <sys/param.h>
# include <sys/mount.h>
KFileSystemType::Type determineFileSystemTypeImpl(const QByteArray& path)
{
struct statfs buf;
if (statfs(path.constData(), &buf) != 0)
return KFileSystemType::Other;
return kde_typeFromName(buf.f_fstypename);
}
#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
# include <sys/vfs.h>
// LSB 3.2 has statfs in sys/statfs.h, sys/vfs.h is just an empty dummy header
# include <sys/statfs.h>
# if defined(Q_OS_LINUX)
# include <linux/magic.h>
# endif
# ifndef NFS_SUPER_MAGIC
# define NFS_SUPER_MAGIC 0x00006969
# endif
# ifndef AUTOFS_SUPER_MAGIC
# define AUTOFS_SUPER_MAGIC 0x00000187
# endif
# ifndef SMB_SUPER_MAGIC
# define SMB_SUPER_MAGIC 0x0000517B
#endif
# ifndef FUSE_SUPER_MAGIC
# define FUSE_SUPER_MAGIC 0x65735546
# endif
// Reverse-engineering without C++ code:
// strace stat -f /mnt 2>&1|grep statfs|grep mnt, and look for f_type
KFileSystemType::Type determineFileSystemTypeImpl(const QByteArray& path)
{
struct statfs buf;
if (statfs(path.constData(), &buf) != 0) {
//kDebug() << path << errno << strerror(errno);
return KFileSystemType::Other;
}
// TODO could be anything. Need to use statfs() to find out more.
if (buf.f_type == NFS_SUPER_MAGIC || buf.f_type == AUTOFS_SUPER_MAGIC || buf.f_type == FUSE_SUPER_MAGIC) {
return KFileSystemType::Nfs;
} else if (buf.f_type == SMB_SUPER_MAGIC) {
return KFileSystemType::Smb;
}
return KFileSystemType::Other;
}
#elif defined(Q_OS_SOLARIS) || defined(Q_OS_NETBSD)
# include <sys/statvfs.h>
KFileSystemType::Type determineFileSystemTypeImpl(const QByteArray& path)
{
struct statvfs buf;
if (statvfs(path.constData(), &buf) != 0)
return KFileSystemType::Other;
#if defined(Q_OS_NETBSD)
return kde_typeFromName(buf.f_fstypename);
#else
return kde_typeFromName(buf.f_basetype);
#endif
}
#endif
KFileSystemType::Type KFileSystemType::fileSystemType(const QString& path)
{
return determineFileSystemTypeImpl(QFile::encodeName(path));
}

View file

@ -1,38 +0,0 @@
/*
This file is part of the KDE libraries
Copyright (c) 2011 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.1 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 KFILESYSTEMTYPE_P_H
#define KFILESYSTEMTYPE_P_H
#include <QtCore/QString>
#include <kdecore_export.h>
namespace KFileSystemType
{
enum Type {
Nfs, // NFS or other full-featured networked filesystems (autofs, subfs, cachefs, sshfs)
Smb, // SMB/CIFS mount (networked but with some FAT-like behavior)
Other // ext, reiser, and so on. "Normal" local filesystems.
};
KDECORE_EXPORT Type fileSystemType(const QString& path);
}
#endif

View file

@ -1552,7 +1552,6 @@ void KDirOperator::setDirLister(KDirLister *lister)
d->proxyModel->setSourceModel(d->dirModel); d->proxyModel->setSourceModel(d->dirModel);
d->dirLister->setAutoUpdate(true); d->dirLister->setAutoUpdate(true);
d->dirLister->setDelayedMimeTypes(true);
QWidget* mainWidget = window(); QWidget* mainWidget = window();
d->dirLister->setMainWindow(mainWidget); d->dirLister->setMainWindow(mainWidget);

View file

@ -785,7 +785,7 @@ void KFilePreviewGenerator::Private::resolveMimeType()
bool resolved = false; bool resolved = false;
do { do {
KFileItem item = m_pendingItems.takeFirst(); KFileItem item = m_pendingItems.takeFirst();
if (item.isMimeTypeKnown()) { if (item.mimeTypePtr()) {
if (m_pendingVisibleIconUpdates > 0) { if (m_pendingVisibleIconUpdates > 0) {
// The item is visible and the MIME type already known. // The item is visible and the MIME type already known.
// Decrease the update counter for dispatchIconUpdateQueue(): // Decrease the update counter for dispatchIconUpdateQueue():
@ -797,7 +797,6 @@ void KFilePreviewGenerator::Private::resolveMimeType()
// would be very expensive. Instead the item is remembered in // would be very expensive. Instead the item is remembered in
// m_resolvedMimeTypes and will be dispatched later // m_resolvedMimeTypes and will be dispatched later
// by dispatchIconUpdateQueue(). // by dispatchIconUpdateQueue().
item.determineMimeType();
m_resolvedMimeTypes.append(item); m_resolvedMimeTypes.append(item);
resolved = true; resolved = true;
} }
@ -1137,7 +1136,7 @@ void KFilePreviewGenerator::setPreviewShown(bool show)
QList<QModelIndex> indexesWithKnownMimeType; QList<QModelIndex> indexesWithKnownMimeType;
foreach (const KFileItem& item, itemList) { foreach (const KFileItem& item, itemList) {
const QModelIndex index = dirModel->indexForItem(item); const QModelIndex index = dirModel->indexForItem(item);
if (item.isMimeTypeKnown()) { if (item.mimeTypePtr()) {
indexesWithKnownMimeType.append(index); indexesWithKnownMimeType.append(index);
} }
dirModel->setData(index, QIcon(), Qt::DecorationRole); dirModel->setData(index, QIcon(), Qt::DecorationRole);

View file

@ -34,7 +34,7 @@ static KIO::PreviewJob* createJob(const KUrl &url, int w, int h)
{ {
if (url.isValid()) { if (url.isValid()) {
KFileItemList items; KFileItemList items;
items.append(KFileItem(KFileItem::Unknown, KFileItem::Unknown, url, true)); items.append(KFileItem(KFileItem::Unknown, KFileItem::Unknown, url));
static const QStringList plugins = KIO::PreviewJob::availablePlugins(); static const QStringList plugins = KIO::PreviewJob::availablePlugins();
KIO::PreviewJob *previewJob = KIO::filePreview(items, QSize(w, h), &plugins); KIO::PreviewJob *previewJob = KIO::filePreview(items, QSize(w, h), &plugins);

View file

@ -29,7 +29,6 @@
KDirListerPrivate::KDirListerPrivate(KDirLister *parent) KDirListerPrivate::KDirListerPrivate(KDirLister *parent)
: autoUpdate(true), : autoUpdate(true),
delayedMimeTypes(false),
autoErrorHandling(true), autoErrorHandling(true),
showingDotFiles(false), showingDotFiles(false),
dirOnlyMode(false), dirOnlyMode(false),
@ -81,7 +80,7 @@ void KDirListerPrivate::processEntries(KIO::Job *job, const KIO::UDSEntryList &e
if (name.isEmpty()) { if (name.isEmpty()) {
continue; continue;
} }
const KFileItem item(it, processJob->url(), delayedMimeTypes, true); const KFileItem item(it, processJob->url(), true);
if (name == QLatin1String(".")) { if (name == QLatin1String(".")) {
rootItem = item; rootItem = item;
continue; continue;
@ -762,14 +761,4 @@ KFileItemList KDirLister::items(WhichItems which) const
return KFileItemList(); return KFileItemList();
} }
bool KDirLister::delayedMimeTypes() const
{
return d->delayedMimeTypes;
}
void KDirLister::setDelayedMimeTypes(bool delayedMimeTypes)
{
d->delayedMimeTypes = delayedMimeTypes;
}
#include "moc_kdirlister.cpp" #include "moc_kdirlister.cpp"

View file

@ -49,7 +49,6 @@ class KIO_EXPORT KDirLister : public QObject
Q_PROPERTY(bool showingDotFiles READ showingDotFiles WRITE setShowingDotFiles) Q_PROPERTY(bool showingDotFiles READ showingDotFiles WRITE setShowingDotFiles)
Q_PROPERTY(bool dirOnlyMode READ dirOnlyMode WRITE setDirOnlyMode) Q_PROPERTY(bool dirOnlyMode READ dirOnlyMode WRITE setDirOnlyMode)
Q_PROPERTY(bool autoErrorHandlingEnabled READ autoErrorHandlingEnabled) Q_PROPERTY(bool autoErrorHandlingEnabled READ autoErrorHandlingEnabled)
Q_PROPERTY(bool delayedMimeTypes READ delayedMimeTypes WRITE setDelayedMimeTypes)
Q_PROPERTY(QString nameFilter READ nameFilter WRITE setNameFilter) Q_PROPERTY(QString nameFilter READ nameFilter WRITE setNameFilter)
Q_PROPERTY(QStringList mimeFilter READ mimeFilters WRITE setMimeFilter RESET clearMimeFilter) Q_PROPERTY(QStringList mimeFilter READ mimeFilters WRITE setMimeFilter RESET clearMimeFilter)
@ -89,21 +88,6 @@ public:
*/ */
void stop(); void stop();
/**
* @return true if the "delayed mimetypes" feature was enabled
* @see setDelayedMimeTypes()
*/
bool delayedMimeTypes() const;
/**
* If enabled, mime types will be fetched on demand, which leads to a
* faster initial directory listing, where icons get progressively replaced
* with the correct one while KMimeType is going through the items with
* unknown or imprecise mimetype (e.g. files with no extension or an
* unknown extension).
*/
void setDelayedMimeTypes(bool delayedMimeTypes);
/** /**
* @return true if KDirWatch is used to automatically update directories. * @return true if KDirWatch is used to automatically update directories.
*/ */

View file

@ -35,7 +35,6 @@ public:
// toplevel URL // toplevel URL
KUrl url; KUrl url;
bool autoUpdate; bool autoUpdate;
bool delayedMimeTypes;
bool autoErrorHandling; bool autoErrorHandling;
bool showingDotFiles; bool showingDotFiles;
bool dirOnlyMode; bool dirOnlyMode;

View file

@ -97,7 +97,6 @@ public:
void setChildCount(int count) { m_childCount = count; } void setChildCount(int count) { m_childCount = count; }
bool isPopulated() const { return m_populated; } bool isPopulated() const { return m_populated; }
void setPopulated( bool populated ) { m_populated = populated; } void setPopulated( bool populated ) { m_populated = populated; }
bool isSlow() const { return item().isSlow(); }
// For removing all child urls from the global hash. // For removing all child urls from the global hash.
void collectAllChildUrls(KUrl::List &urls) const { void collectAllChildUrls(KUrl::List &urls) const {
@ -697,7 +696,7 @@ QVariant KDirModel::data( const QModelIndex & index, int role ) const
else { else {
KDirModelDirNode* dirNode = static_cast<KDirModelDirNode *>(node); KDirModelDirNode* dirNode = static_cast<KDirModelDirNode *>(node);
int count = dirNode->childCount(); int count = dirNode->childCount();
if (count == ChildCountUnknown && item.isReadable() && !dirNode->isSlow()) { if (count == ChildCountUnknown && item.isReadable()) {
const QString path = item.localPath(); const QString path = item.localPath();
if (!path.isEmpty()) { if (!path.isEmpty()) {
// slow // slow

View file

@ -98,7 +98,6 @@ public:
/** /**
* Notify the model that the item at this index has changed. * Notify the model that the item at this index has changed.
* For instance because KMimeTypeResolver called determineMimeType on it.
* This makes the model emit its dataChanged signal at this index, so that views repaint. * This makes the model emit its dataChanged signal at this index, so that views repaint.
* Note that for most things (renaming, changing size etc.), KDirLister's signals tell the model already. * Note that for most things (renaming, changing size etc.), KDirLister's signals tell the model already.
*/ */

View file

@ -43,7 +43,6 @@
#include <kconfiggroup.h> #include <kconfiggroup.h>
#include <kuser.h> #include <kuser.h>
#include <ktoolinvocation.h> #include <ktoolinvocation.h>
#include <kfilesystemtype_p.h>
static bool isKDirShare(const QString &dirpath) static bool isKDirShare(const QString &dirpath)
{ {
@ -68,8 +67,7 @@ public:
KFileItemPrivate(const KIO::UDSEntry &entry, KFileItemPrivate(const KIO::UDSEntry &entry,
mode_t mode, mode_t permissions, mode_t mode, mode_t permissions,
const KUrl &itemOrDirUrl, const KUrl &itemOrDirUrl,
bool urlIsDirectory, bool urlIsDirectory)
bool delayedMimeTypes)
: m_entry(entry), : m_entry(entry),
m_url(itemOrDirUrl), m_url(itemOrDirUrl),
m_strName(), m_strName(),
@ -82,9 +80,6 @@ public:
m_bMarked(false), m_bMarked(false),
m_bLink(false), m_bLink(false),
m_bIsLocalUrl(itemOrDirUrl.isLocalFile()), m_bIsLocalUrl(itemOrDirUrl.isLocalFile()),
m_bMimeTypeKnown(false),
m_delayedMimeTypes(delayedMimeTypes),
m_useIconNameCache(false),
m_slow(SlowUnknown) m_slow(SlowUnknown)
{ {
if (entry.count() != 0) { if (entry.count() != 0) {
@ -110,8 +105,7 @@ public:
} }
} }
const QString mimeTypeStr = m_entry.stringValue(KIO::UDSEntry::UDS_MIME_TYPE); const QString mimeTypeStr = m_entry.stringValue(KIO::UDSEntry::UDS_MIME_TYPE);
m_bMimeTypeKnown = !mimeTypeStr.isEmpty(); if (!mimeTypeStr.isEmpty()) {
if (m_bMimeTypeKnown) {
m_pMimeType = KMimeType::mimeType(mimeTypeStr); m_pMimeType = KMimeType::mimeType(mimeTypeStr);
} }
@ -137,12 +131,10 @@ public:
*/ */
void init(); void init();
QString localPath() const;
QDateTime time(KFileItem::FileTimes which) const; QDateTime time(KFileItem::FileTimes which) const;
void setTime(KFileItem::FileTimes which, long long time_t_val) const; void setTime(KFileItem::FileTimes which, long long time_t_val) const;
QString user() const; QString user() const;
QString group() const; QString group() const;
bool isSlow() const;
/** /**
* The UDSEntry that contains the data for this fileitem, if it came from a directory listing. * The UDSEntry that contains the data for this fileitem, if it came from a directory listing.
@ -201,12 +193,6 @@ public:
*/ */
bool m_bIsLocalUrl; bool m_bIsLocalUrl;
mutable bool m_bMimeTypeKnown;
mutable bool m_delayedMimeTypes;
/** True if m_iconName should be used as cache. */
mutable bool m_useIconNameCache;
// Slow? (nfs/smb/ssh) // Slow? (nfs/smb/ssh)
mutable enum { SlowUnknown, Fast, Slow } m_slow; mutable enum { SlowUnknown, Fast, Slow } m_slow;
@ -313,21 +299,20 @@ KFileItem::KFileItem()
{ {
} }
KFileItem::KFileItem(const KIO::UDSEntry& entry, const KUrl& itemOrDirUrl, bool delayedMimeTypes, bool urlIsDirectory) KFileItem::KFileItem(const KIO::UDSEntry& entry, const KUrl& itemOrDirUrl, bool urlIsDirectory)
: d(new KFileItemPrivate(entry, KFileItem::Unknown, KFileItem::Unknown, itemOrDirUrl, urlIsDirectory, delayedMimeTypes)) : d(new KFileItemPrivate(entry, KFileItem::Unknown, KFileItem::Unknown, itemOrDirUrl, urlIsDirectory))
{ {
} }
KFileItem::KFileItem(mode_t mode, mode_t permissions, const KUrl &url, bool delayedMimeTypes) KFileItem::KFileItem(mode_t mode, mode_t permissions, const KUrl &url)
: d(new KFileItemPrivate(KIO::UDSEntry(), mode, permissions, url, false, delayedMimeTypes)) : d(new KFileItemPrivate(KIO::UDSEntry(), mode, permissions, url, false))
{ {
} }
KFileItem::KFileItem( const KUrl &url, const QString &mimeType, mode_t mode) KFileItem::KFileItem( const KUrl &url, const QString &mimeType, mode_t mode)
: d(new KFileItemPrivate(KIO::UDSEntry(), mode, KFileItem::Unknown, url, false, false)) : d(new KFileItemPrivate(KIO::UDSEntry(), mode, KFileItem::Unknown, url, false))
{ {
d->m_bMimeTypeKnown = !mimeType.isEmpty(); if (!mimeType.isEmpty()) {
if (d->m_bMimeTypeKnown) {
d->m_pMimeType = KMimeType::mimeType(mimeType); d->m_pMimeType = KMimeType::mimeType(mimeType);
} }
} }
@ -353,10 +338,9 @@ void KFileItem::refresh()
d->m_permissions = KFileItem::Unknown; d->m_permissions = KFileItem::Unknown;
refreshMimeType(); refreshMimeType();
// Basically, we can't trust any information we got while listing. // basically, can't trust any information while listing. everything could have changed.
// Everything could have changed... // clearing m_entry makes it possible to detect changes in the size of the file, the time
// Clearing m_entry makes it possible to detect changes in the size of the file, // information, etc.
// the time information, etc.
d->m_entry.clear(); d->m_entry.clear();
d->init(); d->init();
} }
@ -367,8 +351,7 @@ void KFileItem::refreshMimeType()
return; return;
} }
d->m_pMimeType = 0; d->m_pMimeType = nullptr;
d->m_bMimeTypeKnown = false;
d->m_iconName.clear(); d->m_iconName.clear();
} }
@ -409,7 +392,7 @@ QString KFileItem::linkDest() const
return linkStr; return linkStr;
} }
// If not in the KIO::UDSEntry, or if UDSEntry empty, use readlink() [if local URL] // If not in the KIO::UDSEntry or if UDSEntry empty use readlink() [if local URL]
if (d->m_bIsLocalUrl) { if (d->m_bIsLocalUrl) {
char buf[1000]; char buf[1000];
int n = readlink(QFile::encodeName(d->m_url.toLocalFile(KUrl::RemoveTrailingSlash)), buf, sizeof(buf) - 1); int n = readlink(QFile::encodeName(d->m_url.toLocalFile(KUrl::RemoveTrailingSlash)), buf, sizeof(buf) - 1);
@ -421,20 +404,15 @@ QString KFileItem::linkDest() const
return QString(); return QString();
} }
QString KFileItemPrivate::localPath() const
{
if (m_bIsLocalUrl) {
return m_url.toLocalFile();
}
return QString();
}
QString KFileItem::localPath() const QString KFileItem::localPath() const
{ {
if (!d) { if (!d) {
return QString(); return QString();
} }
return d->localPath(); if (d->m_bIsLocalUrl) {
return d->m_url.toLocalFile();
}
return QString();
} }
KIO::filesize_t KFileItem::size() const KIO::filesize_t KFileItem::size() const
@ -559,83 +537,18 @@ QString KFileItemPrivate::group() const
return groupName; return groupName;
} }
bool KFileItemPrivate::isSlow() const
{
if (m_slow == SlowUnknown) {
const QString path = localPath();
if (!path.isEmpty()) {
const KFileSystemType::Type fsType = KFileSystemType::fileSystemType(path);
m_slow = (fsType == KFileSystemType::Nfs || fsType == KFileSystemType::Smb) ? Slow : Fast;
} else {
m_slow = Slow;
}
}
return m_slow == Slow;
}
bool KFileItem::isSlow() const
{
if (!d) {
return false;
}
return d->isSlow();
}
QString KFileItem::mimetype() const QString KFileItem::mimetype() const
{ {
if (!d) { if (!d) {
return QString(); return QString();
} }
KFileItem* that = const_cast<KFileItem *>(this); KMimeType::Ptr mime = mimeTypePtr();
KMimeType::Ptr mime = that->determineMimeType();
if (!mime) { if (!mime) {
return QString(); return QString();
} }
return mime->name(); return mime->name();
} }
KMimeType::Ptr KFileItem::determineMimeType() const
{
if (!d) {
return KMimeType::Ptr();
}
if (!d->m_pMimeType || !d->m_bMimeTypeKnown) {
d->m_pMimeType = KMimeType::findByUrl(d->m_url, d->m_fileMode, !d->m_url.isLocalFile());
Q_ASSERT(d->m_pMimeType);
// kDebug() << d << "finding final mimetype for" << url << ":" << d->m_pMimeType->name();
d->m_bMimeTypeKnown = true;
}
if (d->m_delayedMimeTypes) {
// if we delayed getting the iconName up till now, this is the right point in time to do so
d->m_delayedMimeTypes = false;
d->m_useIconNameCache = false;
(void)iconName();
}
return d->m_pMimeType;
}
bool KFileItem::isMimeTypeKnown() const
{
if (!d) {
return false;
}
// The mimetype isn't known if determineMimeType was never called (on-demand determination)
// or if this fileitem has a guessed mimetype (e.g. ftp symlink) - in which case
// it always remains "not fully determined"
return (d->m_bMimeTypeKnown && d->m_guessedMimeType.isEmpty());
}
bool KFileItem::isFinalIconKnown() const
{
if (!d) {
return false;
}
return (d->m_bMimeTypeKnown && !d->m_delayedMimeTypes);
}
QString KFileItem::mimeComment() const QString KFileItem::mimeComment() const
{ {
if (!d) { if (!d) {
@ -647,10 +560,10 @@ QString KFileItem::mimeComment() const
return displayType; return displayType;
} }
KMimeType::Ptr mime = determineMimeType(); KMimeType::Ptr mime = mimeTypePtr();
// This cannot move to kio_file (with UDS_DISPLAY_TYPE) because it needs // This cannot move to kio_file (with UDS_DISPLAY_TYPE) because it needs
// the mimetype to be determined, which is done here, and possibly delayed... // the mimetype to be determined, which is done here, and possibly delayed...
if (d->m_url.isLocalFile() && !d->isSlow() && mime->is("application/x-desktop")) { if (d->m_bIsLocalUrl && mime->is("application/x-desktop")) {
KDesktopFile cfg(d->m_url.toLocalFile()); KDesktopFile cfg(d->m_url.toLocalFile());
QString comment = cfg.desktopGroup().readEntry("Comment"); QString comment = cfg.desktopGroup().readEntry("Comment");
if (!comment.isEmpty()) { if (!comment.isEmpty()) {
@ -658,7 +571,7 @@ QString KFileItem::mimeComment() const
} }
} }
QString comment = d->isSlow() ? mime->comment() : mime->comment(d->m_url); QString comment = mime->comment(d->m_url);
// kDebug() << "finding comment for " << d->m_url.url() << " : " << d->m_pMimeType->name(); // kDebug() << "finding comment for " << d->m_url.url() << " : " << d->m_pMimeType->name();
if (!comment.isEmpty()) { if (!comment.isEmpty()) {
return comment; return comment;
@ -666,43 +579,18 @@ QString KFileItem::mimeComment() const
return mime->name(); return mime->name();
} }
static QString iconFromDesktopFile(const QString &path)
{
KDesktopFile cfg(path);
const QString icon = cfg.readIcon();
if (cfg.hasLinkType()) {
const KConfigGroup group = cfg.desktopGroup();
const QString type = cfg.readPath();
const QString emptyIcon = group.readEntry("EmptyIcon");
if (!emptyIcon.isEmpty()) {
const QString u = cfg.readUrl();
const KUrl url(u);
if (url.protocol() == "trash") {
// We need to find if the trash is empty, preferably without using a KIO job.
// So instead kio_trash leaves an entry in its config file for us.
KConfig trashConfig("trashrc", KConfig::SimpleConfig);
if (trashConfig.group("Status").readEntry("Empty", true)) {
return emptyIcon;
}
}
}
}
return icon;
}
QString KFileItem::iconName() const QString KFileItem::iconName() const
{ {
if (!d) { if (!d) {
return QString(); return QString();
} }
if (d->m_useIconNameCache && !d->m_iconName.isEmpty()) { if (!d->m_iconName.isEmpty()) {
return d->m_iconName; return d->m_iconName;
} }
d->m_iconName = d->m_entry.stringValue(KIO::UDSEntry::UDS_ICON_NAME); d->m_iconName = d->m_entry.stringValue(KIO::UDSEntry::UDS_ICON_NAME);
if (!d->m_iconName.isEmpty()) { if (!d->m_iconName.isEmpty()) {
d->m_useIconNameCache = d->m_bMimeTypeKnown;
return d->m_iconName; return d->m_iconName;
} }
@ -714,51 +602,36 @@ QString KFileItem::iconName() const
mime = mimeTypePtr(); mime = mimeTypePtr();
} }
const bool delaySlowOperations = d->m_delayedMimeTypes; if (d->m_bIsLocalUrl && isDesktopFile()) {
if (d->m_url.isLocalFile() && !delaySlowOperations && mime->is("application/x-desktop")) { KDesktopFile cfg(d->m_url.toLocalFile());
d->m_iconName = iconFromDesktopFile(d->m_url.toLocalFile()); d->m_iconName = cfg.readIcon();
if (cfg.hasLinkType()) {
const KConfigGroup group = cfg.desktopGroup();
const QString type = cfg.readPath();
const QString emptyIcon = group.readEntry("EmptyIcon");
if (!emptyIcon.isEmpty()) {
const QString u = cfg.readUrl();
const KUrl url(u);
if (url.protocol() == "trash") {
// We need to find if the trash is empty, preferably without using a KIO job.
// So instead kio_trash leaves an entry in its config file for us.
KConfig trashConfig("trashrc", KConfig::SimpleConfig);
if (trashConfig.group("Status").readEntry("Empty", true)) {
d->m_iconName = emptyIcon;
}
}
}
}
if (!d->m_iconName.isEmpty()) { if (!d->m_iconName.isEmpty()) {
d->m_useIconNameCache = d->m_bMimeTypeKnown;
return d->m_iconName; return d->m_iconName;
} }
} }
if (delaySlowOperations) {
d->m_iconName = mime->iconName();
} else {
d->m_iconName = mime->iconName(d->m_url);
}
d->m_useIconNameCache = d->m_bMimeTypeKnown;
// kDebug() << "finding icon for" << d->m_url << ":" << d->m_iconName; // kDebug() << "finding icon for" << d->m_url << ":" << d->m_iconName;
d->m_iconName = mime->iconName(d->m_url);
return d->m_iconName; return d->m_iconName;
} }
/**
* Returns true if this is a desktop file.
* Mimetype determination is optional.
*/
static bool checkDesktopFile(const KFileItem &item, bool _determineMimeType)
{
// only regular files
if (!item.isRegularFile()) {
return false;
}
// only local files
if (!item.url().isLocalFile()) {
return false;
}
// only if readable
if (!item.isReadable()) {
return false;
}
// return true if desktop file
KMimeType::Ptr mime = _determineMimeType ? item.determineMimeType() : item.mimeTypePtr();
return mime->is("application/x-desktop");
}
QStringList KFileItem::overlays() const QStringList KFileItem::overlays() const
{ {
if (!d) { if (!d) {
@ -775,7 +648,7 @@ QStringList KFileItem::overlays() const
names.append("object-locked"); names.append("object-locked");
} }
if (checkDesktopFile(*this, false)) { if (d->m_bIsLocalUrl && isDesktopFile()) {
KDesktopFile cfg(localPath()); KDesktopFile cfg(localPath());
const KConfigGroup group = cfg.desktopGroup(); const KConfigGroup group = cfg.desktopGroup();
@ -1180,7 +1053,7 @@ QDataStream& operator>>(QDataStream &s, KFileItem &a)
a.d->m_strName = strName; a.d->m_strName = strName;
a.d->m_strText = strText; a.d->m_strText = strText;
a.d->m_bIsLocalUrl = a.d->m_url.isLocalFile(); a.d->m_bIsLocalUrl = a.d->m_url.isLocalFile();
a.d->m_bMimeTypeKnown = false; a.d->m_pMimeType = nullptr;
a.refresh(); a.refresh();
return s; return s;
@ -1260,18 +1133,6 @@ KUrl KFileItem::targetUrl() const
return url(); return url();
} }
/*
* Mimetype handling.
*
* Initial state: m_pMimeType = 0.
* When mimeTypePtr() is called first: fast mimetype determination,
* might either find an accurate mimetype (-> Final state), otherwise we
* set m_pMimeType but not m_bMimeTypeKnown (-> Intermediate state)
* Intermediate state: determineMimeType() does the real determination -> Final state.
*
* If delayedMimeTypes isn't set, then we always go to the Final state directly.
*/
KMimeType::Ptr KFileItem::mimeTypePtr() const KMimeType::Ptr KFileItem::mimeTypePtr() const
{ {
if (!d) { if (!d) {
@ -1283,13 +1144,8 @@ KMimeType::Ptr KFileItem::mimeTypePtr() const
d->m_pMimeType = KMimeType::findByUrl( d->m_pMimeType = KMimeType::findByUrl(
d->m_url, d->m_fileMode, d->m_url, d->m_fileMode,
// use fast mode if delayed mimetype determination can refine it later // use fast mode if delayed mimetype determination can refine it later
d->m_delayedMimeTypes !d->m_bIsLocalUrl
); );
// If it was not a perfect (glob and content-based) match,
// then determineMimeType will be able to do better for readable URLs.
const bool canDoBetter = d->m_delayedMimeTypes;
//kDebug() << "finding mimetype for" << d->m_url << ":" << d->m_pMimeType->name() << "canDoBetter=" << canDoBetter;
d->m_bMimeTypeKnown = !canDoBetter;
} }
return d->m_pMimeType; return d->m_pMimeType;
} }
@ -1398,7 +1254,12 @@ KUrl::List KFileItemList::targetUrlList() const
bool KFileItem::isDesktopFile() const bool KFileItem::isDesktopFile() const
{ {
return checkDesktopFile(*this, true); // return true if desktop file
KMimeType::Ptr mime = mimeTypePtr();
if (!mime) {
return false;
}
return mime->is("application/x-desktop");
} }
bool KFileItem::isRegularFile() const bool KFileItem::isRegularFile() const

View file

@ -71,17 +71,13 @@ public:
* *
* @param entry the KIO entry used to get the file, contains info about it * @param entry the KIO entry used to get the file, contains info about it
* @param itemOrDirUrl the URL of the item or of the directory containing this item (see urlIsDirectory). * @param itemOrDirUrl the URL of the item or of the directory containing this item (see urlIsDirectory).
* @param delayedMimeTypes specifies if the mimetype of the given
* URL should be determined immediately or on demand.
* See the bool delayedMimeTypes in the KDirLister constructor.
* @param urlIsDirectory specifies if the url is just the directory of the * @param urlIsDirectory specifies if the url is just the directory of the
* fileitem and the filename from the UDSEntry should be used. * fileitem and the filename from the UDSEntry should be used.
* *
* When creating KFileItems out of the UDSEntry emitted by a KIO list job, * When creating KFileItems out of the UDSEntry emitted by a KIO list job,
* use KFileItem(entry, listjob->url(), delayedMimeTypes, true); * use KFileItem(entry, listjob->url(), true);
*/ */
KFileItem(const KIO::UDSEntry &entry, const KUrl &itemOrDirUrl, KFileItem(const KIO::UDSEntry &entry, const KUrl &itemOrDirUrl,
bool delayedMimeTypes = false,
bool urlIsDirectory = false ); bool urlIsDirectory = false );
/** /**
@ -93,12 +89,8 @@ public:
* local files. * local files.
* Set to KFileItem::Unknown if you don't know the mode or the permission. * Set to KFileItem::Unknown if you don't know the mode or the permission.
* @param url the file url * @param url the file url
*
* @param delayedMimeTypes specify if the mimetype of the given URL
* should be determined immediately or on demand
*/ */
KFileItem(mode_t mode, mode_t permissions, const KUrl &url, KFileItem(mode_t mode, mode_t permissions, const KUrl &url);
bool delayedMimeTypes = false);
/** /**
* Creates an item representing a file, for which the mimetype is already known. * Creates an item representing a file, for which the mimetype is already known.
@ -245,13 +237,6 @@ public:
*/ */
bool isHidden() const; bool isHidden() const;
/**
* @return true if the file is a remote URL, or a local file on a network mount.
* It will return false only for really-local file systems.
* @since 4.7.4
*/
bool isSlow() const;
/** /**
* Checks whether the file is a readable local .desktop file, * Checks whether the file is a readable local .desktop file,
* i.e. a file whose path can be given to KDesktopFile * i.e. a file whose path can be given to KDesktopFile
@ -327,21 +312,11 @@ public:
QString name(bool lowerCase = false) const; QString name(bool lowerCase = false) const;
/** /**
* Returns the mimetype of the file item. * Returns the mimetype of the file item. Equivalent to mimeTypePtr()->name()
* If @p delayedMimeTypes was used in the constructor, this will determine
* the mimetype first. Equivalent to determineMimeType()->name()
* @return the mime type of the file * @return the mime type of the file
*/ */
QString mimetype() const; QString mimetype() const;
/**
* Returns the mimetype of the file item.
* If delayedMimeTypes was used in the constructor, this will determine
* the mimetype first.
* @return the mime type
*/
KMimeType::Ptr determineMimeType() const;
/** /**
* Returns the currently known mimetype of the file item. * Returns the currently known mimetype of the file item.
* This will not try to determine the mimetype if unknown. * This will not try to determine the mimetype if unknown.
@ -349,20 +324,6 @@ public:
*/ */
KMimeType::Ptr mimeTypePtr() const; KMimeType::Ptr mimeTypePtr() const;
/**
* @return true if we have determined the final icon of this file already.
* @since 4.10.2
*/
bool isFinalIconKnown() const;
/**
* @return true if we have determined the mimetype of this file already,
* i.e. if determineMimeType() will be fast. Otherwise it will have to
* find what the mimetype is, which is a possibly slow operation; usually
* this is delayed until necessary.
*/
bool isMimeTypeKnown() const;
/** /**
* Returns the user-readable string representing the type of this file, * Returns the user-readable string representing the type of this file,
* like "OpenDocument Text File". * like "OpenDocument Text File".

View file

@ -263,11 +263,11 @@ QString KFileItemDelegate::Private::information(const QStyleOptionViewItem &opti
break; break;
case KFileItemDelegate::MimeType: case KFileItemDelegate::MimeType:
string += item.isMimeTypeKnown() ? item.mimetype() : i18nc("@info mimetype","Unknown"); string += item.mimeTypePtr() ? item.mimetype() : i18nc("@info mimetype","Unknown");
break; break;
case KFileItemDelegate::FriendlyMimeType: case KFileItemDelegate::FriendlyMimeType:
string += item.isMimeTypeKnown() ? item.mimeComment() : i18nc("@info mimetype","Unknown"); string += item.mimeTypePtr() ? item.mimeComment() : i18nc("@info mimetype","Unknown");
break; break;
case KFileItemDelegate::LinkDest: case KFileItemDelegate::LinkDest:

View file

@ -141,12 +141,6 @@ class KIO_EXPORT KFileItemDelegate : public QAbstractItemDelegate
* For the number of items to be shown for folders, the model must provide a valid * For the number of items to be shown for folders, the model must provide a valid
* value for KDirMode::ChildCountRole, in addition to KDirModel::FileItemRole. * value for KDirMode::ChildCountRole, in addition to KDirModel::FileItemRole.
* *
* Note that KFileItemDelegate will not call KFileItem::determineMimeType() if
* KFileItem::isMimeTypeKnown() returns false, so if you want to display mime types
* you should use a KMimeTypeResolver with the model and the view, to ensure that mime
* types are resolved. If the mime type isn't known, "Unknown" will be displayed until
* the mime type has been successfully resolved.
*
* @see setShowInformation() * @see setShowInformation()
* @see showInformation() * @see showInformation()
* @see information * @see information
@ -289,7 +283,6 @@ class KIO_EXPORT KFileItemDelegate : public QAbstractItemDelegate
*/ */
InformationList showInformation() const; InformationList showInformation() const;
/** /**
* Sets the color used for drawing the text shadow. * Sets the color used for drawing the text shadow.
* *

View file

@ -175,12 +175,10 @@ void KFileItemTest::testMimeTypeOnDemand()
KFileItem fileItem(KFileItem::Unknown, KFileItem::Unknown, KUrl(file.fileName()), true /*on demand*/); KFileItem fileItem(KFileItem::Unknown, KFileItem::Unknown, KUrl(file.fileName()), true /*on demand*/);
QCOMPARE(fileItem.mimeTypePtr()->name(), KMimeType::defaultMimeType()); QCOMPARE(fileItem.mimeTypePtr()->name(), KMimeType::defaultMimeType());
QVERIFY(!fileItem.isMimeTypeKnown()); QVERIFY(!fileItem.isMimeTypeKnown());
QVERIFY(!fileItem.isFinalIconKnown());
//kDebug() << fileItem.determineMimeType()->name(); //kDebug() << fileItem.determineMimeType()->name();
QCOMPARE(fileItem.determineMimeType()->name(), QString("application/x-zerosize")); QCOMPARE(fileItem.determineMimeType()->name(), QString("application/x-zerosize"));
QCOMPARE(fileItem.mimetype(), QString("application/x-zerosize")); QCOMPARE(fileItem.mimetype(), QString("application/x-zerosize"));
QVERIFY(fileItem.isMimeTypeKnown()); QVERIFY(fileItem.isMimeTypeKnown());
QVERIFY(fileItem.isFinalIconKnown());
} }
{ {