Changeset View
Standalone View
src/core/kfileitem.cpp
Show First 20 Lines • Show All 45 Lines • ▼ Show 20 Line(s) | |||||
46 | 46 | | |||
47 | class KFileItemPrivate : public QSharedData | 47 | class KFileItemPrivate : public QSharedData | ||
48 | { | 48 | { | ||
49 | public: | 49 | public: | ||
50 | KFileItemPrivate(const KIO::UDSEntry &entry, | 50 | KFileItemPrivate(const KIO::UDSEntry &entry, | ||
51 | mode_t mode, mode_t permissions, | 51 | mode_t mode, mode_t permissions, | ||
52 | const QUrl &itemOrDirUrl, | 52 | const QUrl &itemOrDirUrl, | ||
53 | bool urlIsDirectory, | 53 | bool urlIsDirectory, | ||
54 | bool delayedMimeTypes) | 54 | bool delayedMimeTypes, | ||
55 | KFileItem::MimeTypeDetermination mimeTypeDetermination) | ||||
55 | : m_entry(entry), | 56 | : m_entry(entry), | ||
56 | m_url(itemOrDirUrl), | 57 | m_url(itemOrDirUrl), | ||
57 | m_strName(), | 58 | m_strName(), | ||
58 | m_strText(), | 59 | m_strText(), | ||
59 | m_iconName(), | 60 | m_iconName(), | ||
60 | m_strLowerCaseName(), | 61 | m_strLowerCaseName(), | ||
61 | m_mimeType(), | 62 | m_mimeType(), | ||
62 | m_fileMode(mode), | 63 | m_fileMode(mode), | ||
63 | m_permissions(permissions), | 64 | m_permissions(permissions), | ||
64 | m_bLink(false), | 65 | m_bLink(false), | ||
65 | m_bIsLocalUrl(itemOrDirUrl.isLocalFile()), | 66 | m_bIsLocalUrl(itemOrDirUrl.isLocalFile()), | ||
66 | m_bMimeTypeKnown(false), | 67 | m_bMimeTypeKnown(false), | ||
67 | m_delayedMimeTypes(delayedMimeTypes), | 68 | m_delayedMimeTypes(delayedMimeTypes), | ||
68 | m_useIconNameCache(false), | 69 | m_useIconNameCache(false), | ||
69 | m_hidden(Auto), | 70 | m_hidden(Auto), | ||
70 | m_slow(SlowUnknown) | 71 | m_slow(SlowUnknown), | ||
72 | m_bSkipMimeTypeFromContent(mimeTypeDetermination == KFileItem::SkipMimeTypeFromContent), | ||||
73 | m_bInitCalled(false) | ||||
71 | { | 74 | { | ||
72 | if (entry.count() != 0) { | 75 | if (entry.count() != 0) { | ||
73 | readUDSEntry(urlIsDirectory); | 76 | readUDSEntry(urlIsDirectory); | ||
74 | } else { | 77 | } else { | ||
75 | Q_ASSERT(!urlIsDirectory); | 78 | Q_ASSERT(!urlIsDirectory); | ||
76 | m_strName = itemOrDirUrl.fileName(); | 79 | m_strName = itemOrDirUrl.fileName(); | ||
77 | m_strText = KIO::decodeFileName(m_strName); | 80 | m_strText = KIO::decodeFileName(m_strName); | ||
78 | } | 81 | } | ||
79 | init(); | | |||
80 | } | 82 | } | ||
81 | 83 | | |||
82 | /** | 84 | /** | ||
83 | * Computes the text and mode from the UDSEntry | 85 | * Call init() if not yet done. | ||
dfaure: Remove this comment, no longer true (only keep the first line, remove the other 3) | |||||
84 | * Called by constructor, but can be called again later | 86 | */ | ||
85 | * Nothing does that anymore though (I guess some old KonqFileItem did) | 87 | void ensureInitialized() const; | ||
86 | * so it's not a protected method of the public class anymore. | 88 | | ||
89 | /** | ||||
90 | * Computes the text and mode from the UDSEntry. | ||||
87 | */ | 91 | */ | ||
88 | void init(); | 92 | void init() const; | ||
89 | 93 | | |||
90 | QString localPath() const; | 94 | QString localPath() const; | ||
91 | KIO::filesize_t size() const; | 95 | KIO::filesize_t size() const; | ||
92 | QDateTime time(KFileItem::FileTimes which) const; | 96 | QDateTime time(KFileItem::FileTimes which) const; | ||
93 | void setTime(KFileItem::FileTimes which, uint time_t_val) const; | 97 | void setTime(KFileItem::FileTimes which, uint time_t_val) const; | ||
94 | void setTime(KFileItem::FileTimes which, const QDateTime &val) const; | 98 | void setTime(KFileItem::FileTimes which, const QDateTime &val) const; | ||
95 | bool cmp(const KFileItemPrivate &item) const; | 99 | bool cmp(const KFileItemPrivate &item) const; | ||
96 | bool isSlow() const; | 100 | bool isSlow() const; | ||
97 | 101 | | |||
98 | /** | 102 | /** | ||
99 | * Extracts the data from the UDSEntry member and updates the KFileItem | 103 | * Extracts the data from the UDSEntry member and updates the KFileItem | ||
100 | * accordingly. | 104 | * accordingly. | ||
101 | */ | 105 | */ | ||
102 | void readUDSEntry(bool _urlIsDirectory); | 106 | void readUDSEntry(bool _urlIsDirectory); | ||
103 | 107 | | |||
104 | /** | 108 | /** | ||
105 | * Parses the given permission set and provides it for access() | 109 | * Parses the given permission set and provides it for access() | ||
106 | */ | 110 | */ | ||
107 | QString parsePermissions(mode_t perm) const; | 111 | QString parsePermissions(mode_t perm) const; | ||
108 | 112 | | |||
109 | /** | 113 | /** | ||
114 | * Mime type helper | ||||
115 | */ | ||||
116 | void determineMimeTypeHelper(const QUrl &url) const; | ||||
117 | | ||||
118 | /** | ||||
110 | * The UDSEntry that contains the data for this fileitem, if it came from a directory listing. | 119 | * The UDSEntry that contains the data for this fileitem, if it came from a directory listing. | ||
111 | */ | 120 | */ | ||
112 | mutable KIO::UDSEntry m_entry; | 121 | mutable KIO::UDSEntry m_entry; | ||
113 | /** | 122 | /** | ||
114 | * The url of the file | 123 | * The url of the file | ||
115 | */ | 124 | */ | ||
116 | QUrl m_url; | 125 | QUrl m_url; | ||
117 | 126 | | |||
Show All 21 Lines | |||||
139 | /** | 148 | /** | ||
140 | * The mimetype of the file | 149 | * The mimetype of the file | ||
141 | */ | 150 | */ | ||
142 | mutable QMimeType m_mimeType; | 151 | mutable QMimeType m_mimeType; | ||
143 | 152 | | |||
144 | /** | 153 | /** | ||
145 | * The file mode | 154 | * The file mode | ||
146 | */ | 155 | */ | ||
147 | mode_t m_fileMode; | 156 | mutable mode_t m_fileMode; | ||
148 | /** | 157 | /** | ||
149 | * The permissions | 158 | * The permissions | ||
150 | */ | 159 | */ | ||
151 | mode_t m_permissions; | 160 | mutable mode_t m_permissions; | ||
152 | 161 | | |||
153 | /** | 162 | /** | ||
154 | * Whether the file is a link | 163 | * Whether the file is a link | ||
155 | */ | 164 | */ | ||
156 | bool m_bLink: 1; | 165 | mutable bool m_bLink: 1; | ||
157 | /** | 166 | /** | ||
158 | * True if local file | 167 | * True if local file | ||
159 | */ | 168 | */ | ||
160 | bool m_bIsLocalUrl: 1; | 169 | bool m_bIsLocalUrl: 1; | ||
161 | 170 | | |||
162 | mutable bool m_bMimeTypeKnown: 1; | 171 | mutable bool m_bMimeTypeKnown: 1; | ||
163 | mutable bool m_delayedMimeTypes: 1; | 172 | mutable bool m_delayedMimeTypes: 1; | ||
164 | 173 | | |||
165 | /** True if m_iconName should be used as cache. */ | 174 | /** True if m_iconName should be used as cache. */ | ||
166 | mutable bool m_useIconNameCache: 1; | 175 | mutable bool m_useIconNameCache: 1; | ||
167 | 176 | | |||
168 | // Auto: check leading dot. | 177 | // Auto: check leading dot. | ||
169 | enum { Auto, Hidden, Shown } m_hidden: 3; | 178 | enum { Auto, Hidden, Shown } m_hidden: 3; | ||
170 | 179 | | |||
171 | // Slow? (nfs/smb/ssh) | 180 | // Slow? (nfs/smb/ssh) | ||
172 | mutable enum { SlowUnknown, Fast, Slow } m_slow: 3; | 181 | mutable enum { SlowUnknown, Fast, Slow } m_slow: 3; | ||
173 | 182 | | |||
183 | /** | ||||
184 | * True if mime type determination by content should be skipped | ||||
185 | */ | ||||
186 | bool m_bSkipMimeTypeFromContent: 1; | ||||
187 | | ||||
188 | /** | ||||
189 | * True if init() was called on demand | ||||
190 | */ | ||||
191 | mutable bool m_bInitCalled: 1; | ||||
192 | | ||||
174 | // For special case like link to dirs over FTP | 193 | // For special case like link to dirs over FTP | ||
175 | QString m_guessedMimeType; | 194 | QString m_guessedMimeType; | ||
176 | mutable QString m_access; | 195 | mutable QString m_access; | ||
196 | | ||||
177 | }; | 197 | }; | ||
178 | 198 | | |||
179 | void KFileItemPrivate::init() | 199 | void KFileItemPrivate::ensureInitialized() const | ||
200 | { | ||||
dfaure: move it so it's with the other bits above | |||||
201 | if (!m_bInitCalled) { | ||||
202 | init(); | ||||
203 | } | ||||
204 | } | ||||
205 | | ||||
206 | void KFileItemPrivate::init() const | ||||
180 | { | 207 | { | ||
181 | m_access.clear(); | 208 | m_access.clear(); | ||
182 | // metaInfo = KFileMetaInfo(); | 209 | // metaInfo = KFileMetaInfo(); | ||
183 | 210 | | |||
184 | // stat() local files if needed | 211 | // stat() local files if needed | ||
185 | // TODO: delay this until requested | | |||
186 | if (m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown || m_entry.count() == 0) { | 212 | if (m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown || m_entry.count() == 0) { | ||
depending on the use case, wouldn't it be enough to implement this TODO instead? dfaure: depending on the use case, wouldn't it be enough to implement this TODO instead? | |||||
dfaure: Remove the TODO :-) | |||||
187 | if (m_url.isLocalFile()) { | 213 | if (m_url.isLocalFile()) { | ||
188 | /* directories may not have a slash at the end if | 214 | /* directories may not have a slash at the end if | ||
189 | * we want to stat() them; it requires that we | 215 | * we want to stat() them; it requires that we | ||
190 | * change into it .. which may not be allowed | 216 | * change into it .. which may not be allowed | ||
191 | * stat("/is/unaccessible") -> rwx------ | 217 | * stat("/is/unaccessible") -> rwx------ | ||
192 | * stat("/is/unaccessible/") -> EPERM H.Z. | 218 | * stat("/is/unaccessible/") -> EPERM H.Z. | ||
193 | * This is the reason for the StripTrailingSlash | 219 | * This is the reason for the StripTrailingSlash | ||
194 | */ | 220 | */ | ||
Show All 29 Lines | 249 | if (m_fileMode == KFileItem::Unknown) { | |||
224 | m_fileMode = mode & QT_STAT_MASK; // extract file type | 250 | m_fileMode = mode & QT_STAT_MASK; // extract file type | ||
225 | } | 251 | } | ||
226 | if (m_permissions == KFileItem::Unknown) { | 252 | if (m_permissions == KFileItem::Unknown) { | ||
227 | m_permissions = mode & 07777; // extract permissions | 253 | m_permissions = mode & 07777; // extract permissions | ||
228 | } | 254 | } | ||
229 | } | 255 | } | ||
230 | } | 256 | } | ||
231 | } | 257 | } | ||
258 | | ||||
259 | m_bInitCalled = true; | ||||
232 | } | 260 | } | ||
261 | | ||||
233 | void KFileItemPrivate::readUDSEntry(bool _urlIsDirectory) | 262 | void KFileItemPrivate::readUDSEntry(bool _urlIsDirectory) | ||
234 | { | 263 | { | ||
235 | // extract fields from the KIO::UDS Entry | 264 | // extract fields from the KIO::UDS Entry | ||
236 | 265 | | |||
237 | m_fileMode = m_entry.numberValue(KIO::UDSEntry::UDS_FILE_TYPE, KFileItem::Unknown); | 266 | m_fileMode = m_entry.numberValue(KIO::UDSEntry::UDS_FILE_TYPE, KFileItem::Unknown); | ||
238 | m_permissions = m_entry.numberValue(KIO::UDSEntry::UDS_ACCESS, KFileItem::Unknown); | 267 | m_permissions = m_entry.numberValue(KIO::UDSEntry::UDS_ACCESS, KFileItem::Unknown); | ||
239 | m_strName = m_entry.stringValue(KIO::UDSEntry::UDS_NAME); | 268 | m_strName = m_entry.stringValue(KIO::UDSEntry::UDS_NAME); | ||
240 | 269 | | |||
Show All 30 Lines | |||||
271 | } | 300 | } | ||
272 | 301 | | |||
273 | m_iconName.clear(); | 302 | m_iconName.clear(); | ||
274 | } | 303 | } | ||
275 | 304 | | |||
276 | inline //because it is used only in one place | 305 | inline //because it is used only in one place | ||
277 | KIO::filesize_t KFileItemPrivate::size() const | 306 | KIO::filesize_t KFileItemPrivate::size() const | ||
278 | { | 307 | { | ||
308 | ensureInitialized(); | ||||
309 | | ||||
279 | // Extract it from the KIO::UDSEntry | 310 | // Extract it from the KIO::UDSEntry | ||
280 | long long fieldVal = m_entry.numberValue(KIO::UDSEntry::UDS_SIZE, -1); | 311 | long long fieldVal = m_entry.numberValue(KIO::UDSEntry::UDS_SIZE, -1); | ||
281 | if (fieldVal != -1) { | 312 | if (fieldVal != -1) { | ||
282 | return fieldVal; | 313 | return fieldVal; | ||
283 | } | 314 | } | ||
284 | 315 | | |||
285 | // If not in the KIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL] | 316 | // If not in the KIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL] | ||
286 | if (m_bIsLocalUrl) { | 317 | if (m_bIsLocalUrl) { | ||
Show All 23 Lines | |||||
310 | void KFileItemPrivate::setTime(KFileItem::FileTimes mappedWhich, const QDateTime &val) const | 341 | void KFileItemPrivate::setTime(KFileItem::FileTimes mappedWhich, const QDateTime &val) const | ||
311 | { | 342 | { | ||
312 | const QDateTime dt = val.toLocalTime(); // #160979 | 343 | const QDateTime dt = val.toLocalTime(); // #160979 | ||
313 | setTime(mappedWhich, dt.toTime_t()); | 344 | setTime(mappedWhich, dt.toTime_t()); | ||
314 | } | 345 | } | ||
315 | 346 | | |||
316 | QDateTime KFileItemPrivate::time(KFileItem::FileTimes mappedWhich) const | 347 | QDateTime KFileItemPrivate::time(KFileItem::FileTimes mappedWhich) const | ||
317 | { | 348 | { | ||
349 | ensureInitialized(); | ||||
350 | | ||||
318 | // Extract it from the KIO::UDSEntry | 351 | // Extract it from the KIO::UDSEntry | ||
319 | const uint uds = udsFieldForTime(mappedWhich); | 352 | const uint uds = udsFieldForTime(mappedWhich); | ||
320 | if (uds > 0) { | 353 | if (uds > 0) { | ||
321 | const long long fieldVal = m_entry.numberValue(uds, -1); | 354 | const long long fieldVal = m_entry.numberValue(uds, -1); | ||
322 | if (fieldVal != -1) { | 355 | if (fieldVal != -1) { | ||
323 | return QDateTime::fromMSecsSinceEpoch(1000 * fieldVal); | 356 | return QDateTime::fromMSecsSinceEpoch(1000 * fieldVal); | ||
324 | } | 357 | } | ||
325 | } | 358 | } | ||
326 | 359 | | |||
327 | return QDateTime(); | 360 | return QDateTime(); | ||
328 | } | 361 | } | ||
329 | 362 | | |||
330 | inline //because it is used only in one place | 363 | inline //because it is used only in one place | ||
331 | bool KFileItemPrivate::cmp(const KFileItemPrivate &item) const | 364 | bool KFileItemPrivate::cmp(const KFileItemPrivate &item) const | ||
332 | { | 365 | { | ||
366 | if (item.m_bInitCalled) { | ||||
What about the other way around? I think this needs the symmetrical test to call item.init() if needed dfaure: What about the other way around? I think this needs the symmetrical test to call item.init() if… | |||||
hoffmannrobert: You're right, fixed, unittest added. | |||||
367 | ensureInitialized(); | ||||
368 | } | ||||
369 | | ||||
370 | if (m_bInitCalled) { | ||||
There is one thing I've been wondering back and forth about: the alternative way of doing this, which is to call init() unconditionally and testing the bool first thing in there. Ah, in another code base (QMimeType) I wrote ensureLoaded(). This could be ensureInitialized() ? Sorry for not suggesting this earlier. Do you agree that it would make the code better? dfaure: There is one thing I've been wondering back and forth about: the alternative way of doing this… | |||||
Yes, I agree, but here you still need the two ifs, and the init() still is needed because of refresh(). hoffmannrobert: Yes, I agree, but here you still need the two ifs, and the init() still is needed because of… | |||||
371 | item.ensureInitialized(); | ||||
372 | } | ||||
373 | | ||||
333 | #if 0 | 374 | #if 0 | ||
334 | //qDebug() << "Comparing" << m_url << "and" << item.m_url; | 375 | //qDebug() << "Comparing" << m_url << "and" << item.m_url; | ||
335 | //qDebug() << " name" << (m_strName == item.m_strName); | 376 | //qDebug() << " name" << (m_strName == item.m_strName); | ||
336 | //qDebug() << " local" << (m_bIsLocalUrl == item.m_bIsLocalUrl); | 377 | //qDebug() << " local" << (m_bIsLocalUrl == item.m_bIsLocalUrl); | ||
337 | //qDebug() << " mode" << (m_fileMode == item.m_fileMode); | 378 | //qDebug() << " mode" << (m_fileMode == item.m_fileMode); | ||
338 | //qDebug() << " perm" << (m_permissions == item.m_permissions); | 379 | //qDebug() << " perm" << (m_permissions == item.m_permissions); | ||
339 | //qDebug() << " UDS_EXTENDED_ACL" << (m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL )); | 380 | //qDebug() << " UDS_EXTENDED_ACL" << (m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL )); | ||
340 | //qDebug() << " UDS_ACL_STRING" << (m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING )); | 381 | //qDebug() << " UDS_ACL_STRING" << (m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING )); | ||
Show All 22 Lines | 388 | #endif | |||
363 | 404 | | |||
364 | // Don't compare the mimetypes here. They might not be known, and we don't want to | 405 | // Don't compare the mimetypes here. They might not be known, and we don't want to | ||
365 | // do the slow operation of determining them here. | 406 | // do the slow operation of determining them here. | ||
366 | } | 407 | } | ||
367 | 408 | | |||
368 | inline //because it is used only in one place | 409 | inline //because it is used only in one place | ||
369 | QString KFileItemPrivate::parsePermissions(mode_t perm) const | 410 | QString KFileItemPrivate::parsePermissions(mode_t perm) const | ||
370 | { | 411 | { | ||
412 | ensureInitialized(); | ||||
413 | | ||||
371 | static char buffer[ 12 ]; | 414 | static char buffer[ 12 ]; | ||
372 | 415 | | |||
373 | char uxbit, gxbit, oxbit; | 416 | char uxbit, gxbit, oxbit; | ||
374 | 417 | | |||
375 | if ((perm & (S_IXUSR | S_ISUID)) == (S_IXUSR | S_ISUID)) { | 418 | if ((perm & (S_IXUSR | S_ISUID)) == (S_IXUSR | S_ISUID)) { | ||
376 | uxbit = 's'; | 419 | uxbit = 's'; | ||
377 | } else if ((perm & (S_IXUSR | S_ISUID)) == S_ISUID) { | 420 | } else if ((perm & (S_IXUSR | S_ISUID)) == S_ISUID) { | ||
378 | uxbit = 'S'; | 421 | uxbit = 'S'; | ||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Line(s) | 484 | if (m_entry.contains(KIO::UDSEntry::UDS_EXTENDED_ACL)) { | |||
443 | buffer[11] = 0; | 486 | buffer[11] = 0; | ||
444 | } else { | 487 | } else { | ||
445 | buffer[10] = 0; | 488 | buffer[10] = 0; | ||
446 | } | 489 | } | ||
447 | 490 | | |||
448 | return QString::fromLatin1(buffer); | 491 | return QString::fromLatin1(buffer); | ||
449 | } | 492 | } | ||
450 | 493 | | |||
494 | void KFileItemPrivate::determineMimeTypeHelper(const QUrl &url) const | ||||
495 | { | ||||
496 | QMimeDatabase db; | ||||
497 | if (m_bSkipMimeTypeFromContent) { | ||||
So, we don't really skip it. We just use a "fast and less precise" mode. Sounds like this should be called DetermineMimeTypeFromExtension (though that's incorrect for http), dfaure: So, we don't really skip it. We just use a "fast and less precise" mode.
Sounds like this… | |||||
498 | const QString scheme = url.scheme(); | ||||
499 | if (scheme.startsWith(QLatin1String("http")) || scheme == QLatin1String("mailto")) | ||||
500 | m_mimeType = db.mimeTypeForName(QLatin1String("application/octet-stream")); | ||||
501 | else | ||||
502 | m_mimeType = db.mimeTypeForFile(url.path(), QMimeDatabase::MatchMode::MatchExtension); | ||||
503 | } else { | ||||
504 | m_mimeType = db.mimeTypeForUrl(url); | ||||
505 | } | ||||
506 | } | ||||
507 | | ||||
451 | /////// | 508 | /////// | ||
452 | 509 | | |||
453 | KFileItem::KFileItem() | 510 | KFileItem::KFileItem() | ||
454 | : d(nullptr) | 511 | : d(nullptr) | ||
455 | { | 512 | { | ||
456 | } | 513 | } | ||
457 | 514 | | |||
458 | KFileItem::KFileItem(const KIO::UDSEntry &entry, const QUrl &itemOrDirUrl, | 515 | KFileItem::KFileItem(const KIO::UDSEntry &entry, const QUrl &itemOrDirUrl, | ||
459 | bool delayedMimeTypes, bool urlIsDirectory) | 516 | bool delayedMimeTypes, bool urlIsDirectory) | ||
460 | : d(new KFileItemPrivate(entry, KFileItem::Unknown, KFileItem::Unknown, itemOrDirUrl, urlIsDirectory, delayedMimeTypes)) | 517 | : d(new KFileItemPrivate(entry, KFileItem::Unknown, KFileItem::Unknown, itemOrDirUrl, urlIsDirectory, delayedMimeTypes, KFileItem::NormalMimeTypeDetermination)) | ||
461 | { | 518 | { | ||
462 | } | 519 | } | ||
463 | 520 | | |||
464 | KFileItem::KFileItem(mode_t mode, mode_t permissions, const QUrl &url, bool delayedMimeTypes) | 521 | KFileItem::KFileItem(mode_t mode, mode_t permissions, const QUrl &url, bool delayedMimeTypes) | ||
465 | : d(new KFileItemPrivate(KIO::UDSEntry(), mode, permissions, | 522 | : d(new KFileItemPrivate(KIO::UDSEntry(), mode, permissions, | ||
466 | url, false, delayedMimeTypes)) | 523 | url, false, delayedMimeTypes, KFileItem::NormalMimeTypeDetermination)) | ||
467 | { | 524 | { | ||
468 | } | 525 | } | ||
469 | 526 | | |||
470 | KFileItem::KFileItem(const QUrl &url, const QString &mimeType, mode_t mode) | 527 | KFileItem::KFileItem(const QUrl &url, const QString &mimeType, mode_t mode) | ||
471 | : d(new KFileItemPrivate(KIO::UDSEntry(), mode, KFileItem::Unknown, | 528 | : d(new KFileItemPrivate(KIO::UDSEntry(), mode, KFileItem::Unknown, | ||
472 | url, false, false)) | 529 | url, false, false, KFileItem::NormalMimeTypeDetermination)) | ||
473 | { | 530 | { | ||
474 | d->m_bMimeTypeKnown = !mimeType.isEmpty(); | 531 | d->m_bMimeTypeKnown = !mimeType.isEmpty(); | ||
475 | if (d->m_bMimeTypeKnown) { | 532 | if (d->m_bMimeTypeKnown) { | ||
476 | QMimeDatabase db; | 533 | QMimeDatabase db; | ||
477 | d->m_mimeType = db.mimeTypeForName(mimeType); | 534 | d->m_mimeType = db.mimeTypeForName(mimeType); | ||
478 | } | 535 | } | ||
479 | } | 536 | } | ||
480 | 537 | | |||
538 | KFileItem::KFileItem(const QUrl &url, KFileItem::MimeTypeDetermination mimeTypeDetermination) | ||||
539 | : d(new KFileItemPrivate(KIO::UDSEntry(), KFileItem::Unknown, KFileItem::Unknown, | ||||
540 | url, false, false, mimeTypeDetermination)) | ||||
541 | { | ||||
542 | } | ||||
543 | | ||||
544 | | ||||
481 | // Default implementations for: | 545 | // Default implementations for: | ||
482 | // - Copy constructor | 546 | // - Copy constructor | ||
483 | // - Move constructor | 547 | // - Move constructor | ||
484 | // - Copy assignment | 548 | // - Copy assignment | ||
485 | // - Move assignment | 549 | // - Move assignment | ||
486 | // - Destructor | 550 | // - Destructor | ||
487 | // The compiler will now generate the content of those. | 551 | // The compiler will now generate the content of those. | ||
488 | KFileItem::KFileItem(const KFileItem&) = default; | 552 | KFileItem::KFileItem(const KFileItem&) = default; | ||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Line(s) | |||||
543 | 607 | | |||
544 | void KFileItem::setLocalPath(const QString &path) | 608 | void KFileItem::setLocalPath(const QString &path) | ||
545 | { | 609 | { | ||
546 | if (!d) { | 610 | if (!d) { | ||
547 | qCWarning(KIO_CORE) << "null item"; | 611 | qCWarning(KIO_CORE) << "null item"; | ||
548 | return; | 612 | return; | ||
549 | } | 613 | } | ||
550 | 614 | | |||
551 | d->m_entry.replace(KIO::UDSEntry::UDS_LOCAL_PATH, path); | 615 | d->m_entry.replace(KIO::UDSEntry::UDS_LOCAL_PATH, path); | ||
dfaure: No no, this won't work. entry() returns a copy, not a reference. | |||||
hoffmannrobert: Ah, sorry, yes. | |||||
552 | } | 616 | } | ||
553 | 617 | | |||
554 | void KFileItem::setName(const QString &name) | 618 | void KFileItem::setName(const QString &name) | ||
555 | { | 619 | { | ||
556 | if (!d) { | 620 | if (!d) { | ||
557 | qCWarning(KIO_CORE) << "null item"; | 621 | qCWarning(KIO_CORE) << "null item"; | ||
558 | return; | 622 | return; | ||
559 | } | 623 | } | ||
560 | 624 | | |||
625 | d->ensureInitialized(); | ||||
626 | | ||||
561 | d->m_strName = name; | 627 | d->m_strName = name; | ||
562 | if (!d->m_strName.isEmpty()) { | 628 | if (!d->m_strName.isEmpty()) { | ||
563 | d->m_strText = KIO::decodeFileName(d->m_strName); | 629 | d->m_strText = KIO::decodeFileName(d->m_strName); | ||
564 | } | 630 | } | ||
565 | if (d->m_entry.contains(KIO::UDSEntry::UDS_NAME)) { | 631 | if (d->m_entry.contains(KIO::UDSEntry::UDS_NAME)) { | ||
566 | d->m_entry.replace(KIO::UDSEntry::UDS_NAME, d->m_strName); // #195385 | 632 | d->m_entry.replace(KIO::UDSEntry::UDS_NAME, d->m_strName); // #195385 | ||
567 | } | 633 | } | ||
568 | 634 | | |||
569 | } | 635 | } | ||
570 | 636 | | |||
571 | QString KFileItem::linkDest() const | 637 | QString KFileItem::linkDest() const | ||
572 | { | 638 | { | ||
573 | if (!d) { | 639 | if (!d) { | ||
574 | return QString(); | 640 | return QString(); | ||
575 | } | 641 | } | ||
576 | 642 | | |||
643 | d->ensureInitialized(); | ||||
644 | | ||||
577 | // Extract it from the KIO::UDSEntry | 645 | // Extract it from the KIO::UDSEntry | ||
578 | const QString linkStr = d->m_entry.stringValue(KIO::UDSEntry::UDS_LINK_DEST); | 646 | const QString linkStr = d->m_entry.stringValue(KIO::UDSEntry::UDS_LINK_DEST); | ||
579 | if (!linkStr.isEmpty()) { | 647 | if (!linkStr.isEmpty()) { | ||
580 | return linkStr; | 648 | return linkStr; | ||
581 | } | 649 | } | ||
582 | 650 | | |||
583 | // If not in the KIO::UDSEntry, or if UDSEntry empty, use readlink() [if local URL] | 651 | // If not in the KIO::UDSEntry, or if UDSEntry empty, use readlink() [if local URL] | ||
584 | if (d->m_bIsLocalUrl) { | 652 | if (d->m_bIsLocalUrl) { | ||
585 | return QFile::symLinkTarget(d->m_url.adjusted(QUrl::StripTrailingSlash).toLocalFile()); | 653 | return QFile::symLinkTarget(d->m_url.adjusted(QUrl::StripTrailingSlash).toLocalFile()); | ||
586 | } | 654 | } | ||
587 | return QString(); | 655 | return QString(); | ||
588 | } | 656 | } | ||
589 | 657 | | |||
590 | QString KFileItemPrivate::localPath() const | 658 | QString KFileItemPrivate::localPath() const | ||
591 | { | 659 | { | ||
592 | if (m_bIsLocalUrl) { | 660 | if (m_bIsLocalUrl) { | ||
593 | return m_url.toLocalFile(); | 661 | return m_url.toLocalFile(); | ||
594 | } | 662 | } | ||
595 | 663 | | |||
664 | ensureInitialized(); | ||||
665 | | ||||
596 | // Extract the local path from the KIO::UDSEntry | 666 | // Extract the local path from the KIO::UDSEntry | ||
597 | return m_entry.stringValue(KIO::UDSEntry::UDS_LOCAL_PATH); | 667 | return m_entry.stringValue(KIO::UDSEntry::UDS_LOCAL_PATH); | ||
dfaure: here entry() would work, no? | |||||
hoffmannrobert: No, it's KFileItemPrivate. | |||||
598 | } | 668 | } | ||
599 | 669 | | |||
600 | QString KFileItem::localPath() const | 670 | QString KFileItem::localPath() const | ||
601 | { | 671 | { | ||
602 | if (!d) { | 672 | if (!d) { | ||
603 | return QString(); | 673 | return QString(); | ||
604 | } | 674 | } | ||
605 | 675 | | |||
Show All 11 Lines | |||||
617 | 687 | | |||
618 | bool KFileItem::hasExtendedACL() const | 688 | bool KFileItem::hasExtendedACL() const | ||
619 | { | 689 | { | ||
620 | if (!d) { | 690 | if (!d) { | ||
621 | return false; | 691 | return false; | ||
622 | } | 692 | } | ||
623 | 693 | | |||
624 | // Check if the field exists; its value doesn't matter | 694 | // Check if the field exists; its value doesn't matter | ||
625 | return d->m_entry.contains(KIO::UDSEntry::UDS_EXTENDED_ACL); | 695 | return entry().contains(KIO::UDSEntry::UDS_EXTENDED_ACL); | ||
626 | } | 696 | } | ||
627 | 697 | | |||
628 | KACL KFileItem::ACL() const | 698 | KACL KFileItem::ACL() const | ||
629 | { | 699 | { | ||
630 | if (!d) { | 700 | if (!d) { | ||
631 | return KACL(); | 701 | return KACL(); | ||
632 | } | 702 | } | ||
633 | 703 | | |||
634 | if (hasExtendedACL()) { | 704 | if (hasExtendedACL()) { | ||
635 | // Extract it from the KIO::UDSEntry | 705 | // Extract it from the KIO::UDSEntry | ||
636 | const QString fieldVal = d->m_entry.stringValue(KIO::UDSEntry::UDS_ACL_STRING); | 706 | const QString fieldVal = d->m_entry.stringValue(KIO::UDSEntry::UDS_ACL_STRING); | ||
637 | if (!fieldVal.isEmpty()) { | 707 | if (!fieldVal.isEmpty()) { | ||
638 | return KACL(fieldVal); | 708 | return KACL(fieldVal); | ||
639 | } | 709 | } | ||
640 | } | 710 | } | ||
711 | | ||||
641 | // create one from the basic permissions | 712 | // create one from the basic permissions | ||
642 | return KACL(d->m_permissions); | 713 | return KACL(d->m_permissions); | ||
643 | } | 714 | } | ||
644 | 715 | | |||
645 | KACL KFileItem::defaultACL() const | 716 | KACL KFileItem::defaultACL() const | ||
646 | { | 717 | { | ||
647 | if (!d) { | 718 | if (!d) { | ||
648 | return KACL(); | 719 | return KACL(); | ||
649 | } | 720 | } | ||
650 | 721 | | |||
651 | // Extract it from the KIO::UDSEntry | 722 | // Extract it from the KIO::UDSEntry | ||
652 | const QString fieldVal = d->m_entry.stringValue(KIO::UDSEntry::UDS_DEFAULT_ACL_STRING); | 723 | const QString fieldVal = entry().stringValue(KIO::UDSEntry::UDS_DEFAULT_ACL_STRING); | ||
dfaure: This use of d->m_entry needs a call to init(), no? | |||||
It does, now there via entry(). And ACL() needs init(), too, it's in hasExtendedACL() there. hoffmannrobert: It does, now there via entry(). And ACL() needs init(), too, it's in hasExtendedACL() there. | |||||
653 | if (!fieldVal.isEmpty()) { | 724 | if (!fieldVal.isEmpty()) { | ||
654 | return KACL(fieldVal); | 725 | return KACL(fieldVal); | ||
655 | } else { | 726 | } else { | ||
656 | return KACL(); | 727 | return KACL(); | ||
657 | } | 728 | } | ||
658 | } | 729 | } | ||
659 | 730 | | |||
660 | QDateTime KFileItem::time(FileTimes which) const | 731 | QDateTime KFileItem::time(FileTimes which) const | ||
661 | { | 732 | { | ||
662 | if (!d) { | 733 | if (!d) { | ||
663 | return QDateTime(); | 734 | return QDateTime(); | ||
664 | } | 735 | } | ||
665 | 736 | | |||
666 | return d->time(which); | 737 | return d->time(which); | ||
667 | } | 738 | } | ||
668 | 739 | | |||
669 | QString KFileItem::user() const | 740 | QString KFileItem::user() const | ||
670 | { | 741 | { | ||
671 | if (!d) { | 742 | if (!d) { | ||
672 | return QString(); | 743 | return QString(); | ||
673 | } | 744 | } | ||
674 | 745 | | |||
675 | return d->m_entry.stringValue(KIO::UDSEntry::UDS_USER); | 746 | return entry().stringValue(KIO::UDSEntry::UDS_USER); | ||
676 | } | 747 | } | ||
677 | 748 | | |||
678 | QString KFileItem::group() const | 749 | QString KFileItem::group() const | ||
679 | { | 750 | { | ||
680 | if (!d) { | 751 | if (!d) { | ||
681 | return QString(); | 752 | return QString(); | ||
682 | } | 753 | } | ||
683 | 754 | | |||
684 | return d->m_entry.stringValue(KIO::UDSEntry::UDS_GROUP); | 755 | return entry().stringValue(KIO::UDSEntry::UDS_GROUP); | ||
This kind of method (which only uses d->m_entry in one place) could be simplified by just doing return entry().stringValue(....); Then the init() would happen inside entry(). This would work in user() just above, too. dfaure: This kind of method (which only uses d->m_entry in one place) could be simplified by just doing… | |||||
And in defaultACL(), setLocalPath(), linkDest(), hasExtendedACL() and overlays(). hoffmannrobert: And in defaultACL(), setLocalPath(), linkDest(), hasExtendedACL() and overlays(). | |||||
685 | } | 756 | } | ||
686 | 757 | | |||
687 | bool KFileItemPrivate::isSlow() const | 758 | bool KFileItemPrivate::isSlow() const | ||
688 | { | 759 | { | ||
689 | if (m_slow == SlowUnknown) { | 760 | if (m_slow == SlowUnknown) { | ||
690 | const QString path = localPath(); | 761 | const QString path = localPath(); | ||
691 | if (!path.isEmpty()) { | 762 | if (!path.isEmpty()) { | ||
692 | const KFileSystemType::Type fsType = KFileSystemType::fileSystemType(path); | 763 | const KFileSystemType::Type fsType = KFileSystemType::fileSystemType(path); | ||
Show All 32 Lines | 792 | { | |||
725 | 796 | | |||
726 | if (!d->m_mimeType.isValid() || !d->m_bMimeTypeKnown) { | 797 | if (!d->m_mimeType.isValid() || !d->m_bMimeTypeKnown) { | ||
727 | QMimeDatabase db; | 798 | QMimeDatabase db; | ||
728 | if (isDir()) { | 799 | if (isDir()) { | ||
729 | d->m_mimeType = db.mimeTypeForName(QStringLiteral("inode/directory")); | 800 | d->m_mimeType = db.mimeTypeForName(QStringLiteral("inode/directory")); | ||
730 | } else { | 801 | } else { | ||
731 | bool isLocalUrl; | 802 | bool isLocalUrl; | ||
732 | const QUrl url = mostLocalUrl(&isLocalUrl); | 803 | const QUrl url = mostLocalUrl(&isLocalUrl); | ||
733 | d->m_mimeType = db.mimeTypeForUrl(url); | 804 | d->determineMimeTypeHelper(url); | ||
805 | | ||||
734 | // was: d->m_mimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl ); | 806 | // was: d->m_mimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl ); | ||
735 | // => we are no longer using d->m_fileMode for remote URLs. | 807 | // => we are no longer using d->m_fileMode for remote URLs. | ||
736 | Q_ASSERT(d->m_mimeType.isValid()); | 808 | Q_ASSERT(d->m_mimeType.isValid()); | ||
dfaure: missing "else" after this line? | |||||
737 | //qDebug() << d << "finding final mimetype for" << url << ":" << d->m_mimeType.name(); | 809 | //qDebug() << d << "finding final mimetype for" << url << ":" << d->m_mimeType.name(); | ||
738 | } | 810 | } | ||
739 | d->m_bMimeTypeKnown = true; | 811 | d->m_bMimeTypeKnown = true; | ||
740 | } | 812 | } | ||
741 | 813 | | |||
742 | if (d->m_delayedMimeTypes) { // if we delayed getting the iconName up till now, this is the right point in time to do so | 814 | if (d->m_delayedMimeTypes) { // if we delayed getting the iconName up till now, this is the right point in time to do so | ||
743 | d->m_delayedMimeTypes = false; | 815 | d->m_delayedMimeTypes = false; | ||
744 | d->m_useIconNameCache = false; | 816 | d->m_useIconNameCache = false; | ||
▲ Show 20 Lines • Show All 178 Lines • ▼ Show 20 Line(s) | 966 | { | |||
923 | if (isLocalUrl && !delaySlowOperations && mime.inherits(QStringLiteral("application/x-desktop"))) { | 995 | if (isLocalUrl && !delaySlowOperations && mime.inherits(QStringLiteral("application/x-desktop"))) { | ||
924 | d->m_iconName = iconFromDesktopFile(url.toLocalFile()); | 996 | d->m_iconName = iconFromDesktopFile(url.toLocalFile()); | ||
925 | if (!d->m_iconName.isEmpty()) { | 997 | if (!d->m_iconName.isEmpty()) { | ||
926 | d->m_useIconNameCache = d->m_bMimeTypeKnown; | 998 | d->m_useIconNameCache = d->m_bMimeTypeKnown; | ||
927 | return d->m_iconName; | 999 | return d->m_iconName; | ||
928 | } | 1000 | } | ||
929 | } | 1001 | } | ||
930 | 1002 | | |||
931 | if (isLocalUrl && !delaySlowOperations && isDir()) { | 1003 | if (isLocalUrl && !delaySlowOperations && isDir()) { | ||
It reads like a bit of a hack here, because reading .directory is unrelated to mimetype determination. But I think your idea is that isDir() is what we don't want to call right? dfaure: It reads like a bit of a hack here, because reading .directory is unrelated to mimetype… | |||||
932 | if (isDirectoryMounted(url)) { | 1004 | if (isDirectoryMounted(url)) { | ||
933 | d->m_iconName = iconFromDirectoryFile(url.toLocalFile()); | 1005 | d->m_iconName = iconFromDirectoryFile(url.toLocalFile()); | ||
934 | if (!d->m_iconName.isEmpty()) { | 1006 | if (!d->m_iconName.isEmpty()) { | ||
935 | d->m_useIconNameCache = d->m_bMimeTypeKnown; | 1007 | d->m_useIconNameCache = d->m_bMimeTypeKnown; | ||
936 | return d->m_iconName; | 1008 | return d->m_iconName; | ||
937 | } | 1009 | } | ||
938 | } | 1010 | } | ||
939 | 1011 | | |||
Show All 38 Lines | |||||
978 | } | 1050 | } | ||
979 | 1051 | | |||
980 | QStringList KFileItem::overlays() const | 1052 | QStringList KFileItem::overlays() const | ||
981 | { | 1053 | { | ||
982 | if (!d) { | 1054 | if (!d) { | ||
983 | return QStringList(); | 1055 | return QStringList(); | ||
984 | } | 1056 | } | ||
985 | 1057 | | |||
1058 | d->ensureInitialized(); | ||||
1059 | | ||||
986 | QStringList names = d->m_entry.stringValue(KIO::UDSEntry::UDS_ICON_OVERLAY_NAMES).split(QLatin1Char(','), QString::SkipEmptyParts); | 1060 | QStringList names = d->m_entry.stringValue(KIO::UDSEntry::UDS_ICON_OVERLAY_NAMES).split(QLatin1Char(','), QString::SkipEmptyParts); | ||
It's more fragile this way here, because the reader of this code won't see that d->m_bLink is initialized indirectly via entry() calling init(). This is why I had only suggested to use entry() in a few places, not in those other places which need init() for other reasons anyway. By fragile it means, it works today, but any further work/refactoring of this code is likely to break. Same problem in linkDest(). dfaure: It's more fragile this way here, because the reader of this code won't see that d->m_bLink is… | |||||
987 | 1061 | | |||
988 | if (d->m_bLink) { | 1062 | if (d->m_bLink) { | ||
989 | names.append(QStringLiteral("emblem-symbolic-link")); | 1063 | names.append(QStringLiteral("emblem-symbolic-link")); | ||
990 | } | 1064 | } | ||
991 | 1065 | | |||
992 | if (!isReadable()) { | 1066 | if (!isReadable()) { | ||
993 | names.append(QStringLiteral("emblem-locked")); | 1067 | names.append(QStringLiteral("emblem-locked")); | ||
994 | } | 1068 | } | ||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Line(s) | |||||
1044 | } | 1118 | } | ||
1045 | 1119 | | |||
1046 | bool KFileItem::isReadable() const | 1120 | bool KFileItem::isReadable() const | ||
1047 | { | 1121 | { | ||
1048 | if (!d) { | 1122 | if (!d) { | ||
1049 | return false; | 1123 | return false; | ||
1050 | } | 1124 | } | ||
1051 | 1125 | | |||
1126 | d->ensureInitialized(); | ||||
1127 | | ||||
1052 | /* | 1128 | /* | ||
1053 | struct passwd * user = getpwuid( geteuid() ); | 1129 | struct passwd * user = getpwuid( geteuid() ); | ||
1054 | bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user); | 1130 | bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user); | ||
1055 | // This gets ugly for the group.... | 1131 | // This gets ugly for the group.... | ||
1056 | // Maybe we want a static QString for the user and a static QStringList | 1132 | // Maybe we want a static QString for the user and a static QStringList | ||
1057 | // for the groups... then we need to handle the deletion properly... | 1133 | // for the groups... then we need to handle the deletion properly... | ||
1058 | */ | 1134 | */ | ||
1059 | 1135 | | |||
Show All 19 Lines | |||||
1079 | } | 1155 | } | ||
1080 | 1156 | | |||
1081 | bool KFileItem::isWritable() const | 1157 | bool KFileItem::isWritable() const | ||
1082 | { | 1158 | { | ||
1083 | if (!d) { | 1159 | if (!d) { | ||
1084 | return false; | 1160 | return false; | ||
1085 | } | 1161 | } | ||
1086 | 1162 | | |||
1163 | d->ensureInitialized(); | ||||
1164 | | ||||
1087 | /* | 1165 | /* | ||
1088 | struct passwd * user = getpwuid( geteuid() ); | 1166 | struct passwd * user = getpwuid( geteuid() ); | ||
1089 | bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user); | 1167 | bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user); | ||
1090 | // This gets ugly for the group.... | 1168 | // This gets ugly for the group.... | ||
1091 | // Maybe we want a static QString for the user and a static QStringList | 1169 | // Maybe we want a static QString for the user and a static QStringList | ||
1092 | // for the groups... then we need to handle the deletion properly... | 1170 | // for the groups... then we need to handle the deletion properly... | ||
1093 | */ | 1171 | */ | ||
1094 | 1172 | | |||
Show All 39 Lines | |||||
1134 | } | 1212 | } | ||
1135 | 1213 | | |||
1136 | bool KFileItem::isDir() const | 1214 | bool KFileItem::isDir() const | ||
1137 | { | 1215 | { | ||
1138 | if (!d) { | 1216 | if (!d) { | ||
1139 | return false; | 1217 | return false; | ||
1140 | } | 1218 | } | ||
1141 | 1219 | | |||
1220 | if (d->m_bSkipMimeTypeFromContent) { | ||||
1221 | return false; | ||||
1222 | } | ||||
1223 | | ||||
1224 | d->ensureInitialized(); | ||||
1225 | | ||||
1142 | if (d->m_fileMode == KFileItem::Unknown) { | 1226 | if (d->m_fileMode == KFileItem::Unknown) { | ||
1143 | // Probably the file was deleted already, and KDirLister hasn't told the world yet. | 1227 | // Probably the file was deleted already, and KDirLister hasn't told the world yet. | ||
1144 | //qDebug() << d << url() << "can't say -> false"; | 1228 | //qDebug() << d << url() << "can't say -> false"; | ||
1145 | return false; // can't say for sure, so no | 1229 | return false; // can't say for sure, so no | ||
1146 | } | 1230 | } | ||
1147 | return (d->m_fileMode & QT_STAT_MASK) == QT_STAT_DIR; | 1231 | return (d->m_fileMode & QT_STAT_MASK) == QT_STAT_DIR; | ||
1148 | } | 1232 | } | ||
1149 | 1233 | | |||
▲ Show 20 Lines • Show All 114 Lines • ▼ Show 20 Line(s) | |||||
1264 | } | 1348 | } | ||
1265 | 1349 | | |||
1266 | QString KFileItem::permissionsString() const | 1350 | QString KFileItem::permissionsString() const | ||
1267 | { | 1351 | { | ||
1268 | if (!d) { | 1352 | if (!d) { | ||
1269 | return QString(); | 1353 | return QString(); | ||
1270 | } | 1354 | } | ||
1271 | 1355 | | |||
1356 | d->ensureInitialized(); | ||||
1357 | | ||||
1272 | if (d->m_access.isNull() && d->m_permissions != KFileItem::Unknown) { | 1358 | if (d->m_access.isNull() && d->m_permissions != KFileItem::Unknown) { | ||
1273 | d->m_access = d->parsePermissions(d->m_permissions); | 1359 | d->m_access = d->parsePermissions(d->m_permissions); | ||
1274 | } | 1360 | } | ||
1275 | 1361 | | |||
1276 | return d->m_access; | 1362 | return d->m_access; | ||
1277 | } | 1363 | } | ||
1278 | 1364 | | |||
1279 | // check if we need to cache this | 1365 | // check if we need to cache this | ||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Line(s) | |||||
1388 | } | 1474 | } | ||
1389 | 1475 | | |||
1390 | mode_t KFileItem::permissions() const | 1476 | mode_t KFileItem::permissions() const | ||
1391 | { | 1477 | { | ||
1392 | if (!d) { | 1478 | if (!d) { | ||
1393 | return 0; | 1479 | return 0; | ||
1394 | } | 1480 | } | ||
1395 | 1481 | | |||
1482 | d->ensureInitialized(); | ||||
1483 | | ||||
1396 | return d->m_permissions; | 1484 | return d->m_permissions; | ||
1397 | } | 1485 | } | ||
1398 | 1486 | | |||
1399 | mode_t KFileItem::mode() const | 1487 | mode_t KFileItem::mode() const | ||
1400 | { | 1488 | { | ||
1401 | if (!d) { | 1489 | if (!d) { | ||
1402 | return 0; | 1490 | return 0; | ||
1403 | } | 1491 | } | ||
1404 | 1492 | | |||
1493 | d->ensureInitialized(); | ||||
1494 | | ||||
1405 | return d->m_fileMode; | 1495 | return d->m_fileMode; | ||
1406 | } | 1496 | } | ||
1407 | 1497 | | |||
1408 | bool KFileItem::isLink() const | 1498 | bool KFileItem::isLink() const | ||
1409 | { | 1499 | { | ||
1410 | if (!d) { | 1500 | if (!d) { | ||
1411 | return false; | 1501 | return false; | ||
1412 | } | 1502 | } | ||
1413 | 1503 | | |||
1504 | d->ensureInitialized(); | ||||
1505 | | ||||
1414 | return d->m_bLink; | 1506 | return d->m_bLink; | ||
1415 | } | 1507 | } | ||
1416 | 1508 | | |||
1417 | bool KFileItem::isLocalFile() const | 1509 | bool KFileItem::isLocalFile() const | ||
1418 | { | 1510 | { | ||
1419 | if (!d) { | 1511 | if (!d) { | ||
1420 | return false; | 1512 | return false; | ||
1421 | } | 1513 | } | ||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Line(s) | 1568 | { | |||
1477 | if (!d) { | 1569 | if (!d) { | ||
1478 | return QMimeType(); | 1570 | return QMimeType(); | ||
1479 | } | 1571 | } | ||
1480 | 1572 | | |||
1481 | if (!d->m_mimeType.isValid()) { | 1573 | if (!d->m_mimeType.isValid()) { | ||
1482 | // On-demand fast (but not always accurate) mimetype determination | 1574 | // On-demand fast (but not always accurate) mimetype determination | ||
1483 | Q_ASSERT(!d->m_url.isEmpty()); | 1575 | Q_ASSERT(!d->m_url.isEmpty()); | ||
1484 | QMimeDatabase db; | 1576 | QMimeDatabase db; | ||
1485 | if (isDir()) { | 1577 | if (isDir()) { | ||
dfaure: my suggestion would simplify this here too | |||||
1486 | d->m_mimeType = db.mimeTypeForName(QStringLiteral("inode/directory")); | 1578 | d->m_mimeType = db.mimeTypeForName(QStringLiteral("inode/directory")); | ||
1487 | return d->m_mimeType; | 1579 | return d->m_mimeType; | ||
1488 | } | 1580 | } | ||
1489 | const QUrl url = mostLocalUrl(); | 1581 | const QUrl url = mostLocalUrl(); | ||
1490 | if (d->m_delayedMimeTypes) { | 1582 | if (d->m_delayedMimeTypes) { | ||
1491 | const QList<QMimeType> mimeTypes = db.mimeTypesForFileName(url.path()); | 1583 | const QList<QMimeType> mimeTypes = db.mimeTypesForFileName(url.path()); | ||
1492 | if (mimeTypes.isEmpty()) { | 1584 | if (mimeTypes.isEmpty()) { | ||
1493 | d->m_mimeType = db.mimeTypeForName(QStringLiteral("application/octet-stream")); | 1585 | d->m_mimeType = db.mimeTypeForName(QStringLiteral("application/octet-stream")); | ||
1494 | d->m_bMimeTypeKnown = false; | 1586 | d->m_bMimeTypeKnown = false; | ||
1495 | } else { | 1587 | } else { | ||
1496 | d->m_mimeType = mimeTypes.first(); | 1588 | d->m_mimeType = mimeTypes.first(); | ||
1497 | // If there were conflicting globs. determineMimeType will be able to do better. | 1589 | // If there were conflicting globs. determineMimeType will be able to do better. | ||
1498 | d->m_bMimeTypeKnown = (mimeTypes.count() == 1); | 1590 | d->m_bMimeTypeKnown = (mimeTypes.count() == 1); | ||
1499 | } | 1591 | } | ||
1500 | } else { | 1592 | } else { | ||
1501 | // ## d->m_fileMode isn't used anymore (for remote urls) | 1593 | // ## d->m_fileMode isn't used anymore (for remote urls) | ||
1502 | d->m_mimeType = db.mimeTypeForUrl(url); | 1594 | d->determineMimeTypeHelper(url); | ||
1503 | d->m_bMimeTypeKnown = true; | 1595 | d->m_bMimeTypeKnown = true; | ||
1504 | } | 1596 | } | ||
1505 | } | 1597 | } | ||
1506 | return d->m_mimeType; | 1598 | return d->m_mimeType; | ||
dfaure: same here -- duplicated code => move to helper function | |||||
1507 | } | 1599 | } | ||
1508 | 1600 | | |||
1509 | KIO::UDSEntry KFileItem::entry() const | 1601 | KIO::UDSEntry KFileItem::entry() const | ||
1510 | { | 1602 | { | ||
1511 | if (!d) { | 1603 | if (!d) { | ||
1512 | return KIO::UDSEntry(); | 1604 | return KIO::UDSEntry(); | ||
1513 | } | 1605 | } | ||
1514 | 1606 | | |||
1607 | d->ensureInitialized(); | ||||
1608 | | ||||
1515 | return d->m_entry; | 1609 | return d->m_entry; | ||
1516 | } | 1610 | } | ||
1517 | 1611 | | |||
1518 | bool KFileItem::isNull() const | 1612 | bool KFileItem::isNull() const | ||
1519 | { | 1613 | { | ||
1520 | return d == nullptr; | 1614 | return d == nullptr; | ||
1521 | } | 1615 | } | ||
1522 | 1616 | | |||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Line(s) | |||||
1581 | } | 1675 | } | ||
1582 | 1676 | | |||
1583 | bool KFileItem::isRegularFile() const | 1677 | bool KFileItem::isRegularFile() const | ||
1584 | { | 1678 | { | ||
1585 | if (!d) { | 1679 | if (!d) { | ||
1586 | return false; | 1680 | return false; | ||
1587 | } | 1681 | } | ||
1588 | 1682 | | |||
1683 | d->ensureInitialized(); | ||||
1684 | | ||||
1589 | return (d->m_fileMode & QT_STAT_MASK) == QT_STAT_REG; | 1685 | return (d->m_fileMode & QT_STAT_MASK) == QT_STAT_REG; | ||
1590 | } | 1686 | } | ||
1591 | 1687 | | |||
1592 | QDebug operator<<(QDebug stream, const KFileItem &item) | 1688 | QDebug operator<<(QDebug stream, const KFileItem &item) | ||
1593 | { | 1689 | { | ||
1594 | QDebugStateSaver saver(stream); | 1690 | QDebugStateSaver saver(stream); | ||
1595 | stream.nospace(); | 1691 | stream.nospace(); | ||
1596 | if (item.isNull()) { | 1692 | if (item.isNull()) { | ||
1597 | stream << "[null KFileItem]"; | 1693 | stream << "[null KFileItem]"; | ||
1598 | } else { | 1694 | } else { | ||
1599 | stream << "[KFileItem for " << item.url() << "]"; | 1695 | stream << "[KFileItem for " << item.url() << "]"; | ||
1600 | } | 1696 | } | ||
1601 | return stream; | 1697 | return stream; | ||
1602 | } | 1698 | } |
Remove this comment, no longer true (only keep the first line, remove the other 3)