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