File indexing completed on 2024-10-13 03:38:08
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2008 Peter Penz <peter.penz@gmx.at> 0004 SPDX-FileCopyrightText: 2008 George Goldberg <grundleborg@googlemail.com> 0005 SPDX-FileCopyrightText: 2009 David Faure <faure@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0008 */ 0009 0010 #include "kfileitemlistproperties.h" 0011 0012 #include <kfileitem.h> 0013 #include <kprotocolmanager.h> 0014 0015 #include <QFileInfo> 0016 0017 class KFileItemListPropertiesPrivate : public QSharedData 0018 { 0019 public: 0020 KFileItemListPropertiesPrivate() 0021 : m_isDirectory(false) 0022 , m_isFile(false) 0023 , m_supportsReading(false) 0024 , m_supportsDeleting(false) 0025 , m_supportsWriting(false) 0026 , m_supportsMoving(false) 0027 , m_isLocal(true) 0028 { 0029 } 0030 void setItems(const KFileItemList &items); 0031 0032 void determineMimeTypeAndGroup() const; 0033 0034 KFileItemList m_items; 0035 mutable QString m_mimeType; 0036 mutable QString m_mimeGroup; 0037 bool m_isDirectory : 1; 0038 bool m_isFile : 1; 0039 bool m_supportsReading : 1; 0040 bool m_supportsDeleting : 1; 0041 bool m_supportsWriting : 1; 0042 bool m_supportsMoving : 1; 0043 bool m_isLocal : 1; 0044 }; 0045 0046 KFileItemListProperties::KFileItemListProperties() 0047 : d(new KFileItemListPropertiesPrivate) 0048 { 0049 } 0050 0051 KFileItemListProperties::KFileItemListProperties(const KFileItemList &items) 0052 : d(new KFileItemListPropertiesPrivate) 0053 { 0054 setItems(items); 0055 } 0056 0057 void KFileItemListProperties::setItems(const KFileItemList &items) 0058 { 0059 d->setItems(items); 0060 } 0061 0062 void KFileItemListPropertiesPrivate::setItems(const KFileItemList &items) 0063 { 0064 const bool initialValue = !items.isEmpty(); 0065 m_items = items; 0066 m_supportsReading = initialValue; 0067 m_supportsDeleting = initialValue; 0068 m_supportsWriting = initialValue; 0069 m_supportsMoving = initialValue; 0070 m_isDirectory = initialValue; 0071 m_isFile = initialValue; 0072 m_isLocal = true; 0073 m_mimeType.clear(); 0074 m_mimeGroup.clear(); 0075 0076 QFileInfo parentDirInfo; 0077 for (const KFileItem &item : items) { 0078 const QUrl url = item.url(); 0079 const auto [localUrl, isLocal] = item.isMostLocalUrl(); 0080 m_isLocal = m_isLocal && isLocal; 0081 m_supportsReading = m_supportsReading && KProtocolManager::supportsReading(url); 0082 m_supportsDeleting = m_supportsDeleting && KProtocolManager::supportsDeleting(url); 0083 m_supportsWriting = m_supportsWriting && KProtocolManager::supportsWriting(url) && item.isWritable(); 0084 m_supportsMoving = m_supportsMoving && KProtocolManager::supportsMoving(url); 0085 0086 // For local files we can do better: check if we have write permission in parent directory 0087 // TODO: if we knew about the parent KFileItem, we could even do that for remote protocols too 0088 #ifndef Q_OS_WIN 0089 if (m_isLocal && (m_supportsDeleting || m_supportsMoving)) { 0090 const QString directory = localUrl.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).toLocalFile(); 0091 if (parentDirInfo.filePath() != directory) { 0092 parentDirInfo.setFile(directory); 0093 } 0094 if (!parentDirInfo.isWritable()) { 0095 m_supportsDeleting = false; 0096 m_supportsMoving = false; 0097 } 0098 } 0099 #else 0100 if (m_isLocal && m_supportsDeleting) { 0101 if (!QFileInfo(url.toLocalFile()).isWritable()) 0102 m_supportsDeleting = false; 0103 } 0104 #endif 0105 if (m_isDirectory && !item.isDir()) { 0106 m_isDirectory = false; 0107 } 0108 0109 if (m_isFile && !item.isFile()) { 0110 m_isFile = false; 0111 } 0112 } 0113 } 0114 0115 KFileItemListProperties::KFileItemListProperties(const KFileItemListProperties &other) 0116 : d(other.d) 0117 { 0118 } 0119 0120 KFileItemListProperties &KFileItemListProperties::operator=(const KFileItemListProperties &other) 0121 { 0122 d = other.d; 0123 return *this; 0124 } 0125 0126 KFileItemListProperties::~KFileItemListProperties() 0127 { 0128 } 0129 0130 bool KFileItemListProperties::supportsReading() const 0131 { 0132 return d->m_supportsReading; 0133 } 0134 0135 bool KFileItemListProperties::supportsDeleting() const 0136 { 0137 return d->m_supportsDeleting; 0138 } 0139 0140 bool KFileItemListProperties::supportsWriting() const 0141 { 0142 return d->m_supportsWriting; 0143 } 0144 0145 bool KFileItemListProperties::supportsMoving() const 0146 { 0147 return d->m_supportsMoving && d->m_supportsDeleting; 0148 } 0149 0150 bool KFileItemListProperties::isLocal() const 0151 { 0152 return d->m_isLocal; 0153 } 0154 0155 KFileItemList KFileItemListProperties::items() const 0156 { 0157 return d->m_items; 0158 } 0159 0160 QList<QUrl> KFileItemListProperties::urlList() const 0161 { 0162 return d->m_items.targetUrlList(); 0163 } 0164 0165 bool KFileItemListProperties::isDirectory() const 0166 { 0167 return d->m_isDirectory; 0168 } 0169 0170 bool KFileItemListProperties::isFile() const 0171 { 0172 return d->m_isFile; 0173 } 0174 0175 QString KFileItemListProperties::mimeType() const 0176 { 0177 if (d->m_mimeType.isEmpty()) { 0178 d->determineMimeTypeAndGroup(); 0179 } 0180 return d->m_mimeType; 0181 } 0182 0183 QString KFileItemListProperties::mimeGroup() const 0184 { 0185 if (d->m_mimeType.isEmpty()) { 0186 d->determineMimeTypeAndGroup(); 0187 } 0188 return d->m_mimeGroup; 0189 } 0190 0191 void KFileItemListPropertiesPrivate::determineMimeTypeAndGroup() const 0192 { 0193 if (!m_items.isEmpty()) { 0194 m_mimeType = m_items.first().mimetype(); 0195 m_mimeGroup = m_mimeType.left(m_mimeType.indexOf(QLatin1Char('/'))); 0196 } 0197 for (const KFileItem &item : std::as_const(m_items)) { 0198 const QString itemMimeType = item.mimetype(); 0199 // Determine if common MIME type among all items 0200 if (m_mimeType != itemMimeType) { 0201 m_mimeType.clear(); 0202 const auto type = QStringView(itemMimeType).left(itemMimeType.indexOf(QLatin1Char('/'))); 0203 if (m_mimeGroup != type) { 0204 m_mimeGroup.clear(); // MIME type groups are different as well! 0205 } 0206 } 0207 } 0208 }