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 d->m_fileMode = KFileItem::Unknown; 00515 d->m_permissions = KFileItem::Unknown; 00516 d->m_metaInfo = KFileMetaInfo(); 00517 d->m_hidden = KFileItemPrivate::Auto; 00518 refreshMimeType(); 00519 00520 // Basically, we can't trust any information we got while listing. 00521 // Everything could have changed... 00522 // Clearing m_entry makes it possible to detect changes in the size of the file, 00523 // the time information, etc. 00524 d->m_entry.clear(); 00525 d->init(); 00526 } 00527 00528 void KFileItem::refreshMimeType() 00529 { 00530 d->m_pMimeType = 0; 00531 d->m_bMimeTypeKnown = false; 00532 d->m_iconName.clear(); 00533 } 00534 00535 void KFileItem::setUrl( const KUrl &url ) 00536 { 00537 d->m_url = url; 00538 setName( url.fileName() ); 00539 } 00540 00541 void KFileItem::setName( const QString& name ) 00542 { 00543 d->m_strName = name; 00544 d->m_strText = KIO::decodeFileName( d->m_strName ); 00545 if (d->m_entry.contains(KIO::UDSEntry::UDS_NAME)) 00546 d->m_entry.insert(KIO::UDSEntry::UDS_NAME, d->m_strName); // #195385 00547 00548 } 00549 00550 QString KFileItem::linkDest() const 00551 { 00552 // Extract it from the KIO::UDSEntry 00553 const QString linkStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_LINK_DEST ); 00554 if ( !linkStr.isEmpty() ) 00555 return linkStr; 00556 00557 // If not in the KIO::UDSEntry, or if UDSEntry empty, use readlink() [if local URL] 00558 if ( d->m_bIsLocalUrl ) 00559 { 00560 char buf[1000]; 00561 int n = readlink( QFile::encodeName(d->m_url.toLocalFile( KUrl::RemoveTrailingSlash )), buf, sizeof(buf)-1 ); 00562 if ( n != -1 ) 00563 { 00564 buf[ n ] = 0; 00565 return QFile::decodeName( buf ); 00566 } 00567 } 00568 return QString(); 00569 } 00570 00571 QString KFileItemPrivate::localPath() const 00572 { 00573 if (m_bIsLocalUrl) { 00574 return m_url.toLocalFile(); 00575 } 00576 00577 // Extract the local path from the KIO::UDSEntry 00578 return m_entry.stringValue( KIO::UDSEntry::UDS_LOCAL_PATH ); 00579 } 00580 00581 QString KFileItem::localPath() const 00582 { 00583 return d->localPath(); 00584 } 00585 00586 KIO::filesize_t KFileItem::size() const 00587 { 00588 return d->size(); 00589 } 00590 00591 bool KFileItem::hasExtendedACL() const 00592 { 00593 // Check if the field exists; its value doesn't matter 00594 return d->m_entry.contains(KIO::UDSEntry::UDS_EXTENDED_ACL); 00595 } 00596 00597 KACL KFileItem::ACL() const 00598 { 00599 if ( hasExtendedACL() ) { 00600 // Extract it from the KIO::UDSEntry 00601 const QString fieldVal = d->m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ); 00602 if ( !fieldVal.isEmpty() ) 00603 return KACL( fieldVal ); 00604 } 00605 // create one from the basic permissions 00606 return KACL( d->m_permissions ); 00607 } 00608 00609 KACL KFileItem::defaultACL() const 00610 { 00611 // Extract it from the KIO::UDSEntry 00612 const QString fieldVal = d->m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING ); 00613 if ( !fieldVal.isEmpty() ) 00614 return KACL(fieldVal); 00615 else 00616 return KACL(); 00617 } 00618 00619 KDateTime KFileItem::time( FileTimes which ) const 00620 { 00621 return d->time(which); 00622 } 00623 00624 #ifndef KDE_NO_DEPRECATED 00625 time_t KFileItem::time( unsigned int which ) const 00626 { 00627 switch (which) { 00628 case KIO::UDSEntry::UDS_ACCESS_TIME: 00629 return d->time(AccessTime).toTime_t(); 00630 case KIO::UDSEntry::UDS_CREATION_TIME: 00631 return d->time(CreationTime).toTime_t(); 00632 case KIO::UDSEntry::UDS_MODIFICATION_TIME: 00633 default: 00634 return d->time(ModificationTime).toTime_t(); 00635 } 00636 } 00637 #endif 00638 00639 QString KFileItem::user() const 00640 { 00641 return d->user(); 00642 } 00643 00644 QString KFileItemPrivate::user() const 00645 { 00646 QString userName = m_entry.stringValue(KIO::UDSEntry::UDS_USER); 00647 if (userName.isEmpty() && m_bIsLocalUrl) { 00648 #ifdef Q_WS_WIN 00649 QFileInfo a(m_url.toLocalFile( KUrl::RemoveTrailingSlash )); 00650 userName = a.owner(); 00651 m_entry.insert( KIO::UDSEntry::UDS_USER, userName ); 00652 #else 00653 KDE_struct_stat buff; 00654 if ( KDE::lstat( m_url.toLocalFile( KUrl::RemoveTrailingSlash ), &buff ) == 0) // get uid/gid of the link, if it's a link 00655 { 00656 struct passwd *pwuser = getpwuid( buff.st_uid ); 00657 if ( pwuser != 0 ) { 00658 userName = QString::fromLocal8Bit(pwuser->pw_name); 00659 m_entry.insert( KIO::UDSEntry::UDS_USER, userName ); 00660 } 00661 } 00662 #endif 00663 } 00664 return userName; 00665 } 00666 00667 QString KFileItem::group() const 00668 { 00669 return d->group(); 00670 } 00671 00672 QString KFileItemPrivate::group() const 00673 { 00674 QString groupName = m_entry.stringValue( KIO::UDSEntry::UDS_GROUP ); 00675 if (groupName.isEmpty() && m_bIsLocalUrl ) 00676 { 00677 #ifdef Q_WS_WIN 00678 QFileInfo a(m_url.toLocalFile( KUrl::RemoveTrailingSlash )); 00679 groupName = a.group(); 00680 m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName ); 00681 #else 00682 KDE_struct_stat buff; 00683 if ( KDE::lstat( m_url.toLocalFile( KUrl::RemoveTrailingSlash ), &buff ) == 0) // get uid/gid of the link, if it's a link 00684 { 00685 struct group *ge = getgrgid( buff.st_gid ); 00686 if ( ge != 0 ) { 00687 groupName = QString::fromLocal8Bit(ge->gr_name); 00688 if (groupName.isEmpty()) 00689 groupName.sprintf("%d",ge->gr_gid); 00690 } 00691 else 00692 groupName.sprintf("%d",buff.st_gid); 00693 m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName ); 00694 } 00695 #endif 00696 } 00697 return groupName; 00698 } 00699 00700 bool KFileItemPrivate::isSlow() const 00701 { 00702 if (m_slow == SlowUnknown) { 00703 const QString path = localPath(); 00704 if (!path.isEmpty()) { 00705 const KFileSystemType::Type fsType = KFileSystemType::fileSystemType(path); 00706 m_slow = (fsType == KFileSystemType::Nfs || fsType == KFileSystemType::Smb) ? Slow : Fast; 00707 } else { 00708 m_slow = Slow; 00709 } 00710 } 00711 return m_slow == Slow; 00712 } 00713 00714 bool KFileItem::isSlow() const 00715 { 00716 return d->isSlow(); 00717 } 00718 00719 QString KFileItem::mimetype() const 00720 { 00721 KFileItem * that = const_cast<KFileItem *>(this); 00722 return that->determineMimeType()->name(); 00723 } 00724 00725 KMimeType::Ptr KFileItem::determineMimeType() const 00726 { 00727 if ( !d->m_pMimeType || !d->m_bMimeTypeKnown ) 00728 { 00729 bool isLocalUrl; 00730 KUrl url = mostLocalUrl(isLocalUrl); 00731 00732 d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl ); 00733 Q_ASSERT(d->m_pMimeType); 00734 //kDebug() << d << "finding final mimetype for" << url << ":" << d->m_pMimeType->name(); 00735 d->m_bMimeTypeKnown = true; 00736 } 00737 00738 return d->m_pMimeType; 00739 } 00740 00741 bool KFileItem::isMimeTypeKnown() const 00742 { 00743 // The mimetype isn't known if determineMimeType was never called (on-demand determination) 00744 // or if this fileitem has a guessed mimetype (e.g. ftp symlink) - in which case 00745 // it always remains "not fully determined" 00746 return d->m_bMimeTypeKnown && d->m_guessedMimeType.isEmpty(); 00747 } 00748 00749 QString KFileItem::mimeComment() const 00750 { 00751 const QString displayType = d->m_entry.stringValue( KIO::UDSEntry::UDS_DISPLAY_TYPE ); 00752 if (!displayType.isEmpty()) 00753 return displayType; 00754 00755 KMimeType::Ptr mType = determineMimeType(); 00756 00757 bool isLocalUrl; 00758 KUrl url = mostLocalUrl(isLocalUrl); 00759 00760 KMimeType::Ptr mime = mimeTypePtr(); 00761 // This cannot move to kio_file (with UDS_DISPLAY_TYPE) because it needs 00762 // the mimetype to be determined, which is done here, and possibly delayed... 00763 if (isLocalUrl && !d->isSlow() && mime->is("application/x-desktop")) { 00764 KDesktopFile cfg( url.toLocalFile() ); 00765 QString comment = cfg.desktopGroup().readEntry( "Comment" ); 00766 if (!comment.isEmpty()) 00767 return comment; 00768 } 00769 00770 QString comment = d->isSlow() ? mType->comment() : mType->comment(url); 00771 //kDebug() << "finding comment for " << url.url() << " : " << d->m_pMimeType->name(); 00772 if (!comment.isEmpty()) 00773 return comment; 00774 else 00775 return mType->name(); 00776 } 00777 00778 static QString iconFromDesktopFile(const QString& path) 00779 { 00780 KDesktopFile cfg( path ); 00781 const QString icon = cfg.readIcon(); 00782 if ( cfg.hasLinkType() ) { 00783 const KConfigGroup group = cfg.desktopGroup(); 00784 const QString type = cfg.readPath(); 00785 const QString emptyIcon = group.readEntry( "EmptyIcon" ); 00786 if ( !emptyIcon.isEmpty() ) { 00787 const QString u = cfg.readUrl(); 00788 const KUrl url( u ); 00789 if ( url.protocol() == "trash" ) { 00790 // We need to find if the trash is empty, preferably without using a KIO job. 00791 // So instead kio_trash leaves an entry in its config file for us. 00792 KConfig trashConfig( "trashrc", KConfig::SimpleConfig ); 00793 if ( trashConfig.group("Status").readEntry( "Empty", true ) ) { 00794 return emptyIcon; 00795 } 00796 } 00797 } 00798 } 00799 return icon; 00800 } 00801 00802 QString KFileItem::iconName() const 00803 { 00804 if (d->m_useIconNameCache && !d->m_iconName.isEmpty()) { 00805 return d->m_iconName; 00806 } 00807 00808 d->m_iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ); 00809 if (!d->m_iconName.isEmpty()) { 00810 d->m_useIconNameCache = d->m_bMimeTypeKnown; 00811 return d->m_iconName; 00812 } 00813 00814 bool isLocalUrl; 00815 KUrl url = mostLocalUrl(isLocalUrl); 00816 00817 KMimeType::Ptr mime; 00818 // Use guessed mimetype for the icon 00819 if (!d->m_guessedMimeType.isEmpty()) { 00820 mime = KMimeType::mimeType( d->m_guessedMimeType ); 00821 } else { 00822 mime = mimeTypePtr(); 00823 } 00824 00825 if (isLocalUrl && !isSlow() && mime->is("application/x-desktop")) { 00826 d->m_iconName = iconFromDesktopFile(url.toLocalFile()); 00827 if (!d->m_iconName.isEmpty()) { 00828 d->m_useIconNameCache = d->m_bMimeTypeKnown; 00829 return d->m_iconName; 00830 } 00831 } 00832 00833 // KDE5: handle .directory files here too, and get rid of 00834 // KFolderMimeType and the url argument in KMimeType::iconName(). 00835 00836 if (isSlow()) 00837 d->m_iconName = mime->iconName(); 00838 else 00839 d->m_iconName = mime->iconName(url); 00840 d->m_useIconNameCache = d->m_bMimeTypeKnown; 00841 //kDebug() << "finding icon for" << url << ":" << d->m_iconName; 00842 return d->m_iconName; 00843 } 00844 00849 static bool checkDesktopFile(const KFileItem& item, bool _determineMimeType) 00850 { 00851 // only local files 00852 bool isLocal; 00853 const KUrl url = item.mostLocalUrl(isLocal); 00854 if (!isLocal) 00855 return false; 00856 00857 // only regular files 00858 if (!item.isRegularFile()) 00859 return false; 00860 00861 // only if readable 00862 if (!item.isReadable()) 00863 return false; 00864 00865 // return true if desktop file 00866 KMimeType::Ptr mime = _determineMimeType ? item.determineMimeType() : item.mimeTypePtr(); 00867 return mime->is("application/x-desktop"); 00868 } 00869 00870 QStringList KFileItem::overlays() const 00871 { 00872 QStringList names = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_OVERLAY_NAMES ).split(','); 00873 if ( d->m_bLink ) { 00874 names.append("emblem-symbolic-link"); 00875 } 00876 00877 if ( !S_ISDIR( d->m_fileMode ) // Locked dirs have a special icon, use the overlay for files only 00878 && !isReadable()) { 00879 names.append("object-locked"); 00880 } 00881 00882 if ( checkDesktopFile(*this, false) ) { 00883 KDesktopFile cfg( localPath() ); 00884 const KConfigGroup group = cfg.desktopGroup(); 00885 00886 // Add a warning emblem if this is an executable desktop file 00887 // which is untrusted. 00888 if ( group.hasKey( "Exec" ) && !KDesktopFile::isAuthorizedDesktopFile( localPath() ) ) { 00889 names.append( "emblem-important" ); 00890 } 00891 00892 if (cfg.hasDeviceType()) { 00893 const QString dev = cfg.readDevice(); 00894 if (!dev.isEmpty()) { 00895 KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByDevice(dev); 00896 if (mountPoint) // mounted? 00897 names.append("emblem-mounted"); 00898 } 00899 } 00900 } 00901 00902 if ( isHidden() ) { 00903 names.append("hidden"); 00904 } 00905 00906 #ifndef Q_OS_WIN 00907 if( S_ISDIR( d->m_fileMode ) && d->m_bIsLocalUrl) 00908 { 00909 if (KSambaShare::instance()->isDirectoryShared( d->m_url.toLocalFile() ) || 00910 KNFSShare::instance()->isDirectoryShared( d->m_url.toLocalFile() )) 00911 { 00912 //kDebug() << d->m_url.path(); 00913 names.append("network-workgroup"); 00914 } 00915 } 00916 #endif // Q_OS_WIN 00917 00918 if ( d->m_pMimeType && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) && 00919 d->m_pMimeType->is("application/x-gzip") ) { 00920 names.append("application-zip"); 00921 } 00922 00923 return names; 00924 } 00925 00926 QString KFileItem::comment() const 00927 { 00928 return d->m_entry.stringValue( KIO::UDSEntry::UDS_COMMENT ); 00929 } 00930 00931 // ## where is this used? 00932 QPixmap KFileItem::pixmap( int _size, int _state ) const 00933 { 00934 const QString iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ); 00935 if ( !iconName.isEmpty() ) 00936 return DesktopIcon(iconName, _size, _state); 00937 00938 if (!d->m_pMimeType) { 00939 // No mimetype determined yet, go for a fast default icon 00940 if (S_ISDIR(d->m_fileMode)) { 00941 static const QString * defaultFolderIcon = 0; 00942 if ( !defaultFolderIcon ) { 00943 const KMimeType::Ptr mimeType = KMimeType::mimeType( "inode/directory" ); 00944 if ( mimeType ) 00945 defaultFolderIcon = &KGlobal::staticQString( mimeType->iconName() ); 00946 else 00947 kWarning(7000) << "No mimetype for inode/directory could be found. Check your installation."; 00948 } 00949 if ( defaultFolderIcon ) 00950 return DesktopIcon( *defaultFolderIcon, _size, _state ); 00951 00952 } 00953 return DesktopIcon( "unknown", _size, _state ); 00954 } 00955 00956 KMimeType::Ptr mime; 00957 // Use guessed mimetype for the icon 00958 if (!d->m_guessedMimeType.isEmpty()) 00959 mime = KMimeType::mimeType( d->m_guessedMimeType ); 00960 else 00961 mime = d->m_pMimeType; 00962 00963 // Support for gzipped files: extract mimetype of contained file 00964 // See also the relevant code in overlays, which adds the zip overlay. 00965 if ( mime->name() == "application/x-gzip" && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) ) 00966 { 00967 KUrl sf; 00968 sf.setPath( d->m_url.path().left( d->m_url.path().length() - 3 ) ); 00969 //kDebug() << "subFileName=" << subFileName; 00970 mime = KMimeType::findByUrl( sf, 0, d->m_bIsLocalUrl ); 00971 } 00972 00973 bool isLocalUrl; 00974 KUrl url = mostLocalUrl(isLocalUrl); 00975 00976 QPixmap p = KIconLoader::global()->loadMimeTypeIcon( mime->iconName( url ), KIconLoader::Desktop, _size, _state ); 00977 //kDebug() << "finding pixmap for " << url.url() << " : " << mime->name(); 00978 if (p.isNull()) 00979 kWarning() << "Pixmap not found for mimetype " << d->m_pMimeType->name(); 00980 00981 return p; 00982 } 00983 00984 bool KFileItem::isReadable() const 00985 { 00986 /* 00987 struct passwd * user = getpwuid( geteuid() ); 00988 bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user); 00989 // This gets ugly for the group.... 00990 // Maybe we want a static QString for the user and a static QStringList 00991 // for the groups... then we need to handle the deletion properly... 00992 */ 00993 00994 if (d->m_permissions != KFileItem::Unknown) { 00995 // No read permission at all 00996 if ( !(S_IRUSR & d->m_permissions) && !(S_IRGRP & d->m_permissions) && !(S_IROTH & d->m_permissions) ) 00997 return false; 00998 00999 // Read permissions for all: save a stat call 01000 if ( (S_IRUSR|S_IRGRP|S_IROTH) & d->m_permissions ) 01001 return true; 01002 } 01003 01004 // Or if we can't read it [using ::access()] - not network transparent 01005 if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), R_OK ) == -1 ) 01006 return false; 01007 01008 return true; 01009 } 01010 01011 bool KFileItem::isWritable() const 01012 { 01013 /* 01014 struct passwd * user = getpwuid( geteuid() ); 01015 bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user); 01016 // This gets ugly for the group.... 01017 // Maybe we want a static QString for the user and a static QStringList 01018 // for the groups... then we need to handle the deletion properly... 01019 */ 01020 01021 if (d->m_permissions != KFileItem::Unknown) { 01022 // No write permission at all 01023 if ( !(S_IWUSR & d->m_permissions) && !(S_IWGRP & d->m_permissions) && !(S_IWOTH & d->m_permissions) ) 01024 return false; 01025 } 01026 01027 // Or if we can't read it [using ::access()] - not network transparent 01028 if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), W_OK ) == -1 ) 01029 return false; 01030 01031 return true; 01032 } 01033 01034 bool KFileItem::isHidden() const 01035 { 01036 // The kioslave can specify explicitly that a file is hidden or shown 01037 if ( d->m_hidden != KFileItemPrivate::Auto ) 01038 return d->m_hidden == KFileItemPrivate::Hidden; 01039 01040 // Prefer the filename that is part of the URL, in case the display name is different. 01041 QString fileName = d->m_url.fileName(); 01042 if (fileName.isEmpty()) // e.g. "trash:/" 01043 fileName = d->m_strName; 01044 return fileName.length() > 1 && fileName[0] == '.'; // Just "." is current directory, not hidden. 01045 } 01046 01047 bool KFileItem::isDir() const 01048 { 01049 if (d->m_fileMode == KFileItem::Unknown) { 01050 // Probably the file was deleted already, and KDirLister hasn't told the world yet. 01051 //kDebug() << d << url() << "can't say -> false"; 01052 return false; // can't say for sure, so no 01053 } 01054 return (S_ISDIR(d->m_fileMode)); 01055 } 01056 01057 bool KFileItem::isFile() const 01058 { 01059 return !isDir(); 01060 } 01061 01062 #ifndef KDE_NO_DEPRECATED 01063 bool KFileItem::acceptsDrops() const 01064 { 01065 // A directory ? 01066 if ( S_ISDIR( mode() ) ) { 01067 return isWritable(); 01068 } 01069 01070 // But only local .desktop files and executables 01071 if ( !d->m_bIsLocalUrl ) 01072 return false; 01073 01074 if ( mimetype() == "application/x-desktop") 01075 return true; 01076 01077 // Executable, shell script ... ? 01078 if ( QFileInfo(d->m_url.toLocalFile()).isExecutable() ) 01079 return true; 01080 01081 return false; 01082 } 01083 #endif 01084 01085 QString KFileItem::getStatusBarInfo() const 01086 { 01087 QString text = d->m_strText; 01088 const QString comment = mimeComment(); 01089 01090 if ( d->m_bLink ) 01091 { 01092 text += ' '; 01093 if ( comment.isEmpty() ) 01094 text += i18n ( "(Symbolic Link to %1)", linkDest() ); 01095 else 01096 text += i18n("(%1, Link to %2)", comment, linkDest()); 01097 } 01098 else if ( targetUrl() != url() ) 01099 { 01100 text += i18n ( " (Points to %1)", targetUrl().pathOrUrl()); 01101 } 01102 else if ( S_ISREG( d->m_fileMode ) ) 01103 { 01104 text += QString(" (%1, %2)").arg( comment, KIO::convertSize( size() ) ); 01105 } 01106 else 01107 { 01108 text += QString(" (%1)").arg( comment ); 01109 } 01110 return text; 01111 } 01112 01113 #ifndef KDE_NO_DEPRECATED 01114 QString KFileItem::getToolTipText(int maxcount) const 01115 { 01116 // we can return QString() if no tool tip should be shown 01117 QString tip; 01118 KFileMetaInfo info = metaInfo(); 01119 01120 // the font tags are a workaround for the fact that the tool tip gets 01121 // screwed if the color scheme uses white as default text color 01122 const QString colorName = QApplication::palette().color(QPalette::ToolTipText).name(); 01123 const QString start = "<tr><td align=\"right\"><nobr><font color=\"" + colorName + "\"><b>"; 01124 const QString mid = " </b></font></nobr></td><td><nobr><font color=\"" + colorName + "\">"; 01125 const char* end = "</font></nobr></td></tr>"; 01126 01127 tip = "<table cellspacing=0 cellpadding=0>"; 01128 01129 tip += start + i18n("Name:") + mid + text() + end; 01130 tip += start + i18n("Type:") + mid; 01131 01132 QString type = Qt::escape(mimeComment()); 01133 if ( d->m_bLink ) { 01134 tip += i18n("Link to %1 (%2)", linkDest(), type) + end; 01135 } else 01136 tip += type + end; 01137 01138 if ( !S_ISDIR ( d->m_fileMode ) ) 01139 tip += start + i18n("Size:") + mid + 01140 QString("%1").arg(KIO::convertSize(size())) + 01141 end; 01142 01143 tip += start + i18n("Modified:") + mid + 01144 timeString( KFileItem::ModificationTime ) + end 01145 #ifndef Q_WS_WIN //TODO: show win32-specific permissions 01146 +start + i18n("Owner:") + mid + user() + " - " + group() + end + 01147 start + i18n("Permissions:") + mid + 01148 permissionsString() + end 01149 #endif 01150 ; 01151 01152 if (info.isValid()) 01153 { 01154 const QStringList keys = info.preferredKeys(); 01155 01156 // now the rest 01157 QStringList::ConstIterator it = keys.begin(); 01158 for (int count = 0; count<maxcount && it!=keys.end() ; ++it) 01159 { 01160 if ( count == 0 ) 01161 { 01162 tip += "<tr><td colspan=2><center><s> </s></center></td></tr>"; 01163 } 01164 01165 KFileMetaInfoItem item = info.item( *it ); 01166 if ( item.isValid() ) 01167 { 01168 QString s = item.value().toString(); 01169 if ( !s.isEmpty() ) 01170 { 01171 count++; 01172 tip += start + 01173 Qt::escape( item.name() ) + ':' + 01174 mid + 01175 Qt::escape( s ) + 01176 end; 01177 } 01178 01179 } 01180 } 01181 } 01182 tip += "</table>"; 01183 01184 //kDebug() << "making this the tool tip rich text:\n"; 01185 //kDebug() << tip; 01186 01187 return tip; 01188 } 01189 #endif 01190 01191 void KFileItem::run( QWidget* parentWidget ) const 01192 { 01193 (void) new KRun( targetUrl(), parentWidget, d->m_fileMode, d->m_bIsLocalUrl ); 01194 } 01195 01196 bool KFileItem::cmp( const KFileItem & item ) const 01197 { 01198 return d->cmp(*item.d); 01199 } 01200 01201 bool KFileItem::operator==(const KFileItem& other) const 01202 { 01203 // is this enough? 01204 return d == other.d; 01205 } 01206 01207 bool KFileItem::operator!=(const KFileItem& other) const 01208 { 01209 return d != other.d; 01210 } 01211 01212 #ifndef KDE_NO_DEPRECATED 01213 void KFileItem::setUDSEntry( const KIO::UDSEntry& _entry, const KUrl& _url, 01214 bool _delayedMimeTypes, bool _urlIsDirectory ) 01215 { 01216 d->m_entry = _entry; 01217 d->m_url = _url; 01218 d->m_strName.clear(); 01219 d->m_strText.clear(); 01220 d->m_iconName.clear(); 01221 d->m_strLowerCaseName.clear(); 01222 d->m_pMimeType = 0; 01223 d->m_fileMode = KFileItem::Unknown; 01224 d->m_permissions = KFileItem::Unknown; 01225 d->m_bMarked = false; 01226 d->m_bLink = false; 01227 d->m_bIsLocalUrl = _url.isLocalFile(); 01228 d->m_bMimeTypeKnown = false; 01229 d->m_hidden = KFileItemPrivate::Auto; 01230 d->m_guessedMimeType.clear(); 01231 d->m_metaInfo = KFileMetaInfo(); 01232 d->m_delayedMimeTypes = _delayedMimeTypes; 01233 d->m_useIconNameCache = false; 01234 01235 d->readUDSEntry( _urlIsDirectory ); 01236 d->init(); 01237 } 01238 #endif 01239 01240 KFileItem::operator QVariant() const 01241 { 01242 return qVariantFromValue(*this); 01243 } 01244 01245 #ifndef KDE_NO_DEPRECATED 01246 void KFileItem::setExtraData( const void *key, void *value ) 01247 { 01248 if ( !key ) 01249 return; 01250 01251 d->m_extra.insert( key, value ); // replaces the value of key if already there 01252 } 01253 #endif 01254 01255 #ifndef KDE_NO_DEPRECATED 01256 const void * KFileItem::extraData( const void *key ) const 01257 { 01258 return d->m_extra.value( key, 0 ); 01259 } 01260 #endif 01261 01262 #ifndef KDE_NO_DEPRECATED 01263 void KFileItem::removeExtraData( const void *key ) 01264 { 01265 d->m_extra.remove( key ); 01266 } 01267 #endif 01268 01269 QString KFileItem::permissionsString() const 01270 { 01271 if (d->m_access.isNull() && d->m_permissions != KFileItem::Unknown) 01272 d->m_access = d->parsePermissions( d->m_permissions ); 01273 01274 return d->m_access; 01275 } 01276 01277 // check if we need to cache this 01278 QString KFileItem::timeString( FileTimes which ) const 01279 { 01280 return KGlobal::locale()->formatDateTime( d->time(which) ); 01281 } 01282 01283 #ifndef KDE_NO_DEPRECATED 01284 QString KFileItem::timeString( unsigned int which ) const 01285 { 01286 switch (which) { 01287 case KIO::UDSEntry::UDS_ACCESS_TIME: 01288 return timeString(AccessTime); 01289 case KIO::UDSEntry::UDS_CREATION_TIME: 01290 return timeString(CreationTime); 01291 case KIO::UDSEntry::UDS_MODIFICATION_TIME: 01292 default: 01293 return timeString(ModificationTime); 01294 } 01295 } 01296 #endif 01297 01298 void KFileItem::setMetaInfo( const KFileMetaInfo & info ) const 01299 { 01300 d->m_metaInfo = info; 01301 } 01302 01303 KFileMetaInfo KFileItem::metaInfo(bool autoget, int what) const 01304 { 01305 if ((isRegularFile() || isDir()) && autoget && !d->m_metaInfo.isValid()) 01306 { 01307 bool isLocalUrl; 01308 KUrl url(mostLocalUrl(isLocalUrl)); 01309 d->m_metaInfo = KFileMetaInfo(url.toLocalFile(), mimetype(), (KFileMetaInfo::What)what); 01310 } 01311 return d->m_metaInfo; 01312 } 01313 01314 #ifndef KDE_NO_DEPRECATED 01315 void KFileItem::assign( const KFileItem & item ) 01316 { 01317 *this = item; 01318 } 01319 #endif 01320 01321 KUrl KFileItem::mostLocalUrl(bool &local) const 01322 { 01323 QString local_path = localPath(); 01324 01325 if ( !local_path.isEmpty() ) 01326 { 01327 local = true; 01328 KUrl url; 01329 url.setPath(local_path); 01330 return url; 01331 } 01332 else 01333 { 01334 local = d->m_bIsLocalUrl; 01335 return d->m_url; 01336 } 01337 } 01338 01339 KUrl KFileItem::mostLocalUrl() const 01340 { 01341 bool local = false; 01342 return mostLocalUrl(local); 01343 } 01344 01345 QDataStream & operator<< ( QDataStream & s, const KFileItem & a ) 01346 { 01347 // We don't need to save/restore anything that refresh() invalidates, 01348 // since that means we can re-determine those by ourselves. 01349 s << a.d->m_url; 01350 s << a.d->m_strName; 01351 s << a.d->m_strText; 01352 return s; 01353 } 01354 01355 QDataStream & operator>> ( QDataStream & s, KFileItem & a ) 01356 { 01357 s >> a.d->m_url; 01358 s >> a.d->m_strName; 01359 s >> a.d->m_strText; 01360 a.d->m_bIsLocalUrl = a.d->m_url.isLocalFile(); 01361 a.d->m_bMimeTypeKnown = false; 01362 a.refresh(); 01363 return s; 01364 } 01365 01366 KUrl KFileItem::url() const 01367 { 01368 return d->m_url; 01369 } 01370 01371 mode_t KFileItem::permissions() const 01372 { 01373 return d->m_permissions; 01374 } 01375 01376 mode_t KFileItem::mode() const 01377 { 01378 return d->m_fileMode; 01379 } 01380 01381 bool KFileItem::isLink() const 01382 { 01383 return d->m_bLink; 01384 } 01385 01386 bool KFileItem::isLocalFile() const 01387 { 01388 return d->m_bIsLocalUrl; 01389 } 01390 01391 QString KFileItem::text() const 01392 { 01393 return d->m_strText; 01394 } 01395 01396 QString KFileItem::name( bool lowerCase ) const 01397 { 01398 if ( !lowerCase ) 01399 return d->m_strName; 01400 else 01401 if ( d->m_strLowerCaseName.isNull() ) 01402 d->m_strLowerCaseName = d->m_strName.toLower(); 01403 return d->m_strLowerCaseName; 01404 } 01405 01406 KUrl KFileItem::targetUrl() const 01407 { 01408 const QString targetUrlStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_TARGET_URL ); 01409 if (!targetUrlStr.isEmpty()) 01410 return KUrl(targetUrlStr); 01411 else 01412 return url(); 01413 } 01414 01415 KUrl KFileItem::nepomukUri() const 01416 { 01417 #ifndef KIO_NO_NEPOMUK 01418 const QString nepomukUriStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_NEPOMUK_URI ); 01419 if(!nepomukUriStr.isEmpty()) { 01420 return KUrl(nepomukUriStr); 01421 } 01422 else if(targetUrl().isLocalFile()) { 01423 return targetUrl(); 01424 } 01425 else { 01426 return KUrl(); 01427 } 01428 #else 01429 return KUrl(); 01430 #endif 01431 } 01432 01433 /* 01434 * Mimetype handling. 01435 * 01436 * Initial state: m_pMimeType = 0. 01437 * When mimeTypePtr() is called first: fast mimetype determination, 01438 * might either find an accurate mimetype (-> Final state), otherwise we 01439 * set m_pMimeType but not m_bMimeTypeKnown (-> Intermediate state) 01440 * Intermediate state: determineMimeType() does the real determination -> Final state. 01441 * 01442 * If delayedMimeTypes isn't set, then we always go to the Final state directly. 01443 */ 01444 01445 KMimeType::Ptr KFileItem::mimeTypePtr() const 01446 { 01447 if (!d->m_pMimeType) { 01448 // On-demand fast (but not always accurate) mimetype determination 01449 Q_ASSERT(!d->m_url.isEmpty()); 01450 bool isLocalUrl; 01451 KUrl url = mostLocalUrl(isLocalUrl); 01452 int accuracy; 01453 d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl, 01454 // use fast mode if delayed mimetype determination can refine it later 01455 d->m_delayedMimeTypes, &accuracy ); 01456 // If we used the "fast mode" (no sniffing), and we didn't get a perfect (extension-based) match, 01457 // then determineMimeType will be able to do better. 01458 const bool canDoBetter = d->m_delayedMimeTypes && accuracy < 100; 01459 //kDebug() << "finding mimetype for" << url << ":" << d->m_pMimeType->name() << "canDoBetter=" << canDoBetter; 01460 d->m_bMimeTypeKnown = !canDoBetter; 01461 } 01462 return d->m_pMimeType; 01463 } 01464 01465 KIO::UDSEntry KFileItem::entry() const 01466 { 01467 return d->m_entry; 01468 } 01469 01470 bool KFileItem::isMarked() const 01471 { 01472 return d->m_bMarked; 01473 } 01474 01475 void KFileItem::mark() 01476 { 01477 d->m_bMarked = true; 01478 } 01479 01480 void KFileItem::unmark() 01481 { 01482 d->m_bMarked = false; 01483 } 01484 01485 KFileItem& KFileItem::operator=(const KFileItem& other) 01486 { 01487 d = other.d; 01488 return *this; 01489 } 01490 01491 bool KFileItem::isNull() const 01492 { 01493 return d == 0; 01494 } 01495 01496 KFileItemList::KFileItemList() 01497 { 01498 } 01499 01500 KFileItemList::KFileItemList( const QList<KFileItem> &items ) 01501 : QList<KFileItem>( items ) 01502 { 01503 } 01504 01505 KFileItem KFileItemList::findByName( const QString& fileName ) const 01506 { 01507 const_iterator it = begin(); 01508 const const_iterator itend = end(); 01509 for ( ; it != itend ; ++it ) { 01510 if ( (*it).name() == fileName ) { 01511 return *it; 01512 } 01513 } 01514 return KFileItem(); 01515 } 01516 01517 KFileItem KFileItemList::findByUrl( const KUrl& url ) const { 01518 const_iterator it = begin(); 01519 const const_iterator itend = end(); 01520 for ( ; it != itend ; ++it ) { 01521 if ( (*it).url() == url ) { 01522 return *it; 01523 } 01524 } 01525 return KFileItem(); 01526 } 01527 01528 KUrl::List KFileItemList::urlList() const { 01529 KUrl::List lst; 01530 const_iterator it = begin(); 01531 const const_iterator itend = end(); 01532 for ( ; it != itend ; ++it ) { 01533 lst.append( (*it).url() ); 01534 } 01535 return lst; 01536 } 01537 01538 KUrl::List KFileItemList::targetUrlList() const { 01539 KUrl::List lst; 01540 const_iterator it = begin(); 01541 const const_iterator itend = end(); 01542 for ( ; it != itend ; ++it ) { 01543 lst.append( (*it).targetUrl() ); 01544 } 01545 return lst; 01546 } 01547 01548 01549 bool KFileItem::isDesktopFile() const 01550 { 01551 return checkDesktopFile(*this, true); 01552 } 01553 01554 bool KFileItem::isRegularFile() const 01555 { 01556 return S_ISREG(d->m_fileMode); 01557 } 01558 01559 QDebug operator<<(QDebug stream, const KFileItem& item) 01560 { 01561 if (item.isNull()) { 01562 stream << "[null KFileItem]"; 01563 } else { 01564 stream << "[KFileItem for" << item.url() << "]"; 01565 } 01566 return stream; 01567 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 20:55:20 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 20:55:20 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.