KIO
kfileitem.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE project 00002 Copyright (C) 1999-2006 David Faure <faure@kde.org> 00003 2001 Carsten Pfeiffer <pfeiffer@kde.org> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "kfileitem.h" 00022 00023 #include <config.h> 00024 #include <config-kio.h> 00025 00026 #include <sys/time.h> 00027 #include <pwd.h> 00028 #include <grp.h> 00029 #include <sys/types.h> 00030 #include <sys/stat.h> 00031 00032 #include <assert.h> 00033 #include <unistd.h> 00034 00035 #include <QtCore/QDate> 00036 #include <QtCore/QDir> 00037 #include <QtCore/QFile> 00038 #include <QtCore/QMap> 00039 #include <QtGui/QApplication> 00040 #include <QtGui/QPalette> 00041 #include <QTextDocument> 00042 00043 #include <kdebug.h> 00044 #include <kfilemetainfo.h> 00045 #include <kglobal.h> 00046 #include <kiconloader.h> 00047 #include <klocale.h> 00048 #include <kmimetype.h> 00049 #include <krun.h> 00050 #include <kde_file.h> 00051 #include <kdesktopfile.h> 00052 #include <kmountpoint.h> 00053 #include <kconfiggroup.h> 00054 #ifndef Q_OS_WIN 00055 #include <knfsshare.h> 00056 #include <ksambashare.h> 00057 #endif 00058 #include <kfilesystemtype_p.h> 00059 00060 class KFileItemPrivate : public QSharedData 00061 { 00062 public: 00063 KFileItemPrivate(const KIO::UDSEntry& entry, 00064 mode_t mode, mode_t permissions, 00065 const KUrl& itemOrDirUrl, 00066 bool urlIsDirectory, 00067 bool delayedMimeTypes) 00068 : m_entry( entry ), 00069 m_url(itemOrDirUrl), 00070 m_strName(), 00071 m_strText(), 00072 m_iconName(), 00073 m_strLowerCaseName(), 00074 m_pMimeType( 0 ), 00075 m_fileMode( mode ), 00076 m_permissions( permissions ), 00077 m_bMarked( false ), 00078 m_bLink( false ), 00079 m_bIsLocalUrl(itemOrDirUrl.isLocalFile()), 00080 m_bMimeTypeKnown( false ), 00081 m_delayedMimeTypes( delayedMimeTypes ), 00082 m_useIconNameCache(false), 00083 m_hidden(Auto), 00084 m_slow(SlowUnknown) 00085 { 00086 if (entry.count() != 0) { 00087 readUDSEntry( urlIsDirectory ); 00088 } else { 00089 Q_ASSERT(!urlIsDirectory); 00090 m_strName = itemOrDirUrl.fileName(); 00091 m_strText = KIO::decodeFileName( m_strName ); 00092 } 00093 init(); 00094 } 00095 00096 ~KFileItemPrivate() 00097 { 00098 } 00099 00106 void init(); 00107 00108 QString localPath() const; 00109 KIO::filesize_t size() const; 00110 KDateTime time( KFileItem::FileTimes which ) const; 00111 void setTime(KFileItem::FileTimes which, long long time_t_val) const; 00112 bool cmp( const KFileItemPrivate & item ) const; 00113 QString user() const; 00114 QString group() const; 00115 bool isSlow() const; 00116 00121 void readUDSEntry( bool _urlIsDirectory ); 00122 00126 QString parsePermissions( mode_t perm ) const; 00127 00131 mutable KIO::UDSEntry m_entry; 00135 KUrl m_url; 00136 00140 QString m_strName; 00141 00146 QString m_strText; 00147 00151 mutable QString m_iconName; 00152 00156 mutable QString m_strLowerCaseName; 00157 00161 mutable KMimeType::Ptr m_pMimeType; 00162 00166 mode_t m_fileMode; 00170 mode_t m_permissions; 00171 00175 bool m_bMarked:1; 00179 bool m_bLink:1; 00183 bool m_bIsLocalUrl:1; 00184 00185 mutable bool m_bMimeTypeKnown:1; 00186 bool m_delayedMimeTypes:1; 00187 00189 mutable bool m_useIconNameCache:1; 00190 00191 // Auto: check leading dot. 00192 enum { Auto, Hidden, Shown } m_hidden:3; 00193 00194 // Slow? (nfs/smb/ssh) 00195 mutable enum { SlowUnknown, Fast, Slow } m_slow:3; 00196 00197 // For special case like link to dirs over FTP 00198 QString m_guessedMimeType; 00199 mutable QString m_access; 00200 #ifndef KDE_NO_DEPRECATED 00201 QMap<const void*, void*> m_extra; // DEPRECATED 00202 #endif 00203 mutable KFileMetaInfo m_metaInfo; 00204 00205 enum { NumFlags = KFileItem::CreationTime + 1 }; 00206 mutable KDateTime m_time[3]; 00207 }; 00208 00209 void KFileItemPrivate::init() 00210 { 00211 m_access.clear(); 00212 // metaInfo = KFileMetaInfo(); 00213 00214 // determine mode and/or permissions if unknown 00215 // TODO: delay this until requested 00216 if ( m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown ) 00217 { 00218 mode_t mode = 0; 00219 if ( m_url.isLocalFile() ) 00220 { 00221 /* directories may not have a slash at the end if 00222 * we want to stat() them; it requires that we 00223 * change into it .. which may not be allowed 00224 * stat("/is/unaccessible") -> rwx------ 00225 * stat("/is/unaccessible/") -> EPERM H.Z. 00226 * This is the reason for the -1 00227 */ 00228 KDE_struct_stat buf; 00229 const QString path = m_url.toLocalFile( KUrl::RemoveTrailingSlash ); 00230 if ( KDE::lstat( path, &buf ) == 0 ) 00231 { 00232 mode = buf.st_mode; 00233 if ( S_ISLNK( mode ) ) 00234 { 00235 m_bLink = true; 00236 if ( KDE::stat( path, &buf ) == 0 ) 00237 mode = buf.st_mode; 00238 else // link pointing to nowhere (see kio/file/file.cc) 00239 mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO; 00240 } 00241 // While we're at it, store the times 00242 setTime(KFileItem::ModificationTime, buf.st_mtime); 00243 setTime(KFileItem::AccessTime, buf.st_atime); 00244 if ( m_fileMode == KFileItem::Unknown ) 00245 m_fileMode = mode & S_IFMT; // extract file type 00246 if ( m_permissions == KFileItem::Unknown ) 00247 m_permissions = mode & 07777; // extract permissions 00248 } else { 00249 kDebug() << path << "does not exist anymore"; 00250 } 00251 } 00252 } 00253 } 00254 00255 void KFileItemPrivate::readUDSEntry( bool _urlIsDirectory ) 00256 { 00257 // extract fields from the KIO::UDS Entry 00258 00259 m_fileMode = m_entry.numberValue( KIO::UDSEntry::UDS_FILE_TYPE ); 00260 m_permissions = m_entry.numberValue( KIO::UDSEntry::UDS_ACCESS ); 00261 m_strName = m_entry.stringValue( KIO::UDSEntry::UDS_NAME ); 00262 00263 const QString displayName = m_entry.stringValue( KIO::UDSEntry::UDS_DISPLAY_NAME ); 00264 if (!displayName.isEmpty()) 00265 m_strText = displayName; 00266 else 00267 m_strText = KIO::decodeFileName( m_strName ); 00268 00269 const QString urlStr = m_entry.stringValue( KIO::UDSEntry::UDS_URL ); 00270 const bool UDS_URL_seen = !urlStr.isEmpty(); 00271 if ( UDS_URL_seen ) { 00272 m_url = KUrl( urlStr ); 00273 if ( m_url.isLocalFile() ) 00274 m_bIsLocalUrl = true; 00275 } 00276 const QString mimeTypeStr = m_entry.stringValue( KIO::UDSEntry::UDS_MIME_TYPE ); 00277 m_bMimeTypeKnown = !mimeTypeStr.isEmpty(); 00278 if ( m_bMimeTypeKnown ) 00279 m_pMimeType = KMimeType::mimeType( mimeTypeStr ); 00280 00281 m_guessedMimeType = m_entry.stringValue( KIO::UDSEntry::UDS_GUESSED_MIME_TYPE ); 00282 m_bLink = !m_entry.stringValue( KIO::UDSEntry::UDS_LINK_DEST ).isEmpty(); // we don't store the link dest 00283 00284 const int hiddenVal = m_entry.numberValue( KIO::UDSEntry::UDS_HIDDEN, -1 ); 00285 m_hidden = hiddenVal == 1 ? Hidden : ( hiddenVal == 0 ? Shown : Auto ); 00286 00287 // avoid creating these QStrings again and again 00288 static const QString& dot = KGlobal::staticQString("."); 00289 if ( _urlIsDirectory && !UDS_URL_seen && !m_strName.isEmpty() && m_strName != dot ) 00290 m_url.addPath( m_strName ); 00291 00292 m_iconName.clear(); 00293 } 00294 00295 inline //because it is used only in one place 00296 KIO::filesize_t KFileItemPrivate::size() const 00297 { 00298 // Extract it from the KIO::UDSEntry 00299 long long fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_SIZE, -1 ); 00300 if ( fieldVal != -1 ) { 00301 return fieldVal; 00302 } 00303 00304 // If not in the KIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL] 00305 if ( m_bIsLocalUrl ) { 00306 KDE_struct_stat buf; 00307 if ( KDE::stat( m_url.toLocalFile(KUrl::RemoveTrailingSlash), &buf ) == 0 ) 00308 return buf.st_size; 00309 } 00310 return 0; 00311 } 00312 00313 void KFileItemPrivate::setTime(KFileItem::FileTimes mappedWhich, long long time_t_val) const 00314 { 00315 m_time[mappedWhich].setTime_t(time_t_val); 00316 m_time[mappedWhich] = m_time[mappedWhich].toLocalZone(); // #160979 00317 } 00318 00319 KDateTime KFileItemPrivate::time( KFileItem::FileTimes mappedWhich ) const 00320 { 00321 if ( !m_time[mappedWhich].isNull() ) 00322 return m_time[mappedWhich]; 00323 00324 // Extract it from the KIO::UDSEntry 00325 long long fieldVal = -1; 00326 switch ( mappedWhich ) { 00327 case KFileItem::ModificationTime: 00328 fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_MODIFICATION_TIME, -1 ); 00329 break; 00330 case KFileItem::AccessTime: 00331 fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_ACCESS_TIME, -1 ); 00332 break; 00333 case KFileItem::CreationTime: 00334 fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_CREATION_TIME, -1 ); 00335 break; 00336 } 00337 if ( fieldVal != -1 ) { 00338 setTime(mappedWhich, fieldVal); 00339 return m_time[mappedWhich]; 00340 } 00341 00342 // If not in the KIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL] 00343 if ( m_bIsLocalUrl ) 00344 { 00345 KDE_struct_stat buf; 00346 if ( KDE::stat( m_url.toLocalFile(KUrl::RemoveTrailingSlash), &buf ) == 0 ) 00347 { 00348 setTime(KFileItem::ModificationTime, buf.st_mtime); 00349 setTime(KFileItem::AccessTime, buf.st_atime); 00350 m_time[KFileItem::CreationTime] = KDateTime(); 00351 return m_time[mappedWhich]; 00352 } 00353 } 00354 return KDateTime(); 00355 } 00356 00357 inline //because it is used only in one place 00358 bool KFileItemPrivate::cmp( const KFileItemPrivate & item ) const 00359 { 00360 #if 0 00361 kDebug() << "Comparing" << m_url << "and" << item.m_url; 00362 kDebug() << " name" << (m_strName == item.m_strName); 00363 kDebug() << " local" << (m_bIsLocalUrl == item.m_bIsLocalUrl); 00364 kDebug() << " mode" << (m_fileMode == item.m_fileMode); 00365 kDebug() << " perm" << (m_permissions == item.m_permissions); 00366 kDebug() << " UDS_USER" << (user() == item.user()); 00367 kDebug() << " UDS_GROUP" << (group() == item.group()); 00368 kDebug() << " UDS_EXTENDED_ACL" << (m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL )); 00369 kDebug() << " UDS_ACL_STRING" << (m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING )); 00370 kDebug() << " UDS_DEFAULT_ACL_STRING" << (m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING )); 00371 kDebug() << " m_bLink" << (m_bLink == item.m_bLink); 00372 kDebug() << " m_hidden" << (m_hidden == item.m_hidden); 00373 kDebug() << " size" << (size() == item.size()); 00374 kDebug() << " ModificationTime" << (time(KFileItem::ModificationTime) == item.time(KFileItem::ModificationTime)); 00375 kDebug() << " UDS_ICON_NAME" << (m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME )); 00376 #endif 00377 return ( m_strName == item.m_strName 00378 && m_bIsLocalUrl == item.m_bIsLocalUrl 00379 && m_fileMode == item.m_fileMode 00380 && m_permissions == item.m_permissions 00381 && user() == item.user() 00382 && group() == item.group() 00383 && m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL ) 00384 && m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ) 00385 && m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING ) 00386 && m_bLink == item.m_bLink 00387 && m_hidden == item.m_hidden 00388 && size() == item.size() 00389 && time(KFileItem::ModificationTime) == item.time(KFileItem::ModificationTime) // TODO only if already known! 00390 && m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ) 00391 ); 00392 00393 // Don't compare the mimetypes here. They might not be known, and we don't want to 00394 // do the slow operation of determining them here. 00395 } 00396 00397 inline //because it is used only in one place 00398 QString KFileItemPrivate::parsePermissions(mode_t perm) const 00399 { 00400 static char buffer[ 12 ]; 00401 00402 char uxbit,gxbit,oxbit; 00403 00404 if ( (perm & (S_IXUSR|S_ISUID)) == (S_IXUSR|S_ISUID) ) 00405 uxbit = 's'; 00406 else if ( (perm & (S_IXUSR|S_ISUID)) == S_ISUID ) 00407 uxbit = 'S'; 00408 else if ( (perm & (S_IXUSR|S_ISUID)) == S_IXUSR ) 00409 uxbit = 'x'; 00410 else 00411 uxbit = '-'; 00412 00413 if ( (perm & (S_IXGRP|S_ISGID)) == (S_IXGRP|S_ISGID) ) 00414 gxbit = 's'; 00415 else if ( (perm & (S_IXGRP|S_ISGID)) == S_ISGID ) 00416 gxbit = 'S'; 00417 else if ( (perm & (S_IXGRP|S_ISGID)) == S_IXGRP ) 00418 gxbit = 'x'; 00419 else 00420 gxbit = '-'; 00421 00422 if ( (perm & (S_IXOTH|S_ISVTX)) == (S_IXOTH|S_ISVTX) ) 00423 oxbit = 't'; 00424 else if ( (perm & (S_IXOTH|S_ISVTX)) == S_ISVTX ) 00425 oxbit = 'T'; 00426 else if ( (perm & (S_IXOTH|S_ISVTX)) == S_IXOTH ) 00427 oxbit = 'x'; 00428 else 00429 oxbit = '-'; 00430 00431 // Include the type in the first char like kde3 did; people are more used to seeing it, 00432 // even though it's not really part of the permissions per se. 00433 if (m_bLink) 00434 buffer[0] = 'l'; 00435 else if (m_fileMode != KFileItem::Unknown) { 00436 if (S_ISDIR(m_fileMode)) 00437 buffer[0] = 'd'; 00438 else if (S_ISSOCK(m_fileMode)) 00439 buffer[0] = 's'; 00440 else if (S_ISCHR(m_fileMode)) 00441 buffer[0] = 'c'; 00442 else if (S_ISBLK(m_fileMode)) 00443 buffer[0] = 'b'; 00444 else if (S_ISFIFO(m_fileMode)) 00445 buffer[0] = 'p'; 00446 else 00447 buffer[0] = '-'; 00448 } else { 00449 buffer[0] = '-'; 00450 } 00451 00452 buffer[1] = ((( perm & S_IRUSR ) == S_IRUSR ) ? 'r' : '-' ); 00453 buffer[2] = ((( perm & S_IWUSR ) == S_IWUSR ) ? 'w' : '-' ); 00454 buffer[3] = uxbit; 00455 buffer[4] = ((( perm & S_IRGRP ) == S_IRGRP ) ? 'r' : '-' ); 00456 buffer[5] = ((( perm & S_IWGRP ) == S_IWGRP ) ? 'w' : '-' ); 00457 buffer[6] = gxbit; 00458 buffer[7] = ((( perm & S_IROTH ) == S_IROTH ) ? 'r' : '-' ); 00459 buffer[8] = ((( perm & S_IWOTH ) == S_IWOTH ) ? 'w' : '-' ); 00460 buffer[9] = oxbit; 00461 // if (hasExtendedACL()) 00462 if (m_entry.contains(KIO::UDSEntry::UDS_EXTENDED_ACL)) { 00463 buffer[10] = '+'; 00464 buffer[11] = 0; 00465 } else { 00466 buffer[10] = 0; 00467 } 00468 00469 return QString::fromLatin1(buffer); 00470 } 00471 00472 00474 00475 KFileItem::KFileItem() 00476 : d(0) 00477 { 00478 } 00479 00480 KFileItem::KFileItem( const KIO::UDSEntry& entry, const KUrl& itemOrDirUrl, 00481 bool delayedMimeTypes, bool urlIsDirectory ) 00482 : d(new KFileItemPrivate(entry, KFileItem::Unknown, KFileItem::Unknown, 00483 itemOrDirUrl, urlIsDirectory, delayedMimeTypes)) 00484 { 00485 } 00486 00487 KFileItem::KFileItem( mode_t mode, mode_t permissions, const KUrl& url, bool delayedMimeTypes ) 00488 : d(new KFileItemPrivate(KIO::UDSEntry(), mode, permissions, 00489 url, false, delayedMimeTypes)) 00490 { 00491 } 00492 00493 KFileItem::KFileItem( const KUrl &url, const QString &mimeType, mode_t mode ) 00494 : d(new KFileItemPrivate(KIO::UDSEntry(), mode, KFileItem::Unknown, 00495 url, false, false)) 00496 { 00497 d->m_bMimeTypeKnown = !mimeType.isEmpty(); 00498 if (d->m_bMimeTypeKnown) 00499 d->m_pMimeType = KMimeType::mimeType( mimeType ); 00500 } 00501 00502 00503 KFileItem::KFileItem(const KFileItem& other) 00504 : d(other.d) 00505 { 00506 } 00507 00508 KFileItem::~KFileItem() 00509 { 00510 } 00511 00512 void KFileItem::refresh() 00513 { 00514 if (!d) { 00515 kWarning() << "null item"; 00516 return; 00517 } 00518 00519 d->m_fileMode = KFileItem::Unknown; 00520 d->m_permissions = KFileItem::Unknown; 00521 d->m_metaInfo = KFileMetaInfo(); 00522 d->m_hidden = KFileItemPrivate::Auto; 00523 refreshMimeType(); 00524 00525 // Basically, we can't trust any information we got while listing. 00526 // Everything could have changed... 00527 // Clearing m_entry makes it possible to detect changes in the size of the file, 00528 // the time information, etc. 00529 d->m_entry.clear(); 00530 d->init(); 00531 } 00532 00533 void KFileItem::refreshMimeType() 00534 { 00535 if (!d) 00536 return; 00537 00538 d->m_pMimeType = 0; 00539 d->m_bMimeTypeKnown = false; 00540 d->m_iconName.clear(); 00541 } 00542 00543 void KFileItem::setUrl( const KUrl &url ) 00544 { 00545 if (!d) { 00546 kWarning() << "null item"; 00547 return; 00548 } 00549 00550 d->m_url = url; 00551 setName( url.fileName() ); 00552 } 00553 00554 void KFileItem::setName( const QString& name ) 00555 { 00556 if (!d) { 00557 kWarning() << "null item"; 00558 return; 00559 } 00560 00561 d->m_strName = name; 00562 d->m_strText = KIO::decodeFileName( d->m_strName ); 00563 if (d->m_entry.contains(KIO::UDSEntry::UDS_NAME)) 00564 d->m_entry.insert(KIO::UDSEntry::UDS_NAME, d->m_strName); // #195385 00565 00566 } 00567 00568 QString KFileItem::linkDest() const 00569 { 00570 if (!d) 00571 return QString(); 00572 00573 // Extract it from the KIO::UDSEntry 00574 const QString linkStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_LINK_DEST ); 00575 if ( !linkStr.isEmpty() ) 00576 return linkStr; 00577 00578 // If not in the KIO::UDSEntry, or if UDSEntry empty, use readlink() [if local URL] 00579 if ( d->m_bIsLocalUrl ) 00580 { 00581 char buf[1000]; 00582 int n = readlink( QFile::encodeName(d->m_url.toLocalFile( KUrl::RemoveTrailingSlash )), buf, sizeof(buf)-1 ); 00583 if ( n != -1 ) 00584 { 00585 buf[ n ] = 0; 00586 return QFile::decodeName( buf ); 00587 } 00588 } 00589 return QString(); 00590 } 00591 00592 QString KFileItemPrivate::localPath() const 00593 { 00594 if (m_bIsLocalUrl) { 00595 return m_url.toLocalFile(); 00596 } 00597 00598 // Extract the local path from the KIO::UDSEntry 00599 return m_entry.stringValue( KIO::UDSEntry::UDS_LOCAL_PATH ); 00600 } 00601 00602 QString KFileItem::localPath() const 00603 { 00604 if (!d) 00605 return QString(); 00606 00607 return d->localPath(); 00608 } 00609 00610 KIO::filesize_t KFileItem::size() const 00611 { 00612 if (!d) 00613 return 0; 00614 00615 return d->size(); 00616 } 00617 00618 bool KFileItem::hasExtendedACL() const 00619 { 00620 if (!d) 00621 return false; 00622 00623 // Check if the field exists; its value doesn't matter 00624 return d->m_entry.contains(KIO::UDSEntry::UDS_EXTENDED_ACL); 00625 } 00626 00627 KACL KFileItem::ACL() const 00628 { 00629 if (!d) 00630 return KACL(); 00631 00632 if ( hasExtendedACL() ) { 00633 // Extract it from the KIO::UDSEntry 00634 const QString fieldVal = d->m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ); 00635 if ( !fieldVal.isEmpty() ) 00636 return KACL( fieldVal ); 00637 } 00638 // create one from the basic permissions 00639 return KACL( d->m_permissions ); 00640 } 00641 00642 KACL KFileItem::defaultACL() const 00643 { 00644 if (!d) 00645 return KACL(); 00646 00647 // Extract it from the KIO::UDSEntry 00648 const QString fieldVal = d->m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING ); 00649 if ( !fieldVal.isEmpty() ) 00650 return KACL(fieldVal); 00651 else 00652 return KACL(); 00653 } 00654 00655 KDateTime KFileItem::time( FileTimes which ) const 00656 { 00657 if (!d) 00658 return KDateTime(); 00659 00660 return d->time(which); 00661 } 00662 00663 #ifndef KDE_NO_DEPRECATED 00664 time_t KFileItem::time( unsigned int which ) const 00665 { 00666 if (!d) 00667 return 0; 00668 00669 switch (which) { 00670 case KIO::UDSEntry::UDS_ACCESS_TIME: 00671 return d->time(AccessTime).toTime_t(); 00672 case KIO::UDSEntry::UDS_CREATION_TIME: 00673 return d->time(CreationTime).toTime_t(); 00674 case KIO::UDSEntry::UDS_MODIFICATION_TIME: 00675 default: 00676 return d->time(ModificationTime).toTime_t(); 00677 } 00678 } 00679 #endif 00680 00681 QString KFileItem::user() const 00682 { 00683 if (!d) 00684 return QString(); 00685 00686 return d->user(); 00687 } 00688 00689 QString KFileItemPrivate::user() const 00690 { 00691 QString userName = m_entry.stringValue(KIO::UDSEntry::UDS_USER); 00692 if (userName.isEmpty() && m_bIsLocalUrl) { 00693 #ifdef Q_WS_WIN 00694 QFileInfo a(m_url.toLocalFile( KUrl::RemoveTrailingSlash )); 00695 userName = a.owner(); 00696 m_entry.insert( KIO::UDSEntry::UDS_USER, userName ); 00697 #else 00698 KDE_struct_stat buff; 00699 if ( KDE::lstat( m_url.toLocalFile( KUrl::RemoveTrailingSlash ), &buff ) == 0) // get uid/gid of the link, if it's a link 00700 { 00701 struct passwd *pwuser = getpwuid( buff.st_uid ); 00702 if ( pwuser != 0 ) { 00703 userName = QString::fromLocal8Bit(pwuser->pw_name); 00704 m_entry.insert( KIO::UDSEntry::UDS_USER, userName ); 00705 } 00706 } 00707 #endif 00708 } 00709 return userName; 00710 } 00711 00712 QString KFileItem::group() const 00713 { 00714 if (!d) 00715 return QString(); 00716 00717 return d->group(); 00718 } 00719 00720 QString KFileItemPrivate::group() const 00721 { 00722 QString groupName = m_entry.stringValue( KIO::UDSEntry::UDS_GROUP ); 00723 if (groupName.isEmpty() && m_bIsLocalUrl ) 00724 { 00725 #ifdef Q_WS_WIN 00726 QFileInfo a(m_url.toLocalFile( KUrl::RemoveTrailingSlash )); 00727 groupName = a.group(); 00728 m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName ); 00729 #else 00730 KDE_struct_stat buff; 00731 if ( KDE::lstat( m_url.toLocalFile( KUrl::RemoveTrailingSlash ), &buff ) == 0) // get uid/gid of the link, if it's a link 00732 { 00733 struct group *ge = getgrgid( buff.st_gid ); 00734 if ( ge != 0 ) { 00735 groupName = QString::fromLocal8Bit(ge->gr_name); 00736 if (groupName.isEmpty()) 00737 groupName.sprintf("%d",ge->gr_gid); 00738 } 00739 else 00740 groupName.sprintf("%d",buff.st_gid); 00741 m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName ); 00742 } 00743 #endif 00744 } 00745 return groupName; 00746 } 00747 00748 bool KFileItemPrivate::isSlow() const 00749 { 00750 if (m_slow == SlowUnknown) { 00751 const QString path = localPath(); 00752 if (!path.isEmpty()) { 00753 const KFileSystemType::Type fsType = KFileSystemType::fileSystemType(path); 00754 m_slow = (fsType == KFileSystemType::Nfs || fsType == KFileSystemType::Smb) ? Slow : Fast; 00755 } else { 00756 m_slow = Slow; 00757 } 00758 } 00759 return m_slow == Slow; 00760 } 00761 00762 bool KFileItem::isSlow() const 00763 { 00764 if (!d) 00765 return false; 00766 00767 return d->isSlow(); 00768 } 00769 00770 QString KFileItem::mimetype() const 00771 { 00772 if (!d) 00773 return QString(); 00774 00775 KFileItem * that = const_cast<KFileItem *>(this); 00776 return that->determineMimeType()->name(); 00777 } 00778 00779 KMimeType::Ptr KFileItem::determineMimeType() const 00780 { 00781 if (!d) 00782 return KMimeType::Ptr(); 00783 00784 if ( !d->m_pMimeType || !d->m_bMimeTypeKnown ) 00785 { 00786 bool isLocalUrl; 00787 KUrl url = mostLocalUrl(isLocalUrl); 00788 00789 d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl ); 00790 Q_ASSERT(d->m_pMimeType); 00791 //kDebug() << d << "finding final mimetype for" << url << ":" << d->m_pMimeType->name(); 00792 d->m_bMimeTypeKnown = true; 00793 } 00794 00795 return d->m_pMimeType; 00796 } 00797 00798 bool KFileItem::isMimeTypeKnown() const 00799 { 00800 if (!d) 00801 return false; 00802 00803 // The mimetype isn't known if determineMimeType was never called (on-demand determination) 00804 // or if this fileitem has a guessed mimetype (e.g. ftp symlink) - in which case 00805 // it always remains "not fully determined" 00806 return d->m_bMimeTypeKnown && d->m_guessedMimeType.isEmpty(); 00807 } 00808 00809 QString KFileItem::mimeComment() const 00810 { 00811 if (!d) 00812 return QString(); 00813 00814 const QString displayType = d->m_entry.stringValue( KIO::UDSEntry::UDS_DISPLAY_TYPE ); 00815 if (!displayType.isEmpty()) 00816 return displayType; 00817 00818 KMimeType::Ptr mType = determineMimeType(); 00819 00820 bool isLocalUrl; 00821 KUrl url = mostLocalUrl(isLocalUrl); 00822 00823 KMimeType::Ptr mime = mimeTypePtr(); 00824 // This cannot move to kio_file (with UDS_DISPLAY_TYPE) because it needs 00825 // the mimetype to be determined, which is done here, and possibly delayed... 00826 if (isLocalUrl && !d->isSlow() && mime->is("application/x-desktop")) { 00827 KDesktopFile cfg( url.toLocalFile() ); 00828 QString comment = cfg.desktopGroup().readEntry( "Comment" ); 00829 if (!comment.isEmpty()) 00830 return comment; 00831 } 00832 00833 QString comment = d->isSlow() ? mType->comment() : mType->comment(url); 00834 //kDebug() << "finding comment for " << url.url() << " : " << d->m_pMimeType->name(); 00835 if (!comment.isEmpty()) 00836 return comment; 00837 else 00838 return mType->name(); 00839 } 00840 00841 static QString iconFromDesktopFile(const QString& path) 00842 { 00843 KDesktopFile cfg( path ); 00844 const QString icon = cfg.readIcon(); 00845 if ( cfg.hasLinkType() ) { 00846 const KConfigGroup group = cfg.desktopGroup(); 00847 const QString type = cfg.readPath(); 00848 const QString emptyIcon = group.readEntry( "EmptyIcon" ); 00849 if ( !emptyIcon.isEmpty() ) { 00850 const QString u = cfg.readUrl(); 00851 const KUrl url( u ); 00852 if ( url.protocol() == "trash" ) { 00853 // We need to find if the trash is empty, preferably without using a KIO job. 00854 // So instead kio_trash leaves an entry in its config file for us. 00855 KConfig trashConfig( "trashrc", KConfig::SimpleConfig ); 00856 if ( trashConfig.group("Status").readEntry( "Empty", true ) ) { 00857 return emptyIcon; 00858 } 00859 } 00860 } 00861 } 00862 return icon; 00863 } 00864 00865 QString KFileItem::iconName() const 00866 { 00867 if (!d) 00868 return QString(); 00869 00870 if (d->m_useIconNameCache && !d->m_iconName.isEmpty()) { 00871 return d->m_iconName; 00872 } 00873 00874 d->m_iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ); 00875 if (!d->m_iconName.isEmpty()) { 00876 d->m_useIconNameCache = d->m_bMimeTypeKnown; 00877 return d->m_iconName; 00878 } 00879 00880 bool isLocalUrl; 00881 KUrl url = mostLocalUrl(isLocalUrl); 00882 00883 KMimeType::Ptr mime; 00884 // Use guessed mimetype for the icon 00885 if (!d->m_guessedMimeType.isEmpty()) { 00886 mime = KMimeType::mimeType( d->m_guessedMimeType ); 00887 } else { 00888 mime = mimeTypePtr(); 00889 } 00890 00891 if (isLocalUrl && !isSlow() && mime->is("application/x-desktop")) { 00892 d->m_iconName = iconFromDesktopFile(url.toLocalFile()); 00893 if (!d->m_iconName.isEmpty()) { 00894 d->m_useIconNameCache = d->m_bMimeTypeKnown; 00895 return d->m_iconName; 00896 } 00897 } 00898 00899 // KDE5: handle .directory files here too, and get rid of 00900 // KFolderMimeType and the url argument in KMimeType::iconName(). 00901 00902 if (isSlow()) 00903 d->m_iconName = mime->iconName(); 00904 else 00905 d->m_iconName = mime->iconName(url); 00906 d->m_useIconNameCache = d->m_bMimeTypeKnown; 00907 //kDebug() << "finding icon for" << url << ":" << d->m_iconName; 00908 return d->m_iconName; 00909 } 00910 00915 static bool checkDesktopFile(const KFileItem& item, bool _determineMimeType) 00916 { 00917 // only local files 00918 bool isLocal; 00919 const KUrl url = item.mostLocalUrl(isLocal); 00920 if (!isLocal) 00921 return false; 00922 00923 // only regular files 00924 if (!item.isRegularFile()) 00925 return false; 00926 00927 // only if readable 00928 if (!item.isReadable()) 00929 return false; 00930 00931 // return true if desktop file 00932 KMimeType::Ptr mime = _determineMimeType ? item.determineMimeType() : item.mimeTypePtr(); 00933 return mime->is("application/x-desktop"); 00934 } 00935 00936 QStringList KFileItem::overlays() const 00937 { 00938 if (!d) 00939 return QStringList(); 00940 00941 QStringList names = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_OVERLAY_NAMES ).split(','); 00942 if ( d->m_bLink ) { 00943 names.append("emblem-symbolic-link"); 00944 } 00945 00946 if ( !S_ISDIR( d->m_fileMode ) // Locked dirs have a special icon, use the overlay for files only 00947 && !isReadable()) { 00948 names.append("object-locked"); 00949 } 00950 00951 if ( checkDesktopFile(*this, false) ) { 00952 KDesktopFile cfg( localPath() ); 00953 const KConfigGroup group = cfg.desktopGroup(); 00954 00955 // Add a warning emblem if this is an executable desktop file 00956 // which is untrusted. 00957 if ( group.hasKey( "Exec" ) && !KDesktopFile::isAuthorizedDesktopFile( localPath() ) ) { 00958 names.append( "emblem-important" ); 00959 } 00960 00961 if (cfg.hasDeviceType()) { 00962 const QString dev = cfg.readDevice(); 00963 if (!dev.isEmpty()) { 00964 KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByDevice(dev); 00965 if (mountPoint) // mounted? 00966 names.append("emblem-mounted"); 00967 } 00968 } 00969 } 00970 00971 if ( isHidden() ) { 00972 names.append("hidden"); 00973 } 00974 00975 #ifndef Q_OS_WIN 00976 if( S_ISDIR( d->m_fileMode ) && d->m_bIsLocalUrl) 00977 { 00978 if (KSambaShare::instance()->isDirectoryShared( d->m_url.toLocalFile() ) || 00979 KNFSShare::instance()->isDirectoryShared( d->m_url.toLocalFile() )) 00980 { 00981 //kDebug() << d->m_url.path(); 00982 names.append("network-workgroup"); 00983 } 00984 } 00985 #endif // Q_OS_WIN 00986 00987 if ( d->m_pMimeType && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) && 00988 d->m_pMimeType->is("application/x-gzip") ) { 00989 names.append("application-zip"); 00990 } 00991 00992 return names; 00993 } 00994 00995 QString KFileItem::comment() const 00996 { 00997 if (!d) 00998 return QString(); 00999 01000 return d->m_entry.stringValue( KIO::UDSEntry::UDS_COMMENT ); 01001 } 01002 01003 // ## where is this used? 01004 QPixmap KFileItem::pixmap( int _size, int _state ) const 01005 { 01006 if (!d) 01007 return QPixmap(); 01008 01009 const QString iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ); 01010 if ( !iconName.isEmpty() ) 01011 return DesktopIcon(iconName, _size, _state); 01012 01013 if (!d->m_pMimeType) { 01014 // No mimetype determined yet, go for a fast default icon 01015 if (S_ISDIR(d->m_fileMode)) { 01016 static const QString * defaultFolderIcon = 0; 01017 if ( !defaultFolderIcon ) { 01018 const KMimeType::Ptr mimeType = KMimeType::mimeType( "inode/directory" ); 01019 if ( mimeType ) 01020 defaultFolderIcon = &KGlobal::staticQString( mimeType->iconName() ); 01021 else 01022 kWarning(7000) << "No mimetype for inode/directory could be found. Check your installation."; 01023 } 01024 if ( defaultFolderIcon ) 01025 return DesktopIcon( *defaultFolderIcon, _size, _state ); 01026 01027 } 01028 return DesktopIcon( "unknown", _size, _state ); 01029 } 01030 01031 KMimeType::Ptr mime; 01032 // Use guessed mimetype for the icon 01033 if (!d->m_guessedMimeType.isEmpty()) 01034 mime = KMimeType::mimeType( d->m_guessedMimeType ); 01035 else 01036 mime = d->m_pMimeType; 01037 01038 // Support for gzipped files: extract mimetype of contained file 01039 // See also the relevant code in overlays, which adds the zip overlay. 01040 if ( mime->name() == "application/x-gzip" && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) ) 01041 { 01042 KUrl sf; 01043 sf.setPath( d->m_url.path().left( d->m_url.path().length() - 3 ) ); 01044 //kDebug() << "subFileName=" << subFileName; 01045 mime = KMimeType::findByUrl( sf, 0, d->m_bIsLocalUrl ); 01046 } 01047 01048 bool isLocalUrl; 01049 KUrl url = mostLocalUrl(isLocalUrl); 01050 01051 QPixmap p = KIconLoader::global()->loadMimeTypeIcon( mime->iconName( url ), KIconLoader::Desktop, _size, _state ); 01052 //kDebug() << "finding pixmap for " << url.url() << " : " << mime->name(); 01053 if (p.isNull()) 01054 kWarning() << "Pixmap not found for mimetype " << d->m_pMimeType->name(); 01055 01056 return p; 01057 } 01058 01059 bool KFileItem::isReadable() const 01060 { 01061 if (!d) 01062 return false; 01063 01064 /* 01065 struct passwd * user = getpwuid( geteuid() ); 01066 bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user); 01067 // This gets ugly for the group.... 01068 // Maybe we want a static QString for the user and a static QStringList 01069 // for the groups... then we need to handle the deletion properly... 01070 */ 01071 01072 if (d->m_permissions != KFileItem::Unknown) { 01073 // No read permission at all 01074 if ( !(S_IRUSR & d->m_permissions) && !(S_IRGRP & d->m_permissions) && !(S_IROTH & d->m_permissions) ) 01075 return false; 01076 01077 // Read permissions for all: save a stat call 01078 if ( (S_IRUSR|S_IRGRP|S_IROTH) & d->m_permissions ) 01079 return true; 01080 } 01081 01082 // Or if we can't read it [using ::access()] - not network transparent 01083 if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), R_OK ) == -1 ) 01084 return false; 01085 01086 return true; 01087 } 01088 01089 bool KFileItem::isWritable() const 01090 { 01091 if (!d) 01092 return false; 01093 01094 /* 01095 struct passwd * user = getpwuid( geteuid() ); 01096 bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user); 01097 // This gets ugly for the group.... 01098 // Maybe we want a static QString for the user and a static QStringList 01099 // for the groups... then we need to handle the deletion properly... 01100 */ 01101 01102 if (d->m_permissions != KFileItem::Unknown) { 01103 // No write permission at all 01104 if ( !(S_IWUSR & d->m_permissions) && !(S_IWGRP & d->m_permissions) && !(S_IWOTH & d->m_permissions) ) 01105 return false; 01106 } 01107 01108 // Or if we can't read it [using ::access()] - not network transparent 01109 if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), W_OK ) == -1 ) 01110 return false; 01111 01112 return true; 01113 } 01114 01115 bool KFileItem::isHidden() const 01116 { 01117 if (!d) 01118 return false; 01119 01120 // The kioslave can specify explicitly that a file is hidden or shown 01121 if ( d->m_hidden != KFileItemPrivate::Auto ) 01122 return d->m_hidden == KFileItemPrivate::Hidden; 01123 01124 // Prefer the filename that is part of the URL, in case the display name is different. 01125 QString fileName = d->m_url.fileName(); 01126 if (fileName.isEmpty()) // e.g. "trash:/" 01127 fileName = d->m_strName; 01128 return fileName.length() > 1 && fileName[0] == '.'; // Just "." is current directory, not hidden. 01129 } 01130 01131 bool KFileItem::isDir() const 01132 { 01133 if (!d) 01134 return false; 01135 01136 if (d->m_fileMode == KFileItem::Unknown) { 01137 // Probably the file was deleted already, and KDirLister hasn't told the world yet. 01138 //kDebug() << d << url() << "can't say -> false"; 01139 return false; // can't say for sure, so no 01140 } 01141 return (S_ISDIR(d->m_fileMode)); 01142 } 01143 01144 bool KFileItem::isFile() const 01145 { 01146 if (!d) 01147 return false; 01148 01149 return !isDir(); 01150 } 01151 01152 #ifndef KDE_NO_DEPRECATED 01153 bool KFileItem::acceptsDrops() const 01154 { 01155 // A directory ? 01156 if ( S_ISDIR( mode() ) ) { 01157 return isWritable(); 01158 } 01159 01160 // But only local .desktop files and executables 01161 if ( !d->m_bIsLocalUrl ) 01162 return false; 01163 01164 if ( mimetype() == "application/x-desktop") 01165 return true; 01166 01167 // Executable, shell script ... ? 01168 if ( QFileInfo(d->m_url.toLocalFile()).isExecutable() ) 01169 return true; 01170 01171 return false; 01172 } 01173 #endif 01174 01175 QString KFileItem::getStatusBarInfo() const 01176 { 01177 if (!d) 01178 return QString(); 01179 01180 QString text = d->m_strText; 01181 const QString comment = mimeComment(); 01182 01183 if ( d->m_bLink ) 01184 { 01185 text += ' '; 01186 if ( comment.isEmpty() ) 01187 text += i18n ( "(Symbolic Link to %1)", linkDest() ); 01188 else 01189 text += i18n("(%1, Link to %2)", comment, linkDest()); 01190 } 01191 else if ( targetUrl() != url() ) 01192 { 01193 text += i18n ( " (Points to %1)", targetUrl().pathOrUrl()); 01194 } 01195 else if ( S_ISREG( d->m_fileMode ) ) 01196 { 01197 text += QString(" (%1, %2)").arg( comment, KIO::convertSize( size() ) ); 01198 } 01199 else 01200 { 01201 text += QString(" (%1)").arg( comment ); 01202 } 01203 return text; 01204 } 01205 01206 #ifndef KDE_NO_DEPRECATED 01207 QString KFileItem::getToolTipText(int maxcount) const 01208 { 01209 if (!d) 01210 return QString(); 01211 01212 // we can return QString() if no tool tip should be shown 01213 QString tip; 01214 KFileMetaInfo info = metaInfo(); 01215 01216 // the font tags are a workaround for the fact that the tool tip gets 01217 // screwed if the color scheme uses white as default text color 01218 const QString colorName = QApplication::palette().color(QPalette::ToolTipText).name(); 01219 const QString start = "<tr><td align=\"right\"><nobr><font color=\"" + colorName + "\"><b>"; 01220 const QString mid = " </b></font></nobr></td><td><nobr><font color=\"" + colorName + "\">"; 01221 const char* end = "</font></nobr></td></tr>"; 01222 01223 tip = "<table cellspacing=0 cellpadding=0>"; 01224 01225 tip += start + i18n("Name:") + mid + text() + end; 01226 tip += start + i18n("Type:") + mid; 01227 01228 QString type = Qt::escape(mimeComment()); 01229 if ( d->m_bLink ) { 01230 tip += i18n("Link to %1 (%2)", linkDest(), type) + end; 01231 } else 01232 tip += type + end; 01233 01234 if ( !S_ISDIR ( d->m_fileMode ) ) 01235 tip += start + i18n("Size:") + mid + 01236 QString("%1").arg(KIO::convertSize(size())) + 01237 end; 01238 01239 tip += start + i18n("Modified:") + mid + 01240 timeString( KFileItem::ModificationTime ) + end 01241 #ifndef Q_WS_WIN //TODO: show win32-specific permissions 01242 +start + i18n("Owner:") + mid + user() + " - " + group() + end + 01243 start + i18n("Permissions:") + mid + 01244 permissionsString() + end 01245 #endif 01246 ; 01247 01248 if (info.isValid()) 01249 { 01250 const QStringList keys = info.preferredKeys(); 01251 01252 // now the rest 01253 QStringList::ConstIterator it = keys.begin(); 01254 for (int count = 0; count<maxcount && it!=keys.end() ; ++it) 01255 { 01256 if ( count == 0 ) 01257 { 01258 tip += "<tr><td colspan=2><center><s> </s></center></td></tr>"; 01259 } 01260 01261 KFileMetaInfoItem item = info.item( *it ); 01262 if ( item.isValid() ) 01263 { 01264 QString s = item.value().toString(); 01265 if ( !s.isEmpty() ) 01266 { 01267 count++; 01268 tip += start + 01269 Qt::escape( item.name() ) + ':' + 01270 mid + 01271 Qt::escape( s ) + 01272 end; 01273 } 01274 01275 } 01276 } 01277 } 01278 tip += "</table>"; 01279 01280 //kDebug() << "making this the tool tip rich text:\n"; 01281 //kDebug() << tip; 01282 01283 return tip; 01284 } 01285 #endif 01286 01287 void KFileItem::run( QWidget* parentWidget ) const 01288 { 01289 if (!d) { 01290 kWarning() << "null item"; 01291 return; 01292 } 01293 01294 (void) new KRun( targetUrl(), parentWidget, d->m_fileMode, d->m_bIsLocalUrl ); 01295 } 01296 01297 bool KFileItem::cmp( const KFileItem & item ) const 01298 { 01299 if (!d && !item.d) 01300 return true; 01301 01302 if (!d || !item.d) 01303 return false; 01304 01305 return d->cmp(*item.d); 01306 } 01307 01308 bool KFileItem::operator==(const KFileItem& other) const 01309 { 01310 // is this enough? 01311 return d == other.d; 01312 } 01313 01314 bool KFileItem::operator!=(const KFileItem& other) const 01315 { 01316 return d != other.d; 01317 } 01318 01319 #ifndef KDE_NO_DEPRECATED 01320 void KFileItem::setUDSEntry( const KIO::UDSEntry& _entry, const KUrl& _url, 01321 bool _delayedMimeTypes, bool _urlIsDirectory ) 01322 { 01323 if (!d) 01324 return; 01325 01326 d->m_entry = _entry; 01327 d->m_url = _url; 01328 d->m_strName.clear(); 01329 d->m_strText.clear(); 01330 d->m_iconName.clear(); 01331 d->m_strLowerCaseName.clear(); 01332 d->m_pMimeType = 0; 01333 d->m_fileMode = KFileItem::Unknown; 01334 d->m_permissions = KFileItem::Unknown; 01335 d->m_bMarked = false; 01336 d->m_bLink = false; 01337 d->m_bIsLocalUrl = _url.isLocalFile(); 01338 d->m_bMimeTypeKnown = false; 01339 d->m_hidden = KFileItemPrivate::Auto; 01340 d->m_guessedMimeType.clear(); 01341 d->m_metaInfo = KFileMetaInfo(); 01342 d->m_delayedMimeTypes = _delayedMimeTypes; 01343 d->m_useIconNameCache = false; 01344 01345 d->readUDSEntry( _urlIsDirectory ); 01346 d->init(); 01347 } 01348 #endif 01349 01350 KFileItem::operator QVariant() const 01351 { 01352 return qVariantFromValue(*this); 01353 } 01354 01355 #ifndef KDE_NO_DEPRECATED 01356 void KFileItem::setExtraData( const void *key, void *value ) 01357 { 01358 if (!d) 01359 return; 01360 01361 if ( !key ) 01362 return; 01363 01364 d->m_extra.insert( key, value ); // replaces the value of key if already there 01365 } 01366 #endif 01367 01368 #ifndef KDE_NO_DEPRECATED 01369 const void * KFileItem::extraData( const void *key ) const 01370 { 01371 if (!d) 01372 return 0; 01373 01374 return d->m_extra.value( key, 0 ); 01375 } 01376 #endif 01377 01378 #ifndef KDE_NO_DEPRECATED 01379 void KFileItem::removeExtraData( const void *key ) 01380 { 01381 if (!d) 01382 return; 01383 01384 d->m_extra.remove( key ); 01385 } 01386 #endif 01387 01388 QString KFileItem::permissionsString() const 01389 { 01390 if (!d) 01391 return QString(); 01392 01393 if (d->m_access.isNull() && d->m_permissions != KFileItem::Unknown) 01394 d->m_access = d->parsePermissions( d->m_permissions ); 01395 01396 return d->m_access; 01397 } 01398 01399 // check if we need to cache this 01400 QString KFileItem::timeString( FileTimes which ) const 01401 { 01402 if (!d) 01403 return QString(); 01404 01405 return KGlobal::locale()->formatDateTime( d->time(which) ); 01406 } 01407 01408 #ifndef KDE_NO_DEPRECATED 01409 QString KFileItem::timeString( unsigned int which ) const 01410 { 01411 if (!d) 01412 return QString(); 01413 01414 switch (which) { 01415 case KIO::UDSEntry::UDS_ACCESS_TIME: 01416 return timeString(AccessTime); 01417 case KIO::UDSEntry::UDS_CREATION_TIME: 01418 return timeString(CreationTime); 01419 case KIO::UDSEntry::UDS_MODIFICATION_TIME: 01420 default: 01421 return timeString(ModificationTime); 01422 } 01423 } 01424 #endif 01425 01426 void KFileItem::setMetaInfo( const KFileMetaInfo & info ) const 01427 { 01428 if (!d) 01429 return; 01430 01431 d->m_metaInfo = info; 01432 } 01433 01434 KFileMetaInfo KFileItem::metaInfo(bool autoget, int what) const 01435 { 01436 if (!d) 01437 return KFileMetaInfo(); 01438 01439 if ((isRegularFile() || isDir()) && autoget && !d->m_metaInfo.isValid()) 01440 { 01441 bool isLocalUrl; 01442 KUrl url(mostLocalUrl(isLocalUrl)); 01443 d->m_metaInfo = KFileMetaInfo(url.toLocalFile(), mimetype(), (KFileMetaInfo::What)what); 01444 } 01445 return d->m_metaInfo; 01446 } 01447 01448 #ifndef KDE_NO_DEPRECATED 01449 void KFileItem::assign( const KFileItem & item ) 01450 { 01451 *this = item; 01452 } 01453 #endif 01454 01455 KUrl KFileItem::mostLocalUrl(bool &local) const 01456 { 01457 if (!d) 01458 return KUrl(); 01459 01460 QString local_path = localPath(); 01461 01462 if ( !local_path.isEmpty() ) 01463 { 01464 local = true; 01465 KUrl url; 01466 url.setPath(local_path); 01467 return url; 01468 } 01469 else 01470 { 01471 local = d->m_bIsLocalUrl; 01472 return d->m_url; 01473 } 01474 } 01475 01476 KUrl KFileItem::mostLocalUrl() const 01477 { 01478 bool local = false; 01479 return mostLocalUrl(local); 01480 } 01481 01482 QDataStream & operator<< ( QDataStream & s, const KFileItem & a ) 01483 { 01484 if (a.d) { 01485 // We don't need to save/restore anything that refresh() invalidates, 01486 // since that means we can re-determine those by ourselves. 01487 s << a.d->m_url; 01488 s << a.d->m_strName; 01489 s << a.d->m_strText; 01490 } else { 01491 s << KUrl(); 01492 s << QString(); 01493 s << QString(); 01494 } 01495 01496 return s; 01497 } 01498 01499 QDataStream & operator>> ( QDataStream & s, KFileItem & a ) 01500 { 01501 KUrl url; 01502 QString strName, strText; 01503 01504 s >> url; 01505 s >> strName; 01506 s >> strText; 01507 01508 if (!a.d) { 01509 kWarning() << "null item"; 01510 return s; 01511 } 01512 01513 if (url.isEmpty()) { 01514 a.d = 0; 01515 return s; 01516 } 01517 01518 a.d->m_url = url; 01519 a.d->m_strName = strName; 01520 a.d->m_strText = strText; 01521 a.d->m_bIsLocalUrl = a.d->m_url.isLocalFile(); 01522 a.d->m_bMimeTypeKnown = false; 01523 a.refresh(); 01524 01525 return s; 01526 } 01527 01528 KUrl KFileItem::url() const 01529 { 01530 if (!d) 01531 return KUrl(); 01532 01533 return d->m_url; 01534 } 01535 01536 mode_t KFileItem::permissions() const 01537 { 01538 if (!d) 01539 return 0; 01540 01541 return d->m_permissions; 01542 } 01543 01544 mode_t KFileItem::mode() const 01545 { 01546 if (!d) 01547 return 0; 01548 01549 return d->m_fileMode; 01550 } 01551 01552 bool KFileItem::isLink() const 01553 { 01554 if (!d) 01555 return false; 01556 01557 return d->m_bLink; 01558 } 01559 01560 bool KFileItem::isLocalFile() const 01561 { 01562 if (!d) 01563 return false; 01564 01565 return d->m_bIsLocalUrl; 01566 } 01567 01568 QString KFileItem::text() const 01569 { 01570 if (!d) 01571 return QString(); 01572 01573 return d->m_strText; 01574 } 01575 01576 QString KFileItem::name( bool lowerCase ) const 01577 { 01578 if (!d) 01579 return QString(); 01580 01581 if ( !lowerCase ) 01582 return d->m_strName; 01583 else 01584 if ( d->m_strLowerCaseName.isNull() ) 01585 d->m_strLowerCaseName = d->m_strName.toLower(); 01586 return d->m_strLowerCaseName; 01587 } 01588 01589 KUrl KFileItem::targetUrl() const 01590 { 01591 if (!d) 01592 return KUrl(); 01593 01594 const QString targetUrlStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_TARGET_URL ); 01595 if (!targetUrlStr.isEmpty()) 01596 return KUrl(targetUrlStr); 01597 else 01598 return url(); 01599 } 01600 01601 KUrl KFileItem::nepomukUri() const 01602 { 01603 #ifndef KIO_NO_NEPOMUK 01604 if (!d) 01605 return KUrl(); 01606 01607 const QString nepomukUriStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_NEPOMUK_URI ); 01608 if(!nepomukUriStr.isEmpty()) { 01609 return KUrl(nepomukUriStr); 01610 } 01611 else if(targetUrl().isLocalFile()) { 01612 return targetUrl(); 01613 } 01614 else { 01615 return KUrl(); 01616 } 01617 #else 01618 return KUrl(); 01619 #endif 01620 } 01621 01622 /* 01623 * Mimetype handling. 01624 * 01625 * Initial state: m_pMimeType = 0. 01626 * When mimeTypePtr() is called first: fast mimetype determination, 01627 * might either find an accurate mimetype (-> Final state), otherwise we 01628 * set m_pMimeType but not m_bMimeTypeKnown (-> Intermediate state) 01629 * Intermediate state: determineMimeType() does the real determination -> Final state. 01630 * 01631 * If delayedMimeTypes isn't set, then we always go to the Final state directly. 01632 */ 01633 01634 KMimeType::Ptr KFileItem::mimeTypePtr() const 01635 { 01636 if (!d) 01637 return KMimeType::Ptr(); 01638 01639 if (!d->m_pMimeType) { 01640 // On-demand fast (but not always accurate) mimetype determination 01641 Q_ASSERT(!d->m_url.isEmpty()); 01642 bool isLocalUrl; 01643 KUrl url = mostLocalUrl(isLocalUrl); 01644 int accuracy; 01645 d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl, 01646 // use fast mode if delayed mimetype determination can refine it later 01647 d->m_delayedMimeTypes, &accuracy ); 01648 // If we used the "fast mode" (no sniffing), and we didn't get a perfect (extension-based) match, 01649 // then determineMimeType will be able to do better. 01650 const bool canDoBetter = d->m_delayedMimeTypes && accuracy < 100; 01651 //kDebug() << "finding mimetype for" << url << ":" << d->m_pMimeType->name() << "canDoBetter=" << canDoBetter; 01652 d->m_bMimeTypeKnown = !canDoBetter; 01653 } 01654 return d->m_pMimeType; 01655 } 01656 01657 KIO::UDSEntry KFileItem::entry() const 01658 { 01659 if (!d) 01660 return KIO::UDSEntry(); 01661 01662 return d->m_entry; 01663 } 01664 01665 bool KFileItem::isMarked() const 01666 { 01667 if (!d) 01668 return false; 01669 01670 return d->m_bMarked; 01671 } 01672 01673 void KFileItem::mark() 01674 { 01675 if (!d) { 01676 kWarning() << "null item"; 01677 return; 01678 } 01679 01680 d->m_bMarked = true; 01681 } 01682 01683 void KFileItem::unmark() 01684 { 01685 if (!d) { 01686 kWarning() << "null item"; 01687 return; 01688 } 01689 01690 d->m_bMarked = false; 01691 } 01692 01693 KFileItem& KFileItem::operator=(const KFileItem& other) 01694 { 01695 d = other.d; 01696 return *this; 01697 } 01698 01699 bool KFileItem::isNull() const 01700 { 01701 return d == 0; 01702 } 01703 01704 KFileItemList::KFileItemList() 01705 { 01706 } 01707 01708 KFileItemList::KFileItemList( const QList<KFileItem> &items ) 01709 : QList<KFileItem>( items ) 01710 { 01711 } 01712 01713 KFileItem KFileItemList::findByName( const QString& fileName ) const 01714 { 01715 const_iterator it = begin(); 01716 const const_iterator itend = end(); 01717 for ( ; it != itend ; ++it ) { 01718 if ( (*it).name() == fileName ) { 01719 return *it; 01720 } 01721 } 01722 return KFileItem(); 01723 } 01724 01725 KFileItem KFileItemList::findByUrl( const KUrl& url ) const { 01726 const_iterator it = begin(); 01727 const const_iterator itend = end(); 01728 for ( ; it != itend ; ++it ) { 01729 if ( (*it).url() == url ) { 01730 return *it; 01731 } 01732 } 01733 return KFileItem(); 01734 } 01735 01736 KUrl::List KFileItemList::urlList() const { 01737 KUrl::List lst; 01738 const_iterator it = begin(); 01739 const const_iterator itend = end(); 01740 for ( ; it != itend ; ++it ) { 01741 lst.append( (*it).url() ); 01742 } 01743 return lst; 01744 } 01745 01746 KUrl::List KFileItemList::targetUrlList() const { 01747 KUrl::List lst; 01748 const_iterator it = begin(); 01749 const const_iterator itend = end(); 01750 for ( ; it != itend ; ++it ) { 01751 lst.append( (*it).targetUrl() ); 01752 } 01753 return lst; 01754 } 01755 01756 01757 bool KFileItem::isDesktopFile() const 01758 { 01759 return checkDesktopFile(*this, true); 01760 } 01761 01762 bool KFileItem::isRegularFile() const 01763 { 01764 if (!d) 01765 return false; 01766 01767 return S_ISREG(d->m_fileMode); 01768 } 01769 01770 QDebug operator<<(QDebug stream, const KFileItem& item) 01771 { 01772 if (item.isNull()) { 01773 stream << "[null KFileItem]"; 01774 } else { 01775 stream << "[KFileItem for" << item.url() << "]"; 01776 } 01777 return stream; 01778 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Jan 21 2019 12:34:59 by doxygen 1.7.5.1 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Jan 21 2019 12:34:59 by doxygen 1.7.5.1 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.