1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2008 Peter Penz <peter.penz@gmx.at>
4 SPDX-FileCopyrightText: 2008 George Goldberg <grundleborg@googlemail.com>
5 SPDX-FileCopyrightText: 2009 David Faure <faure@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
8*/
9
10#include "kfileitemlistproperties.h"
11
12#include <kfileitem.h>
13#include <kprotocolmanager.h>
14
15#include <QFileInfo>
16
17class KFileItemListPropertiesPrivate : public QSharedData
18{
19public:
20 KFileItemListPropertiesPrivate()
21 : m_isDirectory(false)
22 , m_isFile(false)
23 , m_supportsReading(false)
24 , m_supportsDeleting(false)
25 , m_supportsWriting(false)
26 , m_supportsMoving(false)
27 , m_isLocal(true)
28 {
29 }
30 void setItems(const KFileItemList &items);
31
32 void determineMimeTypeAndGroup() const;
33
34 KFileItemList m_items;
35 mutable QString m_mimeType;
36 mutable QString m_mimeGroup;
37 bool m_isDirectory : 1;
38 bool m_isFile : 1;
39 bool m_supportsReading : 1;
40 bool m_supportsDeleting : 1;
41 bool m_supportsWriting : 1;
42 bool m_supportsMoving : 1;
43 bool m_isLocal : 1;
44};
45
46KFileItemListProperties::KFileItemListProperties()
47 : d(new KFileItemListPropertiesPrivate)
48{
49}
50
51KFileItemListProperties::KFileItemListProperties(const KFileItemList &items)
52 : d(new KFileItemListPropertiesPrivate)
53{
54 setItems(items);
55}
56
57void KFileItemListProperties::setItems(const KFileItemList &items)
58{
59 d->setItems(items);
60}
61
62void KFileItemListPropertiesPrivate::setItems(const KFileItemList &items)
63{
64 const bool initialValue = !items.isEmpty();
65 m_items = items;
66 m_supportsReading = initialValue;
67 m_supportsDeleting = initialValue;
68 m_supportsWriting = initialValue;
69 m_supportsMoving = initialValue;
70 m_isDirectory = initialValue;
71 m_isFile = initialValue;
72 m_isLocal = true;
73 m_mimeType.clear();
74 m_mimeGroup.clear();
75
76 QFileInfo parentDirInfo;
77 for (const KFileItem &item : items) {
78 const QUrl url = item.url();
79 const auto [localUrl, isLocal] = item.isMostLocalUrl();
80 m_isLocal = m_isLocal && isLocal;
81 m_supportsReading = m_supportsReading && KProtocolManager::supportsReading(url);
82 m_supportsDeleting = m_supportsDeleting && KProtocolManager::supportsDeleting(url);
83 m_supportsWriting = m_supportsWriting && KProtocolManager::supportsWriting(url) && item.isWritable();
84 m_supportsMoving = m_supportsMoving && KProtocolManager::supportsMoving(url);
85
86 // For local files we can do better: check if we have write permission in parent directory
87 // TODO: if we knew about the parent KFileItem, we could even do that for remote protocols too
88#ifndef Q_OS_WIN
89 if (m_isLocal && (m_supportsDeleting || m_supportsMoving)) {
90 const QString directory = localUrl.adjusted(options: QUrl::RemoveFilename | QUrl::StripTrailingSlash).toLocalFile();
91 if (parentDirInfo.filePath() != directory) {
92 parentDirInfo.setFile(directory);
93 }
94 if (!parentDirInfo.isWritable()) {
95 m_supportsDeleting = false;
96 m_supportsMoving = false;
97 }
98 }
99#else
100 if (m_isLocal && m_supportsDeleting) {
101 if (!QFileInfo(url.toLocalFile()).isWritable())
102 m_supportsDeleting = false;
103 }
104#endif
105 if (m_isDirectory && !item.isDir()) {
106 m_isDirectory = false;
107 }
108
109 if (m_isFile && !item.isFile()) {
110 m_isFile = false;
111 }
112 }
113}
114
115KFileItemListProperties::KFileItemListProperties(const KFileItemListProperties &other)
116 : d(other.d)
117{
118}
119
120KFileItemListProperties &KFileItemListProperties::operator=(const KFileItemListProperties &other)
121{
122 d = other.d;
123 return *this;
124}
125
126KFileItemListProperties::~KFileItemListProperties()
127{
128}
129
130bool KFileItemListProperties::supportsReading() const
131{
132 return d->m_supportsReading;
133}
134
135bool KFileItemListProperties::supportsDeleting() const
136{
137 return d->m_supportsDeleting;
138}
139
140bool KFileItemListProperties::supportsWriting() const
141{
142 return d->m_supportsWriting;
143}
144
145bool KFileItemListProperties::supportsMoving() const
146{
147 return d->m_supportsMoving && d->m_supportsDeleting;
148}
149
150bool KFileItemListProperties::isLocal() const
151{
152 return d->m_isLocal;
153}
154
155KFileItemList KFileItemListProperties::items() const
156{
157 return d->m_items;
158}
159
160QList<QUrl> KFileItemListProperties::urlList() const
161{
162 return d->m_items.targetUrlList();
163}
164
165bool KFileItemListProperties::isDirectory() const
166{
167 return d->m_isDirectory;
168}
169
170bool KFileItemListProperties::isFile() const
171{
172 return d->m_isFile;
173}
174
175QString KFileItemListProperties::mimeType() const
176{
177 if (d->m_mimeType.isEmpty()) {
178 d->determineMimeTypeAndGroup();
179 }
180 return d->m_mimeType;
181}
182
183QString KFileItemListProperties::mimeGroup() const
184{
185 if (d->m_mimeType.isEmpty()) {
186 d->determineMimeTypeAndGroup();
187 }
188 return d->m_mimeGroup;
189}
190
191void KFileItemListPropertiesPrivate::determineMimeTypeAndGroup() const
192{
193 if (!m_items.isEmpty()) {
194 m_mimeType = m_items.first().mimetype();
195 m_mimeGroup = m_mimeType.left(n: m_mimeType.indexOf(c: QLatin1Char('/')));
196 }
197 for (const KFileItem &item : std::as_const(t: m_items)) {
198 const QString itemMimeType = item.mimetype();
199 // Determine if common MIME type among all items
200 if (m_mimeType != itemMimeType) {
201 m_mimeType.clear();
202 const auto type = QStringView(itemMimeType).left(n: itemMimeType.indexOf(c: QLatin1Char('/')));
203 if (m_mimeGroup != type) {
204 m_mimeGroup.clear(); // MIME type groups are different as well!
205 }
206 }
207 }
208}
209

source code of kio/src/core/kfileitemlistproperties.cpp