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 | |
17 | class KFileItemListPropertiesPrivate : public QSharedData |
18 | { |
19 | public: |
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 | |
46 | KFileItemListProperties::KFileItemListProperties() |
47 | : d(new KFileItemListPropertiesPrivate) |
48 | { |
49 | } |
50 | |
51 | KFileItemListProperties::KFileItemListProperties(const KFileItemList &items) |
52 | : d(new KFileItemListPropertiesPrivate) |
53 | { |
54 | setItems(items); |
55 | } |
56 | |
57 | void KFileItemListProperties::setItems(const KFileItemList &items) |
58 | { |
59 | d->setItems(items); |
60 | } |
61 | |
62 | void 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 | |
115 | KFileItemListProperties::KFileItemListProperties(const KFileItemListProperties &other) |
116 | : d(other.d) |
117 | { |
118 | } |
119 | |
120 | KFileItemListProperties &KFileItemListProperties::operator=(const KFileItemListProperties &other) |
121 | { |
122 | d = other.d; |
123 | return *this; |
124 | } |
125 | |
126 | KFileItemListProperties::~KFileItemListProperties() |
127 | { |
128 | } |
129 | |
130 | bool KFileItemListProperties::supportsReading() const |
131 | { |
132 | return d->m_supportsReading; |
133 | } |
134 | |
135 | bool KFileItemListProperties::supportsDeleting() const |
136 | { |
137 | return d->m_supportsDeleting; |
138 | } |
139 | |
140 | bool KFileItemListProperties::supportsWriting() const |
141 | { |
142 | return d->m_supportsWriting; |
143 | } |
144 | |
145 | bool KFileItemListProperties::supportsMoving() const |
146 | { |
147 | return d->m_supportsMoving && d->m_supportsDeleting; |
148 | } |
149 | |
150 | bool KFileItemListProperties::isLocal() const |
151 | { |
152 | return d->m_isLocal; |
153 | } |
154 | |
155 | KFileItemList KFileItemListProperties::items() const |
156 | { |
157 | return d->m_items; |
158 | } |
159 | |
160 | QList<QUrl> KFileItemListProperties::urlList() const |
161 | { |
162 | return d->m_items.targetUrlList(); |
163 | } |
164 | |
165 | bool KFileItemListProperties::isDirectory() const |
166 | { |
167 | return d->m_isDirectory; |
168 | } |
169 | |
170 | bool KFileItemListProperties::isFile() const |
171 | { |
172 | return d->m_isFile; |
173 | } |
174 | |
175 | QString KFileItemListProperties::mimeType() const |
176 | { |
177 | if (d->m_mimeType.isEmpty()) { |
178 | d->determineMimeTypeAndGroup(); |
179 | } |
180 | return d->m_mimeType; |
181 | } |
182 | |
183 | QString KFileItemListProperties::mimeGroup() const |
184 | { |
185 | if (d->m_mimeType.isEmpty()) { |
186 | d->determineMimeTypeAndGroup(); |
187 | } |
188 | return d->m_mimeGroup; |
189 | } |
190 | |
191 | void 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 |