00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kfileitem.h"
00022
00023 #include <config.h>
00024
00025 #include <sys/time.h>
00026 #include <pwd.h>
00027 #include <grp.h>
00028 #include <sys/types.h>
00029 #include <sys/stat.h>
00030
00031 #include <assert.h>
00032 #include <unistd.h>
00033
00034 #include <QtCore/QDate>
00035 #include <QtCore/QDir>
00036 #include <QtCore/QFile>
00037 #include <QtCore/QMap>
00038 #include <QTextDocument>
00039
00040 #include <kdebug.h>
00041 #include <kfilemetainfo.h>
00042 #include <kglobal.h>
00043 #include <kglobalsettings.h>
00044 #include <kiconloader.h>
00045 #include <klocale.h>
00046 #include <kmimetype.h>
00047 #include <krun.h>
00048 #include <kde_file.h>
00049 #include <kdesktopfile.h>
00050 #include <kmountpoint.h>
00051 #include <kconfiggroup.h>
00052 #ifndef Q_OS_WIN
00053 #include <knfsshare.h>
00054 #include <ksambashare.h>
00055 #endif
00056
00057 class KFileItemPrivate : public QSharedData
00058 {
00059 public:
00060 KFileItemPrivate(const KIO::UDSEntry& entry,
00061 mode_t mode, mode_t permissions,
00062 const KUrl& url,
00063 bool urlIsDirectory,
00064 bool delayedMimeTypes)
00065 : m_entry( entry ),
00066 m_url( url ),
00067 m_strName(),
00068 m_strText(),
00069 m_iconName(),
00070 m_strLowerCaseName(),
00071 m_pMimeType( 0 ),
00072 m_fileMode( mode ),
00073 m_permissions( permissions ),
00074 m_bMarked( false ),
00075 m_bLink( false ),
00076 m_bIsLocalUrl( url.isLocalFile() ),
00077 m_bMimeTypeKnown( false ),
00078 m_delayedMimeTypes( delayedMimeTypes ),
00079 m_useIconNameCache(false),
00080 m_hidden( Auto )
00081 {
00082 if (entry.count() != 0) {
00083 readUDSEntry( urlIsDirectory );
00084 } else {
00085 m_strName = url.fileName();
00086 m_strText = KIO::decodeFileName( m_strName );
00087 }
00088 init();
00089 }
00090
00091 ~KFileItemPrivate()
00092 {
00093 }
00094
00095
00096
00103 void init();
00104
00105 KIO::filesize_t size() const;
00106 KDateTime time( KFileItem::FileTimes which ) const;
00107 void setTime(KFileItem::FileTimes which, long long time_t_val) const;
00108 bool cmp( const KFileItemPrivate & item ) const;
00109
00114 void readUDSEntry( bool _urlIsDirectory );
00115
00119 QString parsePermissions( mode_t perm ) const;
00120
00124 mutable KIO::UDSEntry m_entry;
00128 KUrl m_url;
00129
00133 QString m_strName;
00134
00139 QString m_strText;
00140
00144 mutable QString m_iconName;
00145
00149 mutable QString m_strLowerCaseName;
00150
00154 mutable KMimeType::Ptr m_pMimeType;
00155
00159 mode_t m_fileMode;
00163 mode_t m_permissions;
00164
00168 bool m_bMarked:1;
00172 bool m_bLink:1;
00176 bool m_bIsLocalUrl:1;
00177
00178 mutable bool m_bMimeTypeKnown:1;
00179 bool m_delayedMimeTypes:1;
00180
00182 mutable bool m_useIconNameCache:1;
00183
00184
00185 enum { Auto, Hidden, Shown } m_hidden:3;
00186
00187
00188 QString m_guessedMimeType;
00189 mutable QString m_access;
00190 QMap<const void*, void*> m_extra;
00191 mutable KFileMetaInfo m_metaInfo;
00192
00193 enum { NumFlags = KFileItem::CreationTime + 1 };
00194 mutable KDateTime m_time[3];
00195 };
00196
00197 void KFileItemPrivate::init()
00198 {
00199 m_access.clear();
00200
00201
00202
00203
00204 if ( m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown )
00205 {
00206 mode_t mode = 0;
00207 if ( m_url.isLocalFile() )
00208 {
00209
00210
00211
00212
00213
00214
00215
00216 KDE_struct_stat buf;
00217 const QByteArray path = QFile::encodeName(m_url.path( KUrl::RemoveTrailingSlash ));
00218 if ( KDE_lstat( path.data(), &buf ) == 0 )
00219 {
00220 mode = buf.st_mode;
00221 if ( S_ISLNK( mode ) )
00222 {
00223 m_bLink = true;
00224 if ( KDE_stat( path.data(), &buf ) == 0 )
00225 mode = buf.st_mode;
00226 else
00227 mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO;
00228 }
00229
00230 setTime(KFileItem::ModificationTime, buf.st_mtime);
00231 setTime(KFileItem::AccessTime, buf.st_atime);
00232 if ( m_fileMode == KFileItem::Unknown )
00233 m_fileMode = mode & S_IFMT;
00234 if ( m_permissions == KFileItem::Unknown )
00235 m_permissions = mode & 07777;
00236 }
00237 }
00238 }
00239 }
00240
00241 void KFileItemPrivate::readUDSEntry( bool _urlIsDirectory )
00242 {
00243
00244
00245 m_fileMode = m_entry.numberValue( KIO::UDSEntry::UDS_FILE_TYPE );
00246 m_permissions = m_entry.numberValue( KIO::UDSEntry::UDS_ACCESS );
00247 m_strName = m_entry.stringValue( KIO::UDSEntry::UDS_NAME );
00248
00249 const QString displayName = m_entry.stringValue( KIO::UDSEntry::UDS_DISPLAY_NAME );
00250 if (!displayName.isEmpty())
00251 m_strText = displayName;
00252 else
00253 m_strText = KIO::decodeFileName( m_strName );
00254
00255 const QString urlStr = m_entry.stringValue( KIO::UDSEntry::UDS_URL );
00256 const bool UDS_URL_seen = !urlStr.isEmpty();
00257 if ( UDS_URL_seen ) {
00258 m_url = KUrl( urlStr );
00259 if ( m_url.isLocalFile() )
00260 m_bIsLocalUrl = true;
00261 }
00262 const QString mimeTypeStr = m_entry.stringValue( KIO::UDSEntry::UDS_MIME_TYPE );
00263 m_bMimeTypeKnown = !mimeTypeStr.isEmpty();
00264 if ( m_bMimeTypeKnown )
00265 m_pMimeType = KMimeType::mimeType( mimeTypeStr );
00266
00267 m_guessedMimeType = m_entry.stringValue( KIO::UDSEntry::UDS_GUESSED_MIME_TYPE );
00268 m_bLink = !m_entry.stringValue( KIO::UDSEntry::UDS_LINK_DEST ).isEmpty();
00269
00270 const int hiddenVal = m_entry.numberValue( KIO::UDSEntry::UDS_HIDDEN, -1 );
00271 m_hidden = hiddenVal == 1 ? Hidden : ( hiddenVal == 0 ? Shown : Auto );
00272
00273
00274 static const QString& dot = KGlobal::staticQString(".");
00275 if ( _urlIsDirectory && !UDS_URL_seen && !m_strName.isEmpty() && m_strName != dot )
00276 m_url.addPath( m_strName );
00277
00278 m_iconName.clear();
00279 }
00280
00281 inline
00282 KIO::filesize_t KFileItemPrivate::size() const
00283 {
00284
00285 long long fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_SIZE, -1 );
00286 if ( fieldVal != -1 ) {
00287 return fieldVal;
00288 }
00289
00290
00291 if ( m_bIsLocalUrl ) {
00292 KDE_struct_stat buf;
00293 if ( KDE_stat( QFile::encodeName(m_url.path(KUrl::RemoveTrailingSlash)), &buf ) == 0 )
00294 return buf.st_size;
00295 }
00296 return 0;
00297 }
00298
00299 void KFileItemPrivate::setTime(KFileItem::FileTimes mappedWhich, long long time_t_val) const
00300 {
00301 m_time[mappedWhich].setTime_t(time_t_val);
00302 m_time[mappedWhich] = m_time[mappedWhich].toLocalZone();
00303 }
00304
00305 KDateTime KFileItemPrivate::time( KFileItem::FileTimes mappedWhich ) const
00306 {
00307 if ( !m_time[mappedWhich].isNull() )
00308 return m_time[mappedWhich];
00309
00310
00311 long long fieldVal = -1;
00312 switch ( mappedWhich ) {
00313 case KFileItem::ModificationTime:
00314 fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_MODIFICATION_TIME, -1 );
00315 break;
00316 case KFileItem::AccessTime:
00317 fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_ACCESS_TIME, -1 );
00318 break;
00319 case KFileItem::CreationTime:
00320 fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_CREATION_TIME, -1 );
00321 break;
00322 }
00323 if ( fieldVal != -1 ) {
00324 setTime(mappedWhich, fieldVal);
00325 return m_time[mappedWhich];
00326 }
00327
00328
00329 if ( m_bIsLocalUrl )
00330 {
00331 KDE_struct_stat buf;
00332 if ( KDE_stat( QFile::encodeName(m_url.path(KUrl::RemoveTrailingSlash)), &buf ) == 0 )
00333 {
00334 setTime(KFileItem::ModificationTime, buf.st_mtime);
00335 setTime(KFileItem::AccessTime, buf.st_atime);
00336 m_time[KFileItem::CreationTime] = KDateTime();
00337 return m_time[mappedWhich];
00338 }
00339 }
00340 return KDateTime();
00341 }
00342
00343 inline
00344 bool KFileItemPrivate::cmp( const KFileItemPrivate & item ) const
00345 {
00346 return ( m_strName == item.m_strName
00347 && m_bIsLocalUrl == item.m_bIsLocalUrl
00348 && m_fileMode == item.m_fileMode
00349 && m_permissions == item.m_permissions
00350 && m_entry.stringValue( KIO::UDSEntry::UDS_USER ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_USER )
00351 && m_entry.stringValue( KIO::UDSEntry::UDS_GROUP ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_GROUP )
00352 && m_bLink == item.m_bLink
00353 && m_hidden == item.m_hidden
00354 && size() == item.size()
00355 && time(KFileItem::ModificationTime) == item.time(KFileItem::ModificationTime)
00356 && m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME )
00357 );
00358
00359
00360
00361 }
00362
00363 inline
00364 QString KFileItemPrivate::parsePermissions(mode_t perm) const
00365 {
00366 static char buffer[ 12 ];
00367
00368 char uxbit,gxbit,oxbit;
00369
00370 if ( (perm & (S_IXUSR|S_ISUID)) == (S_IXUSR|S_ISUID) )
00371 uxbit = 's';
00372 else if ( (perm & (S_IXUSR|S_ISUID)) == S_ISUID )
00373 uxbit = 'S';
00374 else if ( (perm & (S_IXUSR|S_ISUID)) == S_IXUSR )
00375 uxbit = 'x';
00376 else
00377 uxbit = '-';
00378
00379 if ( (perm & (S_IXGRP|S_ISGID)) == (S_IXGRP|S_ISGID) )
00380 gxbit = 's';
00381 else if ( (perm & (S_IXGRP|S_ISGID)) == S_ISGID )
00382 gxbit = 'S';
00383 else if ( (perm & (S_IXGRP|S_ISGID)) == S_IXGRP )
00384 gxbit = 'x';
00385 else
00386 gxbit = '-';
00387
00388 if ( (perm & (S_IXOTH|S_ISVTX)) == (S_IXOTH|S_ISVTX) )
00389 oxbit = 't';
00390 else if ( (perm & (S_IXOTH|S_ISVTX)) == S_ISVTX )
00391 oxbit = 'T';
00392 else if ( (perm & (S_IXOTH|S_ISVTX)) == S_IXOTH )
00393 oxbit = 'x';
00394 else
00395 oxbit = '-';
00396
00397
00398
00399 if (m_fileMode != KFileItem::Unknown && S_ISDIR(m_fileMode))
00400 buffer[0] = 'd';
00401 else if (m_bLink)
00402 buffer[0] = 'l';
00403 else
00404 buffer[0] = '-';
00405
00406 buffer[1] = ((( perm & S_IRUSR ) == S_IRUSR ) ? 'r' : '-' );
00407 buffer[2] = ((( perm & S_IWUSR ) == S_IWUSR ) ? 'w' : '-' );
00408 buffer[3] = uxbit;
00409 buffer[4] = ((( perm & S_IRGRP ) == S_IRGRP ) ? 'r' : '-' );
00410 buffer[5] = ((( perm & S_IWGRP ) == S_IWGRP ) ? 'w' : '-' );
00411 buffer[6] = gxbit;
00412 buffer[7] = ((( perm & S_IROTH ) == S_IROTH ) ? 'r' : '-' );
00413 buffer[8] = ((( perm & S_IWOTH ) == S_IWOTH ) ? 'w' : '-' );
00414 buffer[9] = oxbit;
00415
00416 if (m_entry.contains(KIO::UDSEntry::UDS_EXTENDED_ACL)) {
00417 buffer[10] = '+';
00418 buffer[11] = 0;
00419 } else {
00420 buffer[10] = 0;
00421 }
00422
00423 return QString::fromLatin1(buffer);
00424 }
00425
00426
00428
00429 KFileItem::KFileItem()
00430 : d(0)
00431 {
00432 }
00433
00434 KFileItem::KFileItem( const KIO::UDSEntry& entry, const KUrl& directoryUrl,
00435 bool delayedMimeTypes, bool urlIsDirectory )
00436 : d(new KFileItemPrivate(entry, KFileItem::Unknown, KFileItem::Unknown,
00437 directoryUrl, urlIsDirectory, delayedMimeTypes))
00438 {
00439 }
00440
00441 KFileItem::KFileItem( mode_t mode, mode_t permissions, const KUrl& url, bool delayedMimeTypes )
00442 : d(new KFileItemPrivate(KIO::UDSEntry(), mode, permissions,
00443 url, false, delayedMimeTypes))
00444 {
00445 }
00446
00447 KFileItem::KFileItem( const KUrl &url, const QString &mimeType, mode_t mode )
00448 : d(new KFileItemPrivate(KIO::UDSEntry(), mode, KFileItem::Unknown,
00449 url, false, false))
00450 {
00451 d->m_bMimeTypeKnown = !mimeType.isEmpty();
00452 if (d->m_bMimeTypeKnown)
00453 d->m_pMimeType = KMimeType::mimeType( mimeType );
00454 }
00455
00456
00457 KFileItem::KFileItem(const KFileItem& other)
00458 : d(other.d)
00459 {
00460 }
00461
00462 KFileItem::~KFileItem()
00463 {
00464 }
00465
00466 void KFileItem::refresh()
00467 {
00468 d->m_fileMode = KFileItem::Unknown;
00469 d->m_permissions = KFileItem::Unknown;
00470 d->m_metaInfo = KFileMetaInfo();
00471 d->m_hidden = KFileItemPrivate::Auto;
00472 refreshMimeType();
00473
00474
00475
00476
00477
00478 d->m_entry.clear();
00479 d->init();
00480 }
00481
00482 void KFileItem::refreshMimeType()
00483 {
00484 d->m_pMimeType = 0;
00485 d->m_bMimeTypeKnown = false;
00486 d->m_iconName.clear();
00487 }
00488
00489 void KFileItem::setUrl( const KUrl &url )
00490 {
00491 d->m_url = url;
00492 setName( url.fileName() );
00493 }
00494
00495 void KFileItem::setName( const QString& name )
00496 {
00497 d->m_strName = name;
00498 d->m_strText = KIO::decodeFileName( d->m_strName );
00499 }
00500
00501 QString KFileItem::linkDest() const
00502 {
00503
00504 const QString linkStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_LINK_DEST );
00505 if ( !linkStr.isEmpty() )
00506 return linkStr;
00507
00508
00509 if ( d->m_bIsLocalUrl )
00510 {
00511 char buf[1000];
00512 int n = readlink( QFile::encodeName(d->m_url.path( KUrl::RemoveTrailingSlash )), buf, sizeof(buf)-1 );
00513 if ( n != -1 )
00514 {
00515 buf[ n ] = 0;
00516 return QFile::decodeName( buf );
00517 }
00518 }
00519 return QString();
00520 }
00521
00522 QString KFileItem::localPath() const
00523 {
00524 if ( d->m_bIsLocalUrl ) {
00525 return d->m_url.path();
00526 }
00527
00528
00529 return d->m_entry.stringValue( KIO::UDSEntry::UDS_LOCAL_PATH );
00530 }
00531
00532 KIO::filesize_t KFileItem::size() const
00533 {
00534 return d->size();
00535 }
00536
00537 bool KFileItem::hasExtendedACL() const
00538 {
00539
00540 return d->m_entry.contains(KIO::UDSEntry::UDS_EXTENDED_ACL);
00541 }
00542
00543 KACL KFileItem::ACL() const
00544 {
00545 if ( hasExtendedACL() ) {
00546
00547 const QString fieldVal = d->m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING );
00548 if ( !fieldVal.isEmpty() )
00549 return KACL( fieldVal );
00550 }
00551
00552 return KACL( d->m_permissions );
00553 }
00554
00555 KACL KFileItem::defaultACL() const
00556 {
00557
00558 const QString fieldVal = d->m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING );
00559 if ( !fieldVal.isEmpty() )
00560 return KACL(fieldVal);
00561 else
00562 return KACL();
00563 }
00564
00565 KDateTime KFileItem::time( FileTimes which ) const
00566 {
00567 return d->time(which);
00568 }
00569
00570 time_t KFileItem::time( unsigned int which ) const
00571 {
00572 switch (which) {
00573 case KIO::UDSEntry::UDS_ACCESS_TIME:
00574 return d->time(AccessTime).toTime_t();
00575 case KIO::UDSEntry::UDS_CREATION_TIME:
00576 return d->time(CreationTime).toTime_t();
00577 case KIO::UDSEntry::UDS_MODIFICATION_TIME:
00578 default:
00579 return d->time(ModificationTime).toTime_t();
00580 }
00581 }
00582
00583 QString KFileItem::user() const
00584 {
00585 QString userName = d->m_entry.stringValue( KIO::UDSEntry::UDS_USER );
00586 if ( userName.isEmpty() && d->m_bIsLocalUrl )
00587 {
00588 #ifdef Q_WS_WIN
00589 QFileInfo a(d->m_url.path( KUrl::RemoveTrailingSlash ));
00590 userName = a.owner();
00591 d->m_entry.insert( KIO::UDSEntry::UDS_USER, userName );
00592 #else
00593 KDE_struct_stat buff;
00594 if ( KDE_lstat( QFile::encodeName(d->m_url.path( KUrl::RemoveTrailingSlash )), &buff ) == 0)
00595 {
00596 struct passwd *pwuser = getpwuid( buff.st_uid );
00597 if ( pwuser != 0 ) {
00598 userName = QString::fromLocal8Bit(pwuser->pw_name);
00599 d->m_entry.insert( KIO::UDSEntry::UDS_USER, userName );
00600 }
00601 }
00602 #endif
00603 }
00604 return userName;
00605 }
00606
00607 QString KFileItem::group() const
00608 {
00609 QString groupName = d->m_entry.stringValue( KIO::UDSEntry::UDS_GROUP );
00610 if (groupName.isEmpty() && d->m_bIsLocalUrl )
00611 {
00612 #ifdef Q_WS_WIN
00613 QFileInfo a(d->m_url.path( KUrl::RemoveTrailingSlash ));
00614 groupName = a.group();
00615 d->m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName );
00616 #else
00617 KDE_struct_stat buff;
00618 if ( KDE_lstat( QFile::encodeName(d->m_url.path( KUrl::RemoveTrailingSlash )), &buff ) == 0)
00619 {
00620 struct group *ge = getgrgid( buff.st_gid );
00621 if ( ge != 0 ) {
00622 groupName = QString::fromLocal8Bit(ge->gr_name);
00623 if (groupName.isEmpty())
00624 groupName.sprintf("%d",ge->gr_gid);
00625 }
00626 else
00627 groupName.sprintf("%d",buff.st_gid);
00628 d->m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName );
00629 }
00630 #endif
00631 }
00632 return groupName;
00633 }
00634
00635 QString KFileItem::mimetype() const
00636 {
00637 KFileItem * that = const_cast<KFileItem *>(this);
00638 return that->determineMimeType()->name();
00639 }
00640
00641 KMimeType::Ptr KFileItem::determineMimeType() const
00642 {
00643 if ( !d->m_pMimeType || !d->m_bMimeTypeKnown )
00644 {
00645 bool isLocalUrl;
00646 KUrl url = mostLocalUrl(isLocalUrl);
00647
00648 d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl );
00649 Q_ASSERT(d->m_pMimeType);
00650
00651 d->m_bMimeTypeKnown = true;
00652 }
00653
00654 return d->m_pMimeType;
00655 }
00656
00657 bool KFileItem::isMimeTypeKnown() const
00658 {
00659
00660
00661
00662 return d->m_bMimeTypeKnown && d->m_guessedMimeType.isEmpty();
00663 }
00664
00665 QString KFileItem::mimeComment() const
00666 {
00667 KMimeType::Ptr mType = determineMimeType();
00668
00669 bool isLocalUrl;
00670 KUrl url = mostLocalUrl(isLocalUrl);
00671
00672 KMimeType::Ptr mime = mimeTypePtr();
00673 if (isLocalUrl && mime->is("application/x-desktop")) {
00674 KDesktopFile cfg( url.path() );
00675 QString comment = cfg.desktopGroup().readEntry( "Comment" );
00676 if (!comment.isEmpty())
00677 return comment;
00678 }
00679
00680 QString comment = mType->comment( url );
00681
00682 if (!comment.isEmpty())
00683 return comment;
00684 else
00685 return mType->name();
00686 }
00687
00688 static QString iconFromDesktopFile(const QString& path)
00689 {
00690 KDesktopFile cfg( path );
00691 const KConfigGroup group = cfg.desktopGroup();
00692 const QString icon = cfg.readIcon();
00693 const QString type = cfg.readPath();
00694
00695 if ( cfg.hasDeviceType() )
00696 {
00697 const QString unmount_icon = group.readEntry( "UnmountIcon" );
00698 const QString dev = cfg.readDevice();
00699 if ( !icon.isEmpty() && !unmount_icon.isEmpty() && !dev.isEmpty() )
00700 {
00701 KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByDevice(dev);
00702 if (!mountPoint)
00703 return unmount_icon;
00704 }
00705 } else if ( cfg.hasLinkType() ) {
00706 const QString emptyIcon = group.readEntry( "EmptyIcon" );
00707 if ( !emptyIcon.isEmpty() ) {
00708 const QString u = cfg.readUrl();
00709 const KUrl url( u );
00710 if ( url.protocol() == "trash" ) {
00711
00712
00713 KConfig trashConfig( "trashrc", KConfig::SimpleConfig );
00714 if ( trashConfig.group("Status").readEntry( "Empty", true ) ) {
00715 return emptyIcon;
00716 }
00717 }
00718 }
00719 }
00720 return icon;
00721 }
00722
00723 QString KFileItem::iconName() const
00724 {
00725 if (d->m_useIconNameCache && !d->m_iconName.isEmpty()) {
00726 return d->m_iconName;
00727 }
00728
00729 d->m_iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME );
00730 if (!d->m_iconName.isEmpty()) {
00731 d->m_useIconNameCache = d->m_bMimeTypeKnown;
00732 return d->m_iconName;
00733 }
00734
00735 bool isLocalUrl;
00736 KUrl url = mostLocalUrl(isLocalUrl);
00737
00738 KMimeType::Ptr mime = mimeTypePtr();
00739 if (isLocalUrl && mime->is("application/x-desktop")) {
00740 d->m_iconName = iconFromDesktopFile(url.path());
00741 if (!d->m_iconName.isEmpty()) {
00742 d->m_useIconNameCache = d->m_bMimeTypeKnown;
00743 return d->m_iconName;
00744 }
00745 }
00746
00747
00748 d->m_iconName = mime->iconName(url);
00749 d->m_useIconNameCache = d->m_bMimeTypeKnown;
00750 return d->m_iconName;
00751 }
00752
00753 QStringList KFileItem::overlays() const
00754 {
00755 QStringList names;
00756 if ( d->m_bLink ) {
00757 names.append("emblem-symbolic-link");
00758 }
00759
00760 if ( !S_ISDIR( d->m_fileMode )
00761 && !isReadable()) {
00762 names.append("object-locked");
00763 }
00764
00765 if ( isHidden() ) {
00766 names.append("hidden");
00767 }
00768
00769 #ifndef Q_OS_WIN
00770 if( S_ISDIR( d->m_fileMode ) && d->m_bIsLocalUrl)
00771 {
00772 if (KSambaShare::instance()->isDirectoryShared( d->m_url.path() ) ||
00773 KNFSShare::instance()->isDirectoryShared( d->m_url.path() ))
00774 {
00775
00776 names.append("network-workgroup");
00777 }
00778 }
00779 #endif // Q_OS_WIN
00780
00781 if ( d->m_pMimeType && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) &&
00782 d->m_pMimeType->is("application/x-gzip") ) {
00783 names.append("application-zip");
00784 }
00785
00786 return names;
00787 }
00788
00789 QPixmap KFileItem::pixmap( int _size, int _state ) const
00790 {
00791 const QString iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME );
00792 if ( !iconName.isEmpty() )
00793 return DesktopIcon(iconName, _size, _state);
00794
00795 if ( !d->m_pMimeType )
00796 {
00797 if ( S_ISDIR( d->m_fileMode ) ) {
00798 static const QString * defaultFolderIcon = 0;
00799 if ( !defaultFolderIcon ) {
00800 const KMimeType::Ptr mimeType = KMimeType::mimeType( "inode/directory" );
00801 if ( mimeType )
00802 defaultFolderIcon = &KGlobal::staticQString( mimeType->iconName() );
00803 else
00804 kWarning(7000) << "No mimetype for inode/directory could be found. Check your installation.";
00805 }
00806 if ( defaultFolderIcon )
00807 return DesktopIcon( *defaultFolderIcon, _size, _state );
00808
00809 }
00810 return DesktopIcon( "unknown", _size, _state );
00811 }
00812
00813 KMimeType::Ptr mime;
00814
00815 if ( !d->m_bMimeTypeKnown && !d->m_guessedMimeType.isEmpty() )
00816 mime = KMimeType::mimeType( d->m_guessedMimeType );
00817 else
00818 mime = d->m_pMimeType;
00819
00820
00821
00822 if ( mime->name() == "application/x-gzip" && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) )
00823 {
00824 KUrl sf;
00825 sf.setPath( d->m_url.path().left( d->m_url.path().length() - 3 ) );
00826
00827 mime = KMimeType::findByUrl( sf, 0, d->m_bIsLocalUrl );
00828 }
00829
00830 bool isLocalUrl;
00831 KUrl url = mostLocalUrl(isLocalUrl);
00832
00833 QPixmap p = KIconLoader::global()->loadMimeTypeIcon( mime->iconName( url ), KIconLoader::Desktop, _size, _state );
00834
00835 if (p.isNull())
00836 kWarning() << "Pixmap not found for mimetype " << d->m_pMimeType->name();
00837
00838 return p;
00839 }
00840
00841 bool KFileItem::isReadable() const
00842 {
00843
00844
00845
00846
00847
00848
00849
00850
00851 if (d->m_permissions != KFileItem::Unknown) {
00852
00853 if ( !(S_IRUSR & d->m_permissions) && !(S_IRGRP & d->m_permissions) && !(S_IROTH & d->m_permissions) )
00854 return false;
00855
00856
00857 if ( (S_IRUSR|S_IRGRP|S_IROTH) & d->m_permissions )
00858 return true;
00859 }
00860
00861
00862 if ( d->m_bIsLocalUrl && ::access( QFile::encodeName(d->m_url.path()), R_OK ) == -1 )
00863 return false;
00864
00865 return true;
00866 }
00867
00868 bool KFileItem::isWritable() const
00869 {
00870
00871
00872
00873
00874
00875
00876
00877
00878 if (d->m_permissions != KFileItem::Unknown) {
00879
00880 if ( !(S_IWUSR & d->m_permissions) && !(S_IWGRP & d->m_permissions) && !(S_IWOTH & d->m_permissions) )
00881 return false;
00882 }
00883
00884
00885 if ( d->m_bIsLocalUrl && ::access( QFile::encodeName(d->m_url.path()), W_OK ) == -1 )
00886 return false;
00887
00888 return true;
00889 }
00890
00891 bool KFileItem::isHidden() const
00892 {
00893 if ( d->m_hidden != KFileItemPrivate::Auto )
00894 return d->m_hidden == KFileItemPrivate::Hidden;
00895
00896 if ( !d->m_url.isEmpty() )
00897 return d->m_url.fileName()[0] == '.';
00898 else
00899 return d->m_strName[0] == '.';
00900 }
00901
00902 bool KFileItem::isDir() const
00903 {
00904 if ( d->m_fileMode == KFileItem::Unknown )
00905 {
00906 kDebug() << "can't say -> false";
00907 return false;
00908 }
00909 return (S_ISDIR(d->m_fileMode));
00910
00911
00912
00913
00914
00915
00916
00917
00918 }
00919
00920 bool KFileItem::isFile() const
00921 {
00922 return !isDir();
00923 }
00924
00925 bool KFileItem::acceptsDrops() const
00926 {
00927
00928 if ( S_ISDIR( mode() ) ) {
00929 return isWritable();
00930 }
00931
00932
00933 if ( !d->m_bIsLocalUrl )
00934 return false;
00935
00936 if ( mimetype() == "application/x-desktop")
00937 return true;
00938
00939
00940 if ( QFileInfo(d->m_url.path()).isExecutable() )
00941 return true;
00942
00943 return false;
00944 }
00945
00946 QString KFileItem::getStatusBarInfo() const
00947 {
00948 QString text = d->m_strText;
00949 const QString comment = mimeComment();
00950
00951 if ( d->m_bLink )
00952 {
00953 text += ' ';
00954 if ( comment.isEmpty() )
00955 text += i18n ( "(Symbolic Link to %1)", linkDest() );
00956 else
00957 text += i18n("(%1, Link to %2)", comment, linkDest());
00958 }
00959 else if ( targetUrl() != url() )
00960 {
00961 text += i18n ( " (Points to %1)", targetUrl().pathOrUrl());
00962 }
00963 else if ( S_ISREG( d->m_fileMode ) )
00964 {
00965 text += QString(" (%1, %2)").arg( comment, KIO::convertSize( size() ) );
00966 }
00967 else
00968 {
00969 text += QString(" (%1)").arg( comment );
00970 }
00971 return text;
00972 }
00973
00974 QString KFileItem::getToolTipText(int maxcount) const
00975 {
00976
00977 QString tip;
00978 KFileMetaInfo info = metaInfo();
00979
00980
00981
00982 const char* start = "<tr><td><nobr><font color=\"black\">";
00983 const char* mid = "</font></nobr></td><td><nobr><font color=\"black\">";
00984 const char* end = "</font></nobr></td></tr>";
00985
00986 tip = "<table cellspacing=0 cellpadding=0>";
00987
00988 tip += start + i18n("Name:") + mid + text() + end;
00989 tip += start + i18n("Type:") + mid;
00990
00991 QString type = Qt::escape(mimeComment());
00992 if ( d->m_bLink ) {
00993 tip += i18n("Link to %1 (%2)", linkDest(), type) + end;
00994 } else
00995 tip += type + end;
00996
00997 if ( !S_ISDIR ( d->m_fileMode ) )
00998 tip += start + i18n("Size:") + mid +
00999 QString("%1 (%2)").arg(KIO::convertSize(size()))
01000 .arg(KGlobal::locale()->formatNumber(size(), 0)) +
01001 end;
01002
01003 tip += start + i18n("Modified:") + mid +
01004 timeString( KFileItem::ModificationTime ) + end
01005 #ifndef Q_WS_WIN //TODO: show win32-specific permissions
01006 +start + i18n("Owner:") + mid + user() + " - " + group() + end +
01007 start + i18n("Permissions:") + mid +
01008 permissionsString() + end
01009 #endif
01010 ;
01011
01012 if (info.isValid())
01013 {
01014 tip += "<tr><td colspan=2><center><s> </s></center></td></tr>";
01015 const QStringList keys = info.preferredKeys();
01016
01017
01018 QStringList::ConstIterator it = keys.begin();
01019 for (int count = 0; count<maxcount && it!=keys.end() ; ++it)
01020 {
01021 KFileMetaInfoItem item = info.item( *it );
01022 if ( item.isValid() )
01023 {
01024 QString s = item.value().toString();
01025 if ( ( item.properties().attributes() & PredicateProperties::SqueezeText )
01026 && s.length() > 50) {
01027 s.truncate(47);
01028 s.append("...");
01029 }
01030 if ( !s.isEmpty() )
01031 {
01032 count++;
01033 tip += start +
01034 Qt::escape( item.name() ) + ':' +
01035 mid +
01036 Qt::escape( s ) +
01037 end;
01038 }
01039
01040 }
01041 }
01042 }
01043 tip += "</table>";
01044
01045
01046
01047
01048 return tip;
01049 }
01050
01051 void KFileItem::run( QWidget* parentWidget ) const
01052 {
01053 (void) new KRun( d->m_url, parentWidget, d->m_fileMode, d->m_bIsLocalUrl );
01054 }
01055
01056 bool KFileItem::cmp( const KFileItem & item ) const
01057 {
01058 return d->cmp(*item.d);
01059 }
01060
01061 bool KFileItem::operator==(const KFileItem& other) const
01062 {
01063
01064 return d == other.d;
01065 }
01066
01067 bool KFileItem::operator!=(const KFileItem& other) const
01068 {
01069 return d != other.d;
01070 }
01071
01072 void KFileItem::setUDSEntry( const KIO::UDSEntry& _entry, const KUrl& _url,
01073 bool _delayedMimeTypes, bool _urlIsDirectory )
01074 {
01075 d->m_entry = _entry;
01076 d->m_url = _url;
01077 d->m_strName.clear();
01078 d->m_strText.clear();
01079 d->m_iconName.clear();
01080 d->m_strLowerCaseName.clear();
01081 d->m_pMimeType = 0;
01082 d->m_fileMode = KFileItem::Unknown;
01083 d->m_permissions = KFileItem::Unknown;
01084 d->m_bMarked = false;
01085 d->m_bLink = false;
01086 d->m_bIsLocalUrl = _url.isLocalFile();
01087 d->m_bMimeTypeKnown = false;
01088 d->m_hidden = KFileItemPrivate::Auto;
01089 d->m_guessedMimeType.clear();
01090 d->m_metaInfo = KFileMetaInfo();
01091 d->m_delayedMimeTypes = _delayedMimeTypes;
01092 d->m_useIconNameCache = false;
01093
01094 d->readUDSEntry( _urlIsDirectory );
01095 d->init();
01096 }
01097
01098 KFileItem::operator QVariant() const
01099 {
01100 return qVariantFromValue(*this);
01101 }
01102
01103 void KFileItem::setExtraData( const void *key, void *value )
01104 {
01105 if ( !key )
01106 return;
01107
01108 d->m_extra.insert( key, value );
01109 }
01110
01111 const void * KFileItem::extraData( const void *key ) const
01112 {
01113 return d->m_extra.value( key, 0 );
01114 }
01115
01116 void KFileItem::removeExtraData( const void *key )
01117 {
01118 d->m_extra.remove( key );
01119 }
01120
01121 QString KFileItem::permissionsString() const
01122 {
01123 if (d->m_access.isNull() && d->m_permissions != KFileItem::Unknown)
01124 d->m_access = d->parsePermissions( d->m_permissions );
01125
01126 return d->m_access;
01127 }
01128
01129
01130 QString KFileItem::timeString( FileTimes which ) const
01131 {
01132 return KGlobal::locale()->formatDateTime( d->time(which) );
01133 }
01134
01135 QString KFileItem::timeString( unsigned int which ) const
01136 {
01137 switch (which) {
01138 case KIO::UDSEntry::UDS_ACCESS_TIME:
01139 return timeString(AccessTime);
01140 case KIO::UDSEntry::UDS_CREATION_TIME:
01141 return timeString(CreationTime);
01142 case KIO::UDSEntry::UDS_MODIFICATION_TIME:
01143 default:
01144 return timeString(ModificationTime);
01145 }
01146 }
01147
01148 void KFileItem::setMetaInfo( const KFileMetaInfo & info ) const
01149 {
01150 d->m_metaInfo = info;
01151 }
01152
01153 KFileMetaInfo KFileItem::metaInfo(bool autoget, int) const
01154 {
01155 if (autoget && !d->m_metaInfo.isValid())
01156 {
01157 bool isLocalUrl;
01158 KUrl url(mostLocalUrl(isLocalUrl));
01159 if (KGlobalSettings::showFilePreview(url))
01160 d->m_metaInfo = KFileMetaInfo(url);
01161 }
01162 return d->m_metaInfo;
01163 }
01164
01165 void KFileItem::assign( const KFileItem & item )
01166 {
01167 *this = item;
01168 }
01169
01170 KUrl KFileItem::mostLocalUrl(bool &local) const
01171 {
01172 QString local_path = localPath();
01173
01174 if ( !local_path.isEmpty() )
01175 {
01176 local = true;
01177 KUrl url;
01178 url.setPath(local_path);
01179 return url;
01180 }
01181 else
01182 {
01183 local = d->m_bIsLocalUrl;
01184 return d->m_url;
01185 }
01186 }
01187
01188 QDataStream & operator<< ( QDataStream & s, const KFileItem & a )
01189 {
01190
01191
01192 s << a.d->m_url;
01193 s << a.d->m_strName;
01194 s << a.d->m_strText;
01195 return s;
01196 }
01197
01198 QDataStream & operator>> ( QDataStream & s, KFileItem & a )
01199 {
01200 s >> a.d->m_url;
01201 s >> a.d->m_strName;
01202 s >> a.d->m_strText;
01203 a.d->m_bIsLocalUrl = a.d->m_url.isLocalFile();
01204 a.d->m_bMimeTypeKnown = false;
01205 a.refresh();
01206 return s;
01207 }
01208
01209 KUrl KFileItem::url() const
01210 {
01211 return d->m_url;
01212 }
01213
01214 mode_t KFileItem::permissions() const
01215 {
01216 return d->m_permissions;
01217 }
01218
01219 mode_t KFileItem::mode() const
01220 {
01221 return d->m_fileMode;
01222 }
01223
01224 bool KFileItem::isLink() const
01225 {
01226 return d->m_bLink;
01227 }
01228
01229 bool KFileItem::isLocalFile() const
01230 {
01231 return d->m_bIsLocalUrl;
01232 }
01233
01234 QString KFileItem::text() const
01235 {
01236 return d->m_strText;
01237 }
01238
01239 QString KFileItem::name( bool lowerCase ) const
01240 {
01241 if ( !lowerCase )
01242 return d->m_strName;
01243 else
01244 if ( d->m_strLowerCaseName.isNull() )
01245 d->m_strLowerCaseName = d->m_strName.toLower();
01246 return d->m_strLowerCaseName;
01247 }
01248
01249 KUrl KFileItem::targetUrl() const
01250 {
01251 const QString targetUrlStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_TARGET_URL );
01252 if (!targetUrlStr.isEmpty())
01253 return KUrl(targetUrlStr);
01254 else
01255 return url();
01256 }
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270 KMimeType::Ptr KFileItem::mimeTypePtr() const
01271 {
01272 if (!d->m_pMimeType) {
01273
01274 Q_ASSERT(!d->m_url.isEmpty());
01275 bool isLocalUrl;
01276 KUrl url = mostLocalUrl(isLocalUrl);
01277 int accuracy;
01278 d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl,
01279
01280 d->m_delayedMimeTypes, &accuracy );
01281
01282
01283 const bool canDoBetter = d->m_delayedMimeTypes && accuracy < 100;
01284
01285 d->m_bMimeTypeKnown = !canDoBetter;
01286 }
01287 return d->m_pMimeType;
01288 }
01289
01290 KIO::UDSEntry KFileItem::entry() const
01291 {
01292 return d->m_entry;
01293 }
01294
01295 bool KFileItem::isMarked() const
01296 {
01297 return d->m_bMarked;
01298 }
01299
01300 void KFileItem::mark()
01301 {
01302 d->m_bMarked = true;
01303 }
01304
01305 void KFileItem::unmark()
01306 {
01307 d->m_bMarked = false;
01308 }
01309
01310 KFileItem& KFileItem::operator=(const KFileItem& other)
01311 {
01312 d = other.d;
01313 return *this;
01314 }
01315
01316 bool KFileItem::isNull() const
01317 {
01318 return d == 0;
01319 }
01320
01321 KFileItemList::KFileItemList()
01322 {
01323 }
01324
01325 KFileItemList::KFileItemList( const QList<KFileItem> &items )
01326 : QList<KFileItem>( items )
01327 {
01328 }
01329
01330 KFileItem KFileItemList::findByName( const QString& fileName ) const
01331 {
01332 const_iterator it = begin();
01333 const const_iterator itend = end();
01334 for ( ; it != itend ; ++it ) {
01335 if ( (*it).name() == fileName ) {
01336 return *it;
01337 }
01338 }
01339 return KFileItem();
01340 }
01341
01342 KFileItem KFileItemList::findByUrl( const KUrl& url ) const {
01343 const_iterator it = begin();
01344 const const_iterator itend = end();
01345 for ( ; it != itend ; ++it ) {
01346 if ( (*it).url() == url ) {
01347 return *it;
01348 }
01349 }
01350 return KFileItem();
01351 }
01352
01353 KUrl::List KFileItemList::urlList() const {
01354 KUrl::List lst;
01355 const_iterator it = begin();
01356 const const_iterator itend = end();
01357 for ( ; it != itend ; ++it ) {
01358 lst.append( (*it).url() );
01359 }
01360 return lst;
01361 }
01362
01363 bool KFileItem::isDesktopFile() const
01364 {
01365
01366 bool isLocal;
01367 const KUrl url = mostLocalUrl(isLocal);
01368 if (!isLocal)
01369 return false;
01370
01371
01372 if (!S_ISREG(d->m_fileMode))
01373 return false;
01374
01375
01376 if (!isReadable())
01377 return false;
01378
01379
01380 return determineMimeType()->is("application/x-desktop");
01381 }
01382