diff --git a/autotests/kfileitemtest.cpp b/autotests/kfileitemtest.cpp index ea38789b..95423fb7 100644 --- a/autotests/kfileitemtest.cpp +++ b/autotests/kfileitemtest.cpp @@ -1,664 +1,667 @@ /* This file is part of the KDE project Copyright (C) 2006 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 "kfileitemtest.h" #include #include #include #include #include #include #include #include #include "kiotesthelper.h" #include QTEST_MAIN(KFileItemTest) void KFileItemTest::initTestCase() { } void KFileItemTest::testPermissionsString() { // Directory QTemporaryDir tempDir; KFileItem dirItem(QUrl::fromLocalFile(tempDir.path() + '/')); QCOMPARE((uint)dirItem.permissions(), (uint)0700); QCOMPARE(dirItem.permissionsString(), QStringLiteral("drwx------")); QVERIFY(dirItem.isReadable()); // File QFile file(tempDir.path() + "/afile"); QVERIFY(file.open(QIODevice::WriteOnly)); file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadOther); // 0604 KFileItem fileItem(QUrl::fromLocalFile(file.fileName()), QString(), KFileItem::Unknown); QCOMPARE((uint)fileItem.permissions(), (uint)0604); QCOMPARE(fileItem.permissionsString(), QStringLiteral("-rw----r--")); QVERIFY(fileItem.isReadable()); // Symlink to file QString symlink = tempDir.path() + "/asymlink"; QVERIFY(file.link(symlink)); QUrl symlinkUrl = QUrl::fromLocalFile(symlink); KFileItem symlinkItem(symlinkUrl, QString(), KFileItem::Unknown); QCOMPARE((uint)symlinkItem.permissions(), (uint)0604); // This is a bit different from "ls -l": we get the 'l' but we see the permissions of the target. // This is actually useful though; the user sees it's a link, and can check if he can read the [target] file. QCOMPARE(symlinkItem.permissionsString(), QStringLiteral("lrw----r--")); QVERIFY(symlinkItem.isReadable()); // Symlink to directory (#162544) QVERIFY(QFile::remove(symlink)); QVERIFY(QFile(tempDir.path() + '/').link(symlink)); KFileItem symlinkToDirItem(symlinkUrl, QString(), KFileItem::Unknown); QCOMPARE((uint)symlinkToDirItem.permissions(), (uint)0700); QCOMPARE(symlinkToDirItem.permissionsString(), QStringLiteral("lrwx------")); } void KFileItemTest::testNull() { KFileItem null; QVERIFY(null.isNull()); KFileItem fileItem(QUrl::fromLocalFile(QStringLiteral("/")), QString(), KFileItem::Unknown); QVERIFY(!fileItem.isNull()); null = fileItem; // ok, now 'null' isn't so null anymore QVERIFY(!null.isNull()); QVERIFY(null.isReadable()); QVERIFY(!null.isHidden()); } void KFileItemTest::testDoesNotExist() { KFileItem fileItem(QUrl::fromLocalFile(QStringLiteral("/doesnotexist")), QString(), KFileItem::Unknown); QVERIFY(!fileItem.isNull()); QVERIFY(!fileItem.isReadable()); QVERIFY(fileItem.user().isEmpty()); QVERIFY(fileItem.group().isEmpty()); } void KFileItemTest::testDetach() { KFileItem fileItem(QUrl::fromLocalFile(QStringLiteral("/one")), QString(), KFileItem::Unknown); QCOMPARE(fileItem.name(), QStringLiteral("one")); KFileItem fileItem2(fileItem); QVERIFY(fileItem == fileItem2); QVERIFY(fileItem.d == fileItem2.d); fileItem2.setName(QStringLiteral("two")); QCOMPARE(fileItem2.name(), QStringLiteral("two")); QCOMPARE(fileItem.name(), QStringLiteral("one")); // it detached QVERIFY(fileItem == fileItem2); QVERIFY(fileItem.d != fileItem2.d); fileItem = fileItem2; QCOMPARE(fileItem.name(), QStringLiteral("two")); QVERIFY(fileItem == fileItem2); QVERIFY(fileItem.d == fileItem2.d); QVERIFY(!(fileItem != fileItem2)); } void KFileItemTest::testMove() { // Test move constructor { KFileItem fileItem(QUrl::fromLocalFile(QStringLiteral("/one")), QString(), KFileItem::Unknown); QCOMPARE(fileItem.name(), QStringLiteral("one")); KFileItem fileItem2(std::move(fileItem)); QCOMPARE(fileItem2.name(), QStringLiteral("one")); } // Test move assignment { KFileItem fileItem(QUrl::fromLocalFile(QStringLiteral("/one")), QString(), KFileItem::Unknown); QCOMPARE(fileItem.name(), QStringLiteral("one")); KFileItem fileItem2(QUrl::fromLocalFile(QStringLiteral("/two")), QString(), KFileItem::Unknown); fileItem2 = std::move(fileItem); QCOMPARE(fileItem2.name(), QStringLiteral("one")); } // Now to test some value changes to make sure moving works as intended. KFileItem fileItem(QUrl::fromLocalFile(QStringLiteral("/one")), QString(), KFileItem::Unknown); QCOMPARE(fileItem.name(), QStringLiteral("one")); fileItem.setUrl(QUrl::fromLocalFile(QStringLiteral("/two"))); QCOMPARE(fileItem.name(), QStringLiteral("two")); // Move fileitem to fileItem2, it should now contain everything fileItem had. // Just testing a property to make sure it does. KFileItem fileItem2(std::move(fileItem)); QCOMPARE(fileItem2.name(), QStringLiteral("two")); } void KFileItemTest::testBasic() { QTemporaryFile file; QVERIFY(file.open()); QFile fileObj(file.fileName()); QVERIFY(fileObj.open(QIODevice::WriteOnly)); fileObj.write(QByteArray("Hello")); fileObj.close(); QUrl url = QUrl::fromLocalFile(file.fileName()); KFileItem fileItem(url, QString(), KFileItem::Unknown); QCOMPARE(fileItem.text(), url.fileName()); QVERIFY(fileItem.isLocalFile()); QCOMPARE(fileItem.localPath(), url.toLocalFile()); QCOMPARE(fileItem.size(), KIO::filesize_t(5)); QVERIFY(fileItem.linkDest().isEmpty()); QVERIFY(!fileItem.isHidden()); QVERIFY(fileItem.isReadable()); QVERIFY(fileItem.isWritable()); QVERIFY(fileItem.isFile()); QVERIFY(!fileItem.isDir()); QVERIFY(!fileItem.isDesktopFile()); #ifndef Q_OS_WIN QCOMPARE(fileItem.user(), KUser().loginName()); #endif } void KFileItemTest::testRootDirectory() { const QString rootPath = QDir::rootPath(); QUrl url = QUrl::fromLocalFile(rootPath); KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, QStringLiteral(".")); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); KFileItem fileItem(entry, url); QCOMPARE(fileItem.text(), QStringLiteral(".")); QVERIFY(fileItem.isLocalFile()); QCOMPARE(fileItem.localPath(), url.toLocalFile()); QVERIFY(fileItem.linkDest().isEmpty()); QVERIFY(!fileItem.isHidden()); QVERIFY(!fileItem.isFile()); QVERIFY(fileItem.isDir()); QVERIFY(!fileItem.isDesktopFile()); } void KFileItemTest::testHiddenFile() { QTemporaryDir tempDir; QFile file(tempDir.path() + "/.hiddenfile"); QVERIFY(file.open(QIODevice::WriteOnly)); KFileItem fileItem(QUrl::fromLocalFile(file.fileName()), QString(), KFileItem::Unknown); QCOMPARE(fileItem.text(), QStringLiteral(".hiddenfile")); QVERIFY(fileItem.isLocalFile()); QVERIFY(fileItem.isHidden()); } void KFileItemTest::testMimeTypeOnDemand() { QTemporaryFile file; QVERIFY(file.open()); { KFileItem fileItem(QUrl::fromLocalFile(file.fileName())); fileItem.setDelayedMimeTypes(true); QVERIFY(fileItem.currentMimeType().isDefault()); QVERIFY(!fileItem.isMimeTypeKnown()); QVERIFY(!fileItem.isFinalIconKnown()); //qDebug() << fileItem.determineMimeType().name(); QCOMPARE(fileItem.determineMimeType().name(), QStringLiteral("application/x-zerosize")); QCOMPARE(fileItem.mimetype(), QStringLiteral("application/x-zerosize")); QVERIFY(fileItem.isMimeTypeKnown()); QVERIFY(fileItem.isFinalIconKnown()); } { // Calling mimeType directly also does mimetype determination KFileItem fileItem(QUrl::fromLocalFile(file.fileName())); fileItem.setDelayedMimeTypes(true); QVERIFY(!fileItem.isMimeTypeKnown()); QCOMPARE(fileItem.mimetype(), QStringLiteral("application/x-zerosize")); QVERIFY(fileItem.isMimeTypeKnown()); } { // Calling overlays should NOT do mimetype determination (#237668) KFileItem fileItem(QUrl::fromLocalFile(file.fileName())); fileItem.setDelayedMimeTypes(true); QVERIFY(!fileItem.isMimeTypeKnown()); fileItem.overlays(); QVERIFY(!fileItem.isMimeTypeKnown()); } { QTemporaryFile file; QVERIFY(file.open()); // Check whether mime-magic is used. // No known extension, so it should be used by determineMimeType. file.write(QByteArray("%PDF-")); QString fileName = file.fileName(); QVERIFY(!fileName.isEmpty()); file.close(); KFileItem fileItem(QUrl::fromLocalFile(fileName)); fileItem.setDelayedMimeTypes(true); QCOMPARE(fileItem.currentMimeType().name(), QLatin1String("application/octet-stream")); QVERIFY(fileItem.currentMimeType().isValid()); QVERIFY(fileItem.currentMimeType().isDefault()); QVERIFY(!fileItem.isMimeTypeKnown()); QCOMPARE(fileItem.determineMimeType().name(), QStringLiteral("application/pdf")); QCOMPARE(fileItem.mimetype(), QStringLiteral("application/pdf")); } { QTemporaryFile file(QDir::tempPath() + QLatin1String("/kfileitemtest_XXXXXX.txt")); QVERIFY(file.open()); // Check whether mime-magic is used. // Known extension, so it should NOT be used. file.write(QByteArray("("filename"); QTest::addColumn("expectedText"); QTest::newRow("simple") << "filename" << "filename"; QTest::newRow("/ at end") << QString(QStringLiteral("foo") + QChar(0x2044)) << QString(QStringLiteral("foo") + QChar(0x2044)); QTest::newRow("/ at begin") << QString(QChar(0x2044)) << QString(QChar(0x2044)); } void KFileItemTest::testDecodeFileName() { QFETCH(QString, filename); QFETCH(QString, expectedText); QCOMPARE(KIO::decodeFileName(filename), expectedText); } void KFileItemTest::testEncodeFileName_data() { QTest::addColumn("text"); QTest::addColumn("expectedFileName"); QTest::newRow("simple") << "filename" << "filename"; QTest::newRow("/ at end") << "foo/" << QString(QStringLiteral("foo") + QChar(0x2044)); QTest::newRow("/ at begin") << "/" << QString(QChar(0x2044)); } void KFileItemTest::testEncodeFileName() { QFETCH(QString, text); QFETCH(QString, expectedFileName); QCOMPARE(KIO::encodeFileName(text), expectedFileName); } void KFileItemTest::testListProperties_data() { QTest::addColumn("itemDescriptions"); QTest::addColumn("expectedReading"); QTest::addColumn("expectedDeleting"); QTest::addColumn("expectedIsLocal"); QTest::addColumn("expectedIsDirectory"); + QTest::addColumn("expectedIsFile"); QTest::addColumn("expectedMimeType"); QTest::addColumn("expectedMimeGroup"); - QTest::newRow("one file") << "f" << true << true << true << false << "text/plain" << "text"; - QTest::newRow("one dir") << "d" << true << true << true << true << "inode/directory" << "inode"; - QTest::newRow("root dir") << "/" << true << false << true << true << "inode/directory" << "inode"; - QTest::newRow("file+dir") << "fd" << true << true << true << false << "" << ""; - QTest::newRow("two dirs") << "dd" << true << true << true << true << "inode/directory" << "inode"; - QTest::newRow("dir+root dir") << "d/" << true << false << true << true << "inode/directory" << "inode"; - QTest::newRow("two (text+html) files") << "ff" << true << true << true << false << "" << "text"; - QTest::newRow("three (text+html+empty) files") << "fff" << true << true << true << false << "" << ""; + QTest::newRow("one file") << "f" << true << true << true << false << true << "text/plain" << "text"; + QTest::newRow("one dir") << "d" << true << true << true << true << false << "inode/directory" << "inode"; + QTest::newRow("root dir") << "/" << true << false << true << true << false << "inode/directory" << "inode"; + QTest::newRow("file+dir") << "fd" << true << true << true << false << false << "" << ""; + QTest::newRow("two dirs") << "dd" << true << true << true << true << false << "inode/directory" << "inode"; + QTest::newRow("dir+root dir") << "d/" << true << false << true << true << false << "inode/directory" << "inode"; + QTest::newRow("two (text+html) files") << "ff" << true << true << true << false << true << "" << "text"; + QTest::newRow("three (text+html+empty) files") << "fff" << true << true << true << false << true << "" << ""; QTest::newRow("http url") << "h" << true << true /*says kio_http...*/ - << false << false << "application/octet-stream" << "application"; + << false << false << true << "application/octet-stream" << "application"; QTest::newRow("2 http urls") << "hh" << true << true /*says kio_http...*/ - << false << false << "application/octet-stream" << "application"; + << false << false << true << "application/octet-stream" << "application"; } void KFileItemTest::testListProperties() { QFETCH(QString, itemDescriptions); QFETCH(bool, expectedReading); QFETCH(bool, expectedDeleting); QFETCH(bool, expectedIsLocal); QFETCH(bool, expectedIsDirectory); + QFETCH(bool, expectedIsFile); QFETCH(QString, expectedMimeType); QFETCH(QString, expectedMimeGroup); QTemporaryDir tempDir; QDir baseDir(tempDir.path()); KFileItemList items; for (int i = 0; i < itemDescriptions.size(); ++i) { QString fileName = tempDir.path() + "/file" + QString::number(i); switch (itemDescriptions[i].toLatin1()) { case 'f': { if (i == 1) { // 2nd file is html fileName += QLatin1String(".html"); } QFile file(fileName); QVERIFY(file.open(QIODevice::WriteOnly)); if (i != 2) { // 3rd file is empty file.write("Hello"); } items << KFileItem(QUrl::fromLocalFile(fileName), QString(), KFileItem::Unknown); } break; case 'd': QVERIFY(baseDir.mkdir(fileName)); items << KFileItem(QUrl::fromLocalFile(fileName), QString(), KFileItem::Unknown); break; case '/': items << KFileItem(QUrl::fromLocalFile(QStringLiteral("/")), QString(), KFileItem::Unknown); break; case 'h': items << KFileItem(QUrl(QStringLiteral("http://www.kde.org")), QString(), KFileItem::Unknown); break; default: QVERIFY(false); } } KFileItemListProperties props(items); QCOMPARE(props.supportsReading(), expectedReading); QCOMPARE(props.supportsDeleting(), expectedDeleting); QCOMPARE(props.isLocal(), expectedIsLocal); QCOMPARE(props.isDirectory(), expectedIsDirectory); + QCOMPARE(props.isFile(), expectedIsFile); QCOMPARE(props.mimeType(), expectedMimeType); QCOMPARE(props.mimeGroup(), expectedMimeGroup); } void KFileItemTest::testIconNameForUrl_data() { QTest::addColumn("url"); QTest::addColumn("expectedIcon"); QTest::newRow("root") << QUrl("file:/") << "folder"; // the icon comes from KProtocolInfo if (QFile::exists(QStringLiteral("/tmp"))) { QTest::newRow("subdir") << QUrl::fromLocalFile("/tmp") << "folder-temp"; } QTest::newRow("home") << QUrl::fromLocalFile(QDir::homePath()) << "user-home"; const QString moviesPath = QStandardPaths::standardLocations(QStandardPaths::MoviesLocation).first(); if (QFileInfo::exists(moviesPath)) { QTest::newRow("videos") << QUrl::fromLocalFile(moviesPath) << (moviesPath == QDir::homePath() ? "user-home" : "folder-videos"); } QTest::newRow("empty") << QUrl() << "unknown"; QTest::newRow("relative") << QUrl("foo") << "unknown"; QTest::newRow("tilde") << QUrl("~") << "unknown"; // TODO more tests } void KFileItemTest::testIconNameForUrl() { QFETCH(QUrl, url); QFETCH(QString, expectedIcon); if (KIO::iconNameForUrl(url) != expectedIcon) { qDebug() << url; QCOMPARE(KIO::iconNameForUrl(url), expectedIcon); } } void KFileItemTest::testMimetypeForRemoteFolder() { KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, QStringLiteral("foo")); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); QUrl url(QStringLiteral("smb://remoteFolder/foo")); KFileItem fileItem(entry, url); QCOMPARE(fileItem.mimetype(), QStringLiteral("inode/directory")); } void KFileItemTest::testMimetypeForRemoteFolderWithFileType() { QString udsMimeType = QStringLiteral("application/x-smb-workgroup"); QVERIFY2(QMimeDatabase().mimeTypeForName(udsMimeType).isValid(), qPrintable(QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation).join(':'))); // kcoreaddons installed? XDG_DATA_DIRS set? KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, QStringLiteral("foo")); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, udsMimeType); QUrl url(QStringLiteral("smb://remoteFolder/foo")); KFileItem fileItem(entry, url); QCOMPARE(fileItem.mimetype(), udsMimeType); } void KFileItemTest::testCurrentMimetypeForRemoteFolder() { KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, QStringLiteral("foo")); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); QUrl url(QStringLiteral("smb://remoteFolder/foo")); KFileItem fileItem(entry, url); QCOMPARE(fileItem.currentMimeType().name(), QStringLiteral("inode/directory")); } void KFileItemTest::testCurrentMimetypeForRemoteFolderWithFileType() { QString udsMimeType = QStringLiteral("application/x-smb-workgroup"); KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, QStringLiteral("foo")); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, udsMimeType); QUrl url(QStringLiteral("smb://remoteFolder/foo")); KFileItem fileItem(entry, url); QCOMPARE(fileItem.currentMimeType().name(), udsMimeType); } void KFileItemTest::testIconNameForCustomFolderIcons() { // Custom folder icons should be displayed (bug 350612) const QString iconName = QStringLiteral("folder-music"); QTemporaryDir tempDir; const QUrl url = QUrl::fromLocalFile(tempDir.path()); KDesktopFile cfg(tempDir.path() + QLatin1String("/.directory")); cfg.desktopGroup().writeEntry("Icon", iconName); cfg.sync(); KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); KFileItem fileItem(entry, url); QCOMPARE(fileItem.iconName(), iconName); } void KFileItemTest::testIconNameForStandardPath() { const QString iconName = QStringLiteral("folder-videos"); const QUrl url = QUrl::fromLocalFile(QDir::homePath() + QLatin1String("/Videos")); QStandardPaths::setTestModeEnabled(true); KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); KFileItem fileItem(entry, url); QCOMPARE(fileItem.iconName(), iconName); } #ifndef Q_OS_WIN // user/group/other write permissions are not handled on windows void KFileItemTest::testIsReadable_data() { QTest::addColumn("mode"); QTest::addColumn("readable"); QTest::newRow("fully-readable") << 0444 << true; QTest::newRow("user-readable") << 0400 << true; QTest::newRow("not-readable-by-us") << 0004 << false; QTest::newRow("not-readable-at-all") << 0000 << false; } void KFileItemTest::testIsReadable() { QFETCH(int, mode); QFETCH(bool, readable); QTemporaryFile file; QVERIFY(file.open()); int ret = fchmod(file.handle(), (mode_t)mode); QCOMPARE(ret, 0); KFileItem fileItem(QUrl::fromLocalFile(file.fileName())); QCOMPARE(fileItem.isReadable(), readable); } #endif diff --git a/src/core/kfileitemlistproperties.cpp b/src/core/kfileitemlistproperties.cpp index 8d0500e6..9121ac51 100644 --- a/src/core/kfileitemlistproperties.cpp +++ b/src/core/kfileitemlistproperties.cpp @@ -1,205 +1,217 @@ /* This file is part of the KDE project Copyright (C) 2008 by Peter Penz Copyright (C) 2008 by George Goldberg Copyright 2009 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. 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 "kfileitemlistproperties.h" #include #include #include class KFileItemListPropertiesPrivate : public QSharedData { public: KFileItemListPropertiesPrivate() : m_isDirectory(false), + m_isFile(false), m_supportsReading(false), m_supportsDeleting(false), m_supportsWriting(false), m_supportsMoving(false), m_isLocal(true) { } void setItems(const KFileItemList &items); void determineMimeTypeAndGroup() const; KFileItemList m_items; mutable QString m_mimeType; mutable QString m_mimeGroup; bool m_isDirectory : 1; + bool m_isFile : 1; bool m_supportsReading : 1; bool m_supportsDeleting : 1; bool m_supportsWriting : 1; bool m_supportsMoving : 1; bool m_isLocal : 1; }; KFileItemListProperties::KFileItemListProperties() : d(new KFileItemListPropertiesPrivate) { } KFileItemListProperties::KFileItemListProperties(const KFileItemList &items) : d(new KFileItemListPropertiesPrivate) { setItems(items); } void KFileItemListProperties::setItems(const KFileItemList &items) { d->setItems(items); } void KFileItemListPropertiesPrivate::setItems(const KFileItemList &items) { const bool initialValue = !items.isEmpty(); m_items = items; m_supportsReading = initialValue; m_supportsDeleting = initialValue; m_supportsWriting = initialValue; m_supportsMoving = initialValue; m_isDirectory = initialValue; + m_isFile = initialValue; m_isLocal = true; m_mimeType.clear(); m_mimeGroup.clear(); QFileInfo parentDirInfo; foreach (const KFileItem &item, items) { const QUrl url = item.url(); m_isLocal = m_isLocal && url.isLocalFile(); m_supportsReading = m_supportsReading && KProtocolManager::supportsReading(url); m_supportsDeleting = m_supportsDeleting && KProtocolManager::supportsDeleting(url); m_supportsWriting = m_supportsWriting && KProtocolManager::supportsWriting(url) && item.isWritable(); m_supportsMoving = m_supportsMoving && KProtocolManager::supportsMoving(url); // For local files we can do better: check if we have write permission in parent directory // TODO: if we knew about the parent KFileItem, we could even do that for remote protocols too #ifndef Q_OS_WIN if (m_isLocal && (m_supportsDeleting || m_supportsMoving)) { const QString directory = url.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).toLocalFile(); if (parentDirInfo.filePath() != directory) { parentDirInfo.setFile(directory); } if (!parentDirInfo.isWritable()) { m_supportsDeleting = false; m_supportsMoving = false; } } #else if (m_isLocal && m_supportsDeleting) { if (!QFileInfo(url.toLocalFile()).isWritable()) m_supportsDeleting = false; } #endif if (m_isDirectory && !item.isDir()) { m_isDirectory = false; } + + if (m_isFile && !item.isFile()) { + m_isFile = false; + } } } KFileItemListProperties::KFileItemListProperties(const KFileItemListProperties &other) : d(other.d) { } KFileItemListProperties &KFileItemListProperties::operator=(const KFileItemListProperties &other) { d = other.d; return *this; } KFileItemListProperties::~KFileItemListProperties() { } bool KFileItemListProperties::supportsReading() const { return d->m_supportsReading; } bool KFileItemListProperties::supportsDeleting() const { return d->m_supportsDeleting; } bool KFileItemListProperties::supportsWriting() const { return d->m_supportsWriting; } bool KFileItemListProperties::supportsMoving() const { return d->m_supportsMoving && d->m_supportsDeleting; } bool KFileItemListProperties::isLocal() const { return d->m_isLocal; } KFileItemList KFileItemListProperties::items() const { return d->m_items; } QList KFileItemListProperties::urlList() const { return d->m_items.targetUrlList(); } bool KFileItemListProperties::isDirectory() const { return d->m_isDirectory; } +bool KFileItemListProperties::isFile() const +{ + return d->m_isFile; +} + QString KFileItemListProperties::mimeType() const { if (d->m_mimeType.isEmpty()) { d->determineMimeTypeAndGroup(); } return d->m_mimeType; } QString KFileItemListProperties::mimeGroup() const { if (d->m_mimeType.isEmpty()) { d->determineMimeTypeAndGroup(); } return d->m_mimeGroup; } void KFileItemListPropertiesPrivate::determineMimeTypeAndGroup() const { if (!m_items.isEmpty()) { m_mimeType = m_items.first().mimetype(); m_mimeGroup = m_mimeType.left(m_mimeType.indexOf('/')); } foreach (const KFileItem &item, m_items) { const QString itemMimeType = item.mimetype(); // Determine if common mimetype among all items if (m_mimeType != itemMimeType) { m_mimeType.clear(); if (m_mimeGroup != itemMimeType.left(itemMimeType.indexOf('/'))) { m_mimeGroup.clear(); // mimetype groups are different as well! } } } } diff --git a/src/core/kfileitemlistproperties.h b/src/core/kfileitemlistproperties.h index a7d9d052..b15819ab 100644 --- a/src/core/kfileitemlistproperties.h +++ b/src/core/kfileitemlistproperties.h @@ -1,142 +1,148 @@ /* This file is part of the KDE project Copyright (C) 2008 by Peter Penz Copyright (C) 2008 by George Goldberg Copyright 2009 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. 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 KFILEITEMLISTPROPERTIES_H #define KFILEITEMLISTPROPERTIES_H #include "kiocore_export.h" #include #include #include class KFileItemListPropertiesPrivate; class KFileItemList; /** * @class KFileItemListProperties kfileitemlistproperties.h * * @brief Provides information about the common properties of a group of * KFileItem objects. * * Given a list of KFileItems, this class can determine (and cache) the common * mimetype for all items, whether all items are directories, whether all items * are readable, writable, etc. * As soon as one file item does not support a specific capability (read, write etc.), * it is marked as unsupported for all items. * * This class is implicitly shared, which means it can be used as a value and * copied around at almost no cost. * * @since 4.3 */ class KIOCORE_EXPORT KFileItemListProperties { public: /** * @brief Default constructor. Use setItems to specify the items. */ KFileItemListProperties(); /** * @brief Constructor that takes a KFileItemList and sets the capabilities * supported by all the FileItems as true. * @param items The list of items that are to have their supported * capabilities checked. */ KFileItemListProperties(const KFileItemList &items); /** * @brief Copy constructor */ KFileItemListProperties(const KFileItemListProperties &); /** * @brief Destructor */ virtual ~KFileItemListProperties(); /** * @brief Assignment operator */ KFileItemListProperties &operator=(const KFileItemListProperties &other); /** * Sets the items that are to have their supported capabilities checked. */ void setItems(const KFileItemList &items); /** * @brief Check if reading capability is supported * @return true if all the FileItems can be read, otherwise false. */ bool supportsReading() const; /** * @brief Check if deleting capability is supported * @return true if all the FileItems can be deleted, otherwise false. */ bool supportsDeleting() const; /** * @brief Check if writing capability is supported * (file managers use this mostly for directories) * @return true if all the FileItems can be written to, otherwise false. */ bool supportsWriting() const; /** * @brief Check if moving capability is supported * @return true if all the FileItems can be moved, otherwise false. */ bool supportsMoving() const; /** * @brief Check if files are local * @return true if all the FileItems are local, otherwise there is one or more * remote file, so false. */ bool isLocal() const; /** * List of fileitems passed to the constructor or to setItems(). */ KFileItemList items() const; /** * List of urls, gathered from the fileitems */ QList urlList() const; /** * @return true if all items are directories */ bool isDirectory() const; + /** + * @return Whether all items are files, as reported by KFileItem::isFile(). + * @since 5.47 + */ + bool isFile() const; + /** * @return the mimetype of all items, if they all have the same, otherwise empty */ QString mimeType() const; /** * @return the mimetype group (e.g. "text") of all items, if they all have the same, otherwise empty */ QString mimeGroup() const; private: /** @brief d-pointer */ QSharedDataPointer d; }; #endif /* KFILEITEMLISTPROPERTIES_H */