• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

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 
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     QString user() const;
00110     QString group() const;
00111 
00116     void readUDSEntry( bool _urlIsDirectory );
00117 
00121     QString parsePermissions( mode_t perm ) const;
00122 
00126     mutable KIO::UDSEntry m_entry;
00130     KUrl m_url;
00131 
00135     QString m_strName;
00136 
00141     QString m_strText;
00142 
00146     mutable QString m_iconName;
00147 
00151     mutable QString m_strLowerCaseName;
00152 
00156     mutable KMimeType::Ptr m_pMimeType;
00157 
00161     mode_t m_fileMode;
00165     mode_t m_permissions;
00166 
00170     bool m_bMarked:1;
00174     bool m_bLink:1;
00178     bool m_bIsLocalUrl:1;
00179 
00180     mutable bool m_bMimeTypeKnown:1;
00181     bool m_delayedMimeTypes:1;
00182 
00184     mutable bool m_useIconNameCache:1;
00185 
00186     // Auto: check leading dot.
00187     enum { Auto, Hidden, Shown } m_hidden:3;
00188 
00189     // For special case like link to dirs over FTP
00190     QString m_guessedMimeType;
00191     mutable QString m_access;
00192     QMap<const void*, void*> m_extra; // DEPRECATED
00193     mutable KFileMetaInfo m_metaInfo;
00194 
00195     enum { NumFlags = KFileItem::CreationTime + 1 };
00196     mutable KDateTime m_time[3];
00197 };
00198 
00199 void KFileItemPrivate::init()
00200 {
00201     m_access.clear();
00202     //  metaInfo = KFileMetaInfo();
00203 
00204     // determine mode and/or permissions if unknown
00205     // TODO: delay this until requested
00206     if ( m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown )
00207     {
00208         mode_t mode = 0;
00209         if ( m_url.isLocalFile() )
00210         {
00211             /* directories may not have a slash at the end if
00212              * we want to stat() them; it requires that we
00213              * change into it .. which may not be allowed
00214              * stat("/is/unaccessible")  -> rwx------
00215              * stat("/is/unaccessible/") -> EPERM            H.Z.
00216              * This is the reason for the -1
00217              */
00218             KDE_struct_stat buf;
00219             const QString path = m_url.toLocalFile( KUrl::RemoveTrailingSlash );
00220             if ( KDE::lstat( path, &buf ) == 0 )
00221             {
00222                 mode = buf.st_mode;
00223                 if ( S_ISLNK( mode ) )
00224                 {
00225                     m_bLink = true;
00226                     if ( KDE::stat( path, &buf ) == 0 )
00227                         mode = buf.st_mode;
00228                     else // link pointing to nowhere (see kio/file/file.cc)
00229                         mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO;
00230                 }
00231                 // While we're at it, store the times
00232                 setTime(KFileItem::ModificationTime, buf.st_mtime);
00233                 setTime(KFileItem::AccessTime, buf.st_atime);
00234                 if ( m_fileMode == KFileItem::Unknown )
00235                     m_fileMode = mode & S_IFMT; // extract file type
00236                 if ( m_permissions == KFileItem::Unknown )
00237                     m_permissions = mode & 07777; // extract permissions
00238             } else {
00239                 kDebug() << path << "does not exist anymore";
00240             }
00241         }
00242     }
00243 }
00244 
00245 void KFileItemPrivate::readUDSEntry( bool _urlIsDirectory )
00246 {
00247     // extract fields from the KIO::UDS Entry
00248 
00249     m_fileMode = m_entry.numberValue( KIO::UDSEntry::UDS_FILE_TYPE );
00250     m_permissions = m_entry.numberValue( KIO::UDSEntry::UDS_ACCESS );
00251     m_strName = m_entry.stringValue( KIO::UDSEntry::UDS_NAME );
00252 
00253     const QString displayName = m_entry.stringValue( KIO::UDSEntry::UDS_DISPLAY_NAME );
00254     if (!displayName.isEmpty())
00255       m_strText = displayName;
00256     else
00257       m_strText = KIO::decodeFileName( m_strName );
00258 
00259     const QString urlStr = m_entry.stringValue( KIO::UDSEntry::UDS_URL );
00260     const bool UDS_URL_seen = !urlStr.isEmpty();
00261     if ( UDS_URL_seen ) {
00262         m_url = KUrl( urlStr );
00263         if ( m_url.isLocalFile() )
00264             m_bIsLocalUrl = true;
00265     }
00266     const QString mimeTypeStr = m_entry.stringValue( KIO::UDSEntry::UDS_MIME_TYPE );
00267     m_bMimeTypeKnown = !mimeTypeStr.isEmpty();
00268     if ( m_bMimeTypeKnown )
00269         m_pMimeType = KMimeType::mimeType( mimeTypeStr );
00270 
00271     m_guessedMimeType = m_entry.stringValue( KIO::UDSEntry::UDS_GUESSED_MIME_TYPE );
00272     m_bLink = !m_entry.stringValue( KIO::UDSEntry::UDS_LINK_DEST ).isEmpty(); // we don't store the link dest
00273 
00274     const int hiddenVal = m_entry.numberValue( KIO::UDSEntry::UDS_HIDDEN, -1 );
00275     m_hidden = hiddenVal == 1 ? Hidden : ( hiddenVal == 0 ? Shown : Auto );
00276 
00277     // avoid creating these QStrings again and again
00278     static const QString& dot = KGlobal::staticQString(".");
00279     if ( _urlIsDirectory && !UDS_URL_seen && !m_strName.isEmpty() && m_strName != dot )
00280         m_url.addPath( m_strName );
00281 
00282     m_iconName.clear();
00283 }
00284 
00285 inline //because it is used only in one place
00286 KIO::filesize_t KFileItemPrivate::size() const
00287 {
00288     // Extract it from the KIO::UDSEntry
00289     long long fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_SIZE, -1 );
00290     if ( fieldVal != -1 ) {
00291         return fieldVal;
00292     }
00293 
00294     // If not in the KIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL]
00295     if ( m_bIsLocalUrl ) {
00296         KDE_struct_stat buf;
00297         if ( KDE::stat( m_url.toLocalFile(KUrl::RemoveTrailingSlash), &buf ) == 0 )
00298             return buf.st_size;
00299     }
00300     return 0;
00301 }
00302 
00303 void KFileItemPrivate::setTime(KFileItem::FileTimes mappedWhich, long long time_t_val) const
00304 {
00305     m_time[mappedWhich].setTime_t(time_t_val);
00306     m_time[mappedWhich] = m_time[mappedWhich].toLocalZone(); // #160979
00307 }
00308 
00309 KDateTime KFileItemPrivate::time( KFileItem::FileTimes mappedWhich ) const
00310 {
00311     if ( !m_time[mappedWhich].isNull() )
00312         return m_time[mappedWhich];
00313 
00314     // Extract it from the KIO::UDSEntry
00315     long long fieldVal = -1;
00316     switch ( mappedWhich ) {
00317     case KFileItem::ModificationTime:
00318         fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_MODIFICATION_TIME, -1 );
00319         break;
00320     case KFileItem::AccessTime:
00321         fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_ACCESS_TIME, -1 );
00322         break;
00323     case KFileItem::CreationTime:
00324         fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_CREATION_TIME, -1 );
00325         break;
00326     }
00327     if ( fieldVal != -1 ) {
00328         setTime(mappedWhich, fieldVal);
00329         return m_time[mappedWhich];
00330     }
00331 
00332     // If not in the KIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL]
00333     if ( m_bIsLocalUrl )
00334     {
00335         KDE_struct_stat buf;
00336         if ( KDE::stat( m_url.toLocalFile(KUrl::RemoveTrailingSlash), &buf ) == 0 )
00337         {
00338             setTime(KFileItem::ModificationTime, buf.st_mtime);
00339             setTime(KFileItem::AccessTime, buf.st_atime);
00340             m_time[KFileItem::CreationTime] = KDateTime();
00341             return m_time[mappedWhich];
00342         }
00343     }
00344     return KDateTime();
00345 }
00346 
00347 inline //because it is used only in one place
00348 bool KFileItemPrivate::cmp( const KFileItemPrivate & item ) const
00349 {
00350 #if 0
00351     kDebug() << "Comparing" << m_url << "and" << item.m_url;
00352     kDebug() << " name" << (m_strName == item.m_strName);
00353     kDebug() << " local" << (m_bIsLocalUrl == item.m_bIsLocalUrl);
00354     kDebug() << " mode" << (m_fileMode == item.m_fileMode);
00355     kDebug() << " perm" << (m_permissions == item.m_permissions);
00356     kDebug() << " UDS_USER" << (user() == item.user());
00357     kDebug() << " UDS_GROUP" << (group() == item.group());
00358     kDebug() << " UDS_EXTENDED_ACL" << (m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL ));
00359     kDebug() << " UDS_ACL_STRING" << (m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ));
00360     kDebug() << " UDS_DEFAULT_ACL_STRING" << (m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING ));
00361     kDebug() << " m_bLink" << (m_bLink == item.m_bLink);
00362     kDebug() << " m_hidden" << (m_hidden == item.m_hidden);
00363     kDebug() << " size" << (size() == item.size());
00364     kDebug() << " ModificationTime" << (time(KFileItem::ModificationTime) == item.time(KFileItem::ModificationTime));
00365     kDebug() << " UDS_ICON_NAME" << (m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ));
00366 #endif
00367     return ( m_strName == item.m_strName
00368              && m_bIsLocalUrl == item.m_bIsLocalUrl
00369              && m_fileMode == item.m_fileMode
00370              && m_permissions == item.m_permissions
00371              && user() == item.user()
00372              && group() == item.group()
00373              && m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL )
00374              && m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING )
00375              && m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING )
00376              && m_bLink == item.m_bLink
00377              && m_hidden == item.m_hidden
00378              && size() == item.size()
00379              && time(KFileItem::ModificationTime) == item.time(KFileItem::ModificationTime)
00380              && m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME )
00381         );
00382 
00383     // Don't compare the mimetypes here. They might not be known, and we don't want to
00384     // do the slow operation of determining them here.
00385 }
00386 
00387 inline //because it is used only in one place
00388 QString KFileItemPrivate::parsePermissions(mode_t perm) const
00389 {
00390     static char buffer[ 12 ];
00391 
00392     char uxbit,gxbit,oxbit;
00393 
00394     if ( (perm & (S_IXUSR|S_ISUID)) == (S_IXUSR|S_ISUID) )
00395         uxbit = 's';
00396     else if ( (perm & (S_IXUSR|S_ISUID)) == S_ISUID )
00397         uxbit = 'S';
00398     else if ( (perm & (S_IXUSR|S_ISUID)) == S_IXUSR )
00399         uxbit = 'x';
00400     else
00401         uxbit = '-';
00402 
00403     if ( (perm & (S_IXGRP|S_ISGID)) == (S_IXGRP|S_ISGID) )
00404         gxbit = 's';
00405     else if ( (perm & (S_IXGRP|S_ISGID)) == S_ISGID )
00406         gxbit = 'S';
00407     else if ( (perm & (S_IXGRP|S_ISGID)) == S_IXGRP )
00408         gxbit = 'x';
00409     else
00410         gxbit = '-';
00411 
00412     if ( (perm & (S_IXOTH|S_ISVTX)) == (S_IXOTH|S_ISVTX) )
00413         oxbit = 't';
00414     else if ( (perm & (S_IXOTH|S_ISVTX)) == S_ISVTX )
00415         oxbit = 'T';
00416     else if ( (perm & (S_IXOTH|S_ISVTX)) == S_IXOTH )
00417         oxbit = 'x';
00418     else
00419         oxbit = '-';
00420 
00421     // Include the type in the first char like kde3 did; people are more used to seeing it,
00422     // even though it's not really part of the permissions per se.
00423     if (m_bLink)
00424         buffer[0] = 'l';
00425     else if (m_fileMode != KFileItem::Unknown) {
00426         if (S_ISDIR(m_fileMode))
00427             buffer[0] = 'd';
00428         else if (S_ISSOCK(m_fileMode))
00429             buffer[0] = 's';
00430         else if (S_ISCHR(m_fileMode))
00431             buffer[0] = 'c';
00432         else if (S_ISBLK(m_fileMode))
00433             buffer[0] = 'b';
00434         else if (S_ISFIFO(m_fileMode))
00435             buffer[0] = 'p';
00436         else
00437             buffer[0] = '-';
00438     } else {
00439         buffer[0] = '-';
00440     }
00441 
00442     buffer[1] = ((( perm & S_IRUSR ) == S_IRUSR ) ? 'r' : '-' );
00443     buffer[2] = ((( perm & S_IWUSR ) == S_IWUSR ) ? 'w' : '-' );
00444     buffer[3] = uxbit;
00445     buffer[4] = ((( perm & S_IRGRP ) == S_IRGRP ) ? 'r' : '-' );
00446     buffer[5] = ((( perm & S_IWGRP ) == S_IWGRP ) ? 'w' : '-' );
00447     buffer[6] = gxbit;
00448     buffer[7] = ((( perm & S_IROTH ) == S_IROTH ) ? 'r' : '-' );
00449     buffer[8] = ((( perm & S_IWOTH ) == S_IWOTH ) ? 'w' : '-' );
00450     buffer[9] = oxbit;
00451     // if (hasExtendedACL())
00452     if (m_entry.contains(KIO::UDSEntry::UDS_EXTENDED_ACL)) {
00453         buffer[10] = '+';
00454         buffer[11] = 0;
00455     } else {
00456         buffer[10] = 0;
00457     }
00458 
00459     return QString::fromLatin1(buffer);
00460 }
00461 
00462 
00464 
00465 KFileItem::KFileItem()
00466     : d(0)
00467 {
00468 }
00469 
00470 KFileItem::KFileItem( const KIO::UDSEntry& entry, const KUrl& itemOrDirUrl,
00471                       bool delayedMimeTypes, bool urlIsDirectory )
00472     : d(new KFileItemPrivate(entry, KFileItem::Unknown, KFileItem::Unknown,
00473                              itemOrDirUrl, urlIsDirectory, delayedMimeTypes))
00474 {
00475 }
00476 
00477 KFileItem::KFileItem( mode_t mode, mode_t permissions, const KUrl& url, bool delayedMimeTypes )
00478     : d(new KFileItemPrivate(KIO::UDSEntry(), mode, permissions,
00479                              url, false, delayedMimeTypes))
00480 {
00481 }
00482 
00483 KFileItem::KFileItem( const KUrl &url, const QString &mimeType, mode_t mode )
00484     : d(new KFileItemPrivate(KIO::UDSEntry(), mode, KFileItem::Unknown,
00485                              url, false, false))
00486 {
00487     d->m_bMimeTypeKnown = !mimeType.isEmpty();
00488     if (d->m_bMimeTypeKnown)
00489         d->m_pMimeType = KMimeType::mimeType( mimeType );
00490 }
00491 
00492 
00493 KFileItem::KFileItem(const KFileItem& other)
00494     : d(other.d)
00495 {
00496 }
00497 
00498 KFileItem::~KFileItem()
00499 {
00500 }
00501 
00502 void KFileItem::refresh()
00503 {
00504     d->m_fileMode = KFileItem::Unknown;
00505     d->m_permissions = KFileItem::Unknown;
00506     d->m_metaInfo = KFileMetaInfo();
00507     d->m_hidden = KFileItemPrivate::Auto;
00508     refreshMimeType();
00509 
00510     // Basically, we can't trust any information we got while listing.
00511     // Everything could have changed...
00512     // Clearing m_entry makes it possible to detect changes in the size of the file,
00513     // the time information, etc.
00514     d->m_entry.clear();
00515     d->init();
00516 }
00517 
00518 void KFileItem::refreshMimeType()
00519 {
00520     d->m_pMimeType = 0;
00521     d->m_bMimeTypeKnown = false;
00522     d->m_iconName.clear();
00523 }
00524 
00525 void KFileItem::setUrl( const KUrl &url )
00526 {
00527     d->m_url = url;
00528     setName( url.fileName() );
00529 }
00530 
00531 void KFileItem::setName( const QString& name )
00532 {
00533     d->m_strName = name;
00534     d->m_strText = KIO::decodeFileName( d->m_strName );
00535     if (d->m_entry.contains(KIO::UDSEntry::UDS_NAME))
00536         d->m_entry.insert(KIO::UDSEntry::UDS_NAME, d->m_strName); // #195385
00537 
00538 }
00539 
00540 QString KFileItem::linkDest() const
00541 {
00542     // Extract it from the KIO::UDSEntry
00543     const QString linkStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_LINK_DEST );
00544     if ( !linkStr.isEmpty() )
00545         return linkStr;
00546 
00547     // If not in the KIO::UDSEntry, or if UDSEntry empty, use readlink() [if local URL]
00548     if ( d->m_bIsLocalUrl )
00549     {
00550         char buf[1000];
00551         int n = readlink( QFile::encodeName(d->m_url.toLocalFile( KUrl::RemoveTrailingSlash )), buf, sizeof(buf)-1 );
00552         if ( n != -1 )
00553         {
00554             buf[ n ] = 0;
00555             return QFile::decodeName( buf );
00556         }
00557     }
00558     return QString();
00559 }
00560 
00561 QString KFileItem::localPath() const
00562 {
00563   if ( d->m_bIsLocalUrl ) {
00564     return d->m_url.toLocalFile();
00565   }
00566 
00567   // Extract the local path from the KIO::UDSEntry
00568   return d->m_entry.stringValue( KIO::UDSEntry::UDS_LOCAL_PATH );
00569 }
00570 
00571 KIO::filesize_t KFileItem::size() const
00572 {
00573     return d->size();
00574 }
00575 
00576 bool KFileItem::hasExtendedACL() const
00577 {
00578     // Check if the field exists; its value doesn't matter
00579     return d->m_entry.contains(KIO::UDSEntry::UDS_EXTENDED_ACL);
00580 }
00581 
00582 KACL KFileItem::ACL() const
00583 {
00584     if ( hasExtendedACL() ) {
00585         // Extract it from the KIO::UDSEntry
00586         const QString fieldVal = d->m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING );
00587         if ( !fieldVal.isEmpty() )
00588             return KACL( fieldVal );
00589     }
00590     // create one from the basic permissions
00591     return KACL( d->m_permissions );
00592 }
00593 
00594 KACL KFileItem::defaultACL() const
00595 {
00596     // Extract it from the KIO::UDSEntry
00597     const QString fieldVal = d->m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING );
00598     if ( !fieldVal.isEmpty() )
00599         return KACL(fieldVal);
00600     else
00601         return KACL();
00602 }
00603 
00604 KDateTime KFileItem::time( FileTimes which ) const
00605 {
00606     return d->time(which);
00607 }
00608 
00609 time_t KFileItem::time( unsigned int which ) const
00610 {
00611     switch (which) {
00612     case KIO::UDSEntry::UDS_ACCESS_TIME:
00613         return d->time(AccessTime).toTime_t();
00614     case KIO::UDSEntry::UDS_CREATION_TIME:
00615         return d->time(CreationTime).toTime_t();
00616     case KIO::UDSEntry::UDS_MODIFICATION_TIME:
00617     default:
00618         return d->time(ModificationTime).toTime_t();
00619     }
00620 }
00621 
00622 QString KFileItem::user() const
00623 {
00624     return d->user();
00625 }
00626 
00627 QString KFileItemPrivate::user() const
00628 {
00629     QString userName = m_entry.stringValue(KIO::UDSEntry::UDS_USER);
00630     if (userName.isEmpty() && m_bIsLocalUrl) {
00631 #ifdef Q_WS_WIN
00632         QFileInfo a(m_url.toLocalFile( KUrl::RemoveTrailingSlash ));
00633         userName = a.owner();
00634         m_entry.insert( KIO::UDSEntry::UDS_USER, userName );
00635 #else
00636         KDE_struct_stat buff;
00637         if ( KDE::lstat( m_url.toLocalFile( KUrl::RemoveTrailingSlash ), &buff ) == 0) // get uid/gid of the link, if it's a link
00638         {
00639             struct passwd *pwuser = getpwuid( buff.st_uid );
00640             if ( pwuser != 0 ) {
00641                 userName = QString::fromLocal8Bit(pwuser->pw_name);
00642                 m_entry.insert( KIO::UDSEntry::UDS_USER, userName );
00643             }
00644         }
00645 #endif
00646     }
00647     return userName;
00648 }
00649 
00650 QString KFileItem::group() const
00651 {
00652     return d->group();
00653 }
00654 
00655 QString KFileItemPrivate::group() const
00656 {
00657     QString groupName = m_entry.stringValue( KIO::UDSEntry::UDS_GROUP );
00658     if (groupName.isEmpty() && m_bIsLocalUrl )
00659     {
00660 #ifdef Q_WS_WIN
00661         QFileInfo a(m_url.toLocalFile( KUrl::RemoveTrailingSlash ));
00662         groupName = a.group();
00663         m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName );
00664 #else
00665         KDE_struct_stat buff;
00666         if ( KDE::lstat( m_url.toLocalFile( KUrl::RemoveTrailingSlash ), &buff ) == 0) // get uid/gid of the link, if it's a link
00667         {
00668             struct group *ge = getgrgid( buff.st_gid );
00669             if ( ge != 0 ) {
00670                 groupName = QString::fromLocal8Bit(ge->gr_name);
00671                 if (groupName.isEmpty())
00672                     groupName.sprintf("%d",ge->gr_gid);
00673             }
00674             else
00675                 groupName.sprintf("%d",buff.st_gid);
00676             m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName );
00677         }
00678 #endif
00679     }
00680     return groupName;
00681 }
00682 
00683 QString KFileItem::mimetype() const
00684 {
00685     KFileItem * that = const_cast<KFileItem *>(this);
00686     return that->determineMimeType()->name();
00687 }
00688 
00689 KMimeType::Ptr KFileItem::determineMimeType() const
00690 {
00691     if ( !d->m_pMimeType || !d->m_bMimeTypeKnown )
00692     {
00693         bool isLocalUrl;
00694         KUrl url = mostLocalUrl(isLocalUrl);
00695 
00696         d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl );
00697         Q_ASSERT(d->m_pMimeType);
00698         //kDebug() << d << "finding final mimetype for" << url << ":" << d->m_pMimeType->name();
00699         d->m_bMimeTypeKnown = true;
00700     }
00701 
00702     return d->m_pMimeType;
00703 }
00704 
00705 bool KFileItem::isMimeTypeKnown() const
00706 {
00707     // The mimetype isn't known if determineMimeType was never called (on-demand determination)
00708     // or if this fileitem has a guessed mimetype (e.g. ftp symlink) - in which case
00709     // it always remains "not fully determined"
00710     return d->m_bMimeTypeKnown && d->m_guessedMimeType.isEmpty();
00711 }
00712 
00713 QString KFileItem::mimeComment() const
00714 {
00715     KMimeType::Ptr mType = determineMimeType();
00716 
00717     bool isLocalUrl;
00718     KUrl url = mostLocalUrl(isLocalUrl);
00719 
00720     KMimeType::Ptr mime = mimeTypePtr();
00721     if (isLocalUrl && mime->is("application/x-desktop")) {
00722         KDesktopFile cfg( url.toLocalFile() );
00723         QString comment = cfg.desktopGroup().readEntry( "Comment" );
00724         if (!comment.isEmpty())
00725             return comment;
00726     }
00727 
00728     QString comment = mType->comment( url );
00729     //kDebug() << "finding comment for " << url.url() << " : " << d->m_pMimeType->name();
00730     if (!comment.isEmpty())
00731         return comment;
00732     else
00733         return mType->name();
00734 }
00735 
00736 static QString iconFromDesktopFile(const QString& path)
00737 {
00738     KDesktopFile cfg( path );
00739     const KConfigGroup group = cfg.desktopGroup();
00740     const QString icon = cfg.readIcon();
00741     const QString type = cfg.readPath();
00742 
00743     if ( cfg.hasDeviceType() )
00744     {
00745         const QString unmount_icon = group.readEntry( "UnmountIcon" );
00746         const QString dev = cfg.readDevice();
00747         if ( !icon.isEmpty() && !unmount_icon.isEmpty() && !dev.isEmpty() )
00748         {
00749             KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByDevice(dev);
00750             if (!mountPoint) // not mounted?
00751                 return unmount_icon;
00752         }
00753     } else if ( cfg.hasLinkType() ) {
00754         const QString emptyIcon = group.readEntry( "EmptyIcon" );
00755         if ( !emptyIcon.isEmpty() ) {
00756             const QString u = cfg.readUrl();
00757             const KUrl url( u );
00758             if ( url.protocol() == "trash" ) {
00759                 // We need to find if the trash is empty, preferrably without using a KIO job.
00760                 // So instead kio_trash leaves an entry in its config file for us.
00761                 KConfig trashConfig( "trashrc", KConfig::SimpleConfig );
00762                 if ( trashConfig.group("Status").readEntry( "Empty", true ) ) {
00763                     return emptyIcon;
00764                 }
00765             }
00766         }
00767     }
00768     return icon;
00769 }
00770 
00771 QString KFileItem::iconName() const
00772 {
00773     if (d->m_useIconNameCache && !d->m_iconName.isEmpty()) {
00774         return d->m_iconName;
00775     }
00776 
00777     d->m_iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME );
00778     if (!d->m_iconName.isEmpty()) {
00779         d->m_useIconNameCache = d->m_bMimeTypeKnown;
00780         return d->m_iconName;
00781     }
00782 
00783     bool isLocalUrl;
00784     KUrl url = mostLocalUrl(isLocalUrl);
00785 
00786     KMimeType::Ptr mime = mimeTypePtr();
00787     if (isLocalUrl && mime->is("application/x-desktop")) {
00788         d->m_iconName = iconFromDesktopFile(url.toLocalFile());
00789         if (!d->m_iconName.isEmpty()) {
00790             d->m_useIconNameCache = d->m_bMimeTypeKnown;
00791             return d->m_iconName;
00792         }
00793     }
00794 
00795     // KDE5: handle .directory files here too, and get rid of
00796     // KFolderMimeType and the url argument in KMimeType::iconName().
00797 
00798     d->m_iconName = mime->iconName(url);
00799     d->m_useIconNameCache = d->m_bMimeTypeKnown;
00800     //kDebug() << "finding icon for" << url << ":" << d->m_iconName;
00801     return d->m_iconName;
00802 }
00803 
00804 QStringList KFileItem::overlays() const
00805 {
00806     QStringList names;
00807     if ( d->m_bLink ) {
00808         names.append("emblem-symbolic-link");
00809     }
00810 
00811     if ( !S_ISDIR( d->m_fileMode ) // Locked dirs have a special icon, use the overlay for files only
00812          && !isReadable()) {
00813         names.append("object-locked");
00814     }
00815 
00816     if ( isDesktopFile() ) {
00817         KDesktopFile cfg( localPath() );
00818         const KConfigGroup group = cfg.desktopGroup();
00819 
00820         // Add a warning emblem if this is an executable desktop file
00821         // which is untrusted.
00822         if ( group.hasKey( "Exec" ) && !KDesktopFile::isAuthorizedDesktopFile( localPath() ) ) {
00823             names.append( "emblem-important" );
00824         }
00825     }
00826 
00827     if ( isHidden() ) {
00828         names.append("hidden");
00829     }
00830 
00831 #ifndef Q_OS_WIN
00832     if( S_ISDIR( d->m_fileMode ) && d->m_bIsLocalUrl)
00833     {
00834         if (KSambaShare::instance()->isDirectoryShared( d->m_url.toLocalFile() ) ||
00835             KNFSShare::instance()->isDirectoryShared( d->m_url.toLocalFile() ))
00836         {
00837             //kDebug() << d->m_url.path();
00838             names.append("network-workgroup");
00839         }
00840     }
00841 #endif  // Q_OS_WIN
00842 
00843     if ( d->m_pMimeType && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) &&
00844          d->m_pMimeType->is("application/x-gzip") ) {
00845         names.append("application-zip");
00846     }
00847 
00848     return names;
00849 }
00850 
00851 // ## where is this used?
00852 QPixmap KFileItem::pixmap( int _size, int _state ) const
00853 {
00854     const QString iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME );
00855     if ( !iconName.isEmpty() )
00856         return DesktopIcon(iconName, _size, _state);
00857 
00858     if (!d->m_pMimeType) {
00859         // No mimetype determined yet, go for a fast default icon
00860         if (S_ISDIR(d->m_fileMode)) {
00861             static const QString * defaultFolderIcon = 0;
00862             if ( !defaultFolderIcon ) {
00863                 const KMimeType::Ptr mimeType = KMimeType::mimeType( "inode/directory" );
00864                 if ( mimeType )
00865                     defaultFolderIcon = &KGlobal::staticQString( mimeType->iconName() );
00866                else
00867                     kWarning(7000) << "No mimetype for inode/directory could be found. Check your installation.";
00868             }
00869             if ( defaultFolderIcon )
00870                 return DesktopIcon( *defaultFolderIcon, _size, _state );
00871 
00872         }
00873         return DesktopIcon( "unknown", _size, _state );
00874     }
00875 
00876     KMimeType::Ptr mime;
00877     // Use guessed mimetype if the main one hasn't been determined for sure
00878     if ( !d->m_bMimeTypeKnown && !d->m_guessedMimeType.isEmpty() )
00879         mime = KMimeType::mimeType( d->m_guessedMimeType );
00880     else
00881         mime = d->m_pMimeType;
00882 
00883     // Support for gzipped files: extract mimetype of contained file
00884     // See also the relevant code in overlays, which adds the zip overlay.
00885     if ( mime->name() == "application/x-gzip" && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) )
00886     {
00887         KUrl sf;
00888         sf.setPath( d->m_url.path().left( d->m_url.path().length() - 3 ) );
00889         //kDebug() << "subFileName=" << subFileName;
00890         mime = KMimeType::findByUrl( sf, 0, d->m_bIsLocalUrl );
00891     }
00892 
00893     bool isLocalUrl;
00894     KUrl url = mostLocalUrl(isLocalUrl);
00895 
00896     QPixmap p = KIconLoader::global()->loadMimeTypeIcon( mime->iconName( url ), KIconLoader::Desktop, _size, _state );
00897     //kDebug() << "finding pixmap for " << url.url() << " : " << mime->name();
00898     if (p.isNull())
00899         kWarning() << "Pixmap not found for mimetype " << d->m_pMimeType->name();
00900 
00901     return p;
00902 }
00903 
00904 bool KFileItem::isReadable() const
00905 {
00906     /*
00907       struct passwd * user = getpwuid( geteuid() );
00908       bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user);
00909       // This gets ugly for the group....
00910       // Maybe we want a static QString for the user and a static QStringList
00911       // for the groups... then we need to handle the deletion properly...
00912       */
00913 
00914     if (d->m_permissions != KFileItem::Unknown) {
00915         // No read permission at all
00916         if ( !(S_IRUSR & d->m_permissions) && !(S_IRGRP & d->m_permissions) && !(S_IROTH & d->m_permissions) )
00917             return false;
00918 
00919         // Read permissions for all: save a stat call
00920         if ( (S_IRUSR|S_IRGRP|S_IROTH) & d->m_permissions )
00921             return true;
00922     }
00923 
00924     // Or if we can't read it [using ::access()] - not network transparent
00925     if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), R_OK ) == -1 )
00926         return false;
00927 
00928     return true;
00929 }
00930 
00931 bool KFileItem::isWritable() const
00932 {
00933     /*
00934       struct passwd * user = getpwuid( geteuid() );
00935       bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user);
00936       // This gets ugly for the group....
00937       // Maybe we want a static QString for the user and a static QStringList
00938       // for the groups... then we need to handle the deletion properly...
00939       */
00940 
00941     if (d->m_permissions != KFileItem::Unknown) {
00942         // No write permission at all
00943         if ( !(S_IWUSR & d->m_permissions) && !(S_IWGRP & d->m_permissions) && !(S_IWOTH & d->m_permissions) )
00944             return false;
00945     }
00946 
00947     // Or if we can't read it [using ::access()] - not network transparent
00948     if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), W_OK ) == -1 )
00949         return false;
00950 
00951     return true;
00952 }
00953 
00954 bool KFileItem::isHidden() const
00955 {
00956     // The kioslave can specify explicitly that a file is hidden or shown
00957     if ( d->m_hidden != KFileItemPrivate::Auto )
00958         return d->m_hidden == KFileItemPrivate::Hidden;
00959 
00960     // Prefer the filename that is part of the URL, in case the display name is different.
00961     QString fileName = d->m_url.fileName();
00962     if (fileName.isEmpty()) // e.g. "trash:/"
00963         fileName = d->m_strName;
00964     return fileName.length() > 1 && fileName[0] == '.';  // Just "." is current directory, not hidden.
00965 }
00966 
00967 bool KFileItem::isDir() const
00968 {
00969     if (d->m_fileMode == KFileItem::Unknown) {
00970         // Probably the file was deleted already, and KDirLister hasn't told the world yet.
00971         //kDebug() << d << url() << "can't say -> false";
00972         return false; // can't say for sure, so no
00973     }
00974     return (S_ISDIR(d->m_fileMode));
00975 }
00976 
00977 bool KFileItem::isFile() const
00978 {
00979     return !isDir();
00980 }
00981 
00982 bool KFileItem::acceptsDrops() const
00983 {
00984     // A directory ?
00985     if ( S_ISDIR( mode() ) ) {
00986         return isWritable();
00987     }
00988 
00989     // But only local .desktop files and executables
00990     if ( !d->m_bIsLocalUrl )
00991         return false;
00992 
00993     if ( mimetype() == "application/x-desktop")
00994         return true;
00995 
00996     // Executable, shell script ... ?
00997     if ( QFileInfo(d->m_url.toLocalFile()).isExecutable() )
00998         return true;
00999 
01000     return false;
01001 }
01002 
01003 QString KFileItem::getStatusBarInfo() const
01004 {
01005     QString text = d->m_strText;
01006     const QString comment = mimeComment();
01007 
01008     if ( d->m_bLink )
01009     {
01010         text += ' ';
01011         if ( comment.isEmpty() )
01012             text += i18n ( "(Symbolic Link to %1)", linkDest() );
01013         else
01014             text += i18n("(%1, Link to %2)", comment, linkDest());
01015     }
01016     else if ( targetUrl() != url() )
01017     {
01018         text += i18n ( " (Points to %1)", targetUrl().pathOrUrl());
01019     }
01020     else if ( S_ISREG( d->m_fileMode ) )
01021     {
01022         text += QString(" (%1, %2)").arg( comment, KIO::convertSize( size() ) );
01023     }
01024     else
01025     {
01026         text += QString(" (%1)").arg( comment );
01027     }
01028     return text;
01029 }
01030 
01031 QString KFileItem::getToolTipText(int maxcount) const
01032 {
01033     // we can return QString() if no tool tip should be shown
01034     QString tip;
01035     KFileMetaInfo info = metaInfo();
01036 
01037     // the font tags are a workaround for the fact that the tool tip gets
01038     // screwed if the color scheme uses white as default text color
01039     const QString colorName = QApplication::palette().color(QPalette::ToolTipText).name();
01040     const QString start = "<tr><td align=\"right\"><nobr><font color=\"" + colorName + "\"><b>";
01041     const QString mid = "&nbsp;</b></font></nobr></td><td><nobr><font color=\"" + colorName + "\">";
01042     const char* end = "</font></nobr></td></tr>";
01043 
01044     tip = "<table cellspacing=0 cellpadding=0>";
01045 
01046     tip += start + i18n("Name:") + mid + text() + end;
01047     tip += start + i18n("Type:") + mid;
01048 
01049     QString type = Qt::escape(mimeComment());
01050     if ( d->m_bLink ) {
01051         tip += i18n("Link to %1 (%2)", linkDest(), type) + end;
01052     } else
01053         tip += type + end;
01054 
01055     if ( !S_ISDIR ( d->m_fileMode ) )
01056         tip += start + i18n("Size:") + mid +
01057                QString("%1").arg(KIO::convertSize(size())) +
01058                end;
01059 
01060     tip += start + i18n("Modified:") + mid +
01061            timeString( KFileItem::ModificationTime ) + end
01062 #ifndef Q_WS_WIN //TODO: show win32-specific permissions
01063            +start + i18n("Owner:") + mid + user() + " - " + group() + end +
01064            start + i18n("Permissions:") + mid +
01065            permissionsString() + end
01066 #endif
01067            ;
01068 
01069     if (info.isValid())
01070     {
01071         const QStringList keys = info.preferredKeys();
01072 
01073         // now the rest
01074         QStringList::ConstIterator it = keys.begin();
01075         for (int count = 0; count<maxcount && it!=keys.end() ; ++it)
01076         {
01077             if ( count == 0 )
01078             {
01079                 tip += "<tr><td colspan=2><center><s>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</s></center></td></tr>";
01080             }
01081 
01082             KFileMetaInfoItem item = info.item( *it );
01083             if ( item.isValid() )
01084             {
01085                 QString s = item.value().toString();
01086                 if ( ( item.properties().attributes() & PredicateProperties::SqueezeText )
01087                      && s.length() > 50) {
01088                     s.truncate(47);
01089                     s.append("...");
01090                 }
01091                 if ( !s.isEmpty() )
01092                 {
01093                     count++;
01094                     tip += start +
01095                            Qt::escape( item.name() ) + ':' +
01096                            mid +
01097                            Qt::escape( s ) +
01098                            end;
01099                 }
01100 
01101             }
01102         }
01103     }
01104     tip += "</table>";
01105 
01106     //kDebug() << "making this the tool tip rich text:\n";
01107     //kDebug() << tip;
01108 
01109     return tip;
01110 }
01111 
01112 void KFileItem::run( QWidget* parentWidget ) const
01113 {
01114     (void) new KRun( targetUrl(), parentWidget, d->m_fileMode, d->m_bIsLocalUrl );
01115 }
01116 
01117 bool KFileItem::cmp( const KFileItem & item ) const
01118 {
01119     return d->cmp(*item.d);
01120 }
01121 
01122 bool KFileItem::operator==(const KFileItem& other) const
01123 {
01124     // is this enough?
01125     return d == other.d;
01126 }
01127 
01128 bool KFileItem::operator!=(const KFileItem& other) const
01129 {
01130     return d != other.d;
01131 }
01132 
01133 void KFileItem::setUDSEntry( const KIO::UDSEntry& _entry, const KUrl& _url,
01134                              bool _delayedMimeTypes, bool _urlIsDirectory )
01135 {
01136     d->m_entry = _entry;
01137     d->m_url = _url;
01138     d->m_strName.clear();
01139     d->m_strText.clear();
01140     d->m_iconName.clear();
01141     d->m_strLowerCaseName.clear();
01142     d->m_pMimeType = 0;
01143     d->m_fileMode = KFileItem::Unknown;
01144     d->m_permissions = KFileItem::Unknown;
01145     d->m_bMarked = false;
01146     d->m_bLink = false;
01147     d->m_bIsLocalUrl = _url.isLocalFile();
01148     d->m_bMimeTypeKnown = false;
01149     d->m_hidden = KFileItemPrivate::Auto;
01150     d->m_guessedMimeType.clear();
01151     d->m_metaInfo = KFileMetaInfo();
01152     d->m_delayedMimeTypes = _delayedMimeTypes;
01153     d->m_useIconNameCache = false;
01154 
01155     d->readUDSEntry( _urlIsDirectory );
01156     d->init();
01157 }
01158 
01159 KFileItem::operator QVariant() const
01160 {
01161     return qVariantFromValue(*this);
01162 }
01163 
01164 void KFileItem::setExtraData( const void *key, void *value )
01165 {
01166     if ( !key )
01167         return;
01168 
01169     d->m_extra.insert( key, value ); // replaces the value of key if already there
01170 }
01171 
01172 const void * KFileItem::extraData( const void *key ) const
01173 {
01174     return d->m_extra.value( key, 0 );
01175 }
01176 
01177 void KFileItem::removeExtraData( const void *key )
01178 {
01179     d->m_extra.remove( key );
01180 }
01181 
01182 QString KFileItem::permissionsString() const
01183 {
01184     if (d->m_access.isNull() && d->m_permissions != KFileItem::Unknown)
01185         d->m_access = d->parsePermissions( d->m_permissions );
01186 
01187     return d->m_access;
01188 }
01189 
01190 // check if we need to cache this
01191 QString KFileItem::timeString( FileTimes which ) const
01192 {
01193     return KGlobal::locale()->formatDateTime( d->time(which) );
01194 }
01195 
01196 QString KFileItem::timeString( unsigned int which ) const
01197 {
01198     switch (which) {
01199     case KIO::UDSEntry::UDS_ACCESS_TIME:
01200         return timeString(AccessTime);
01201     case KIO::UDSEntry::UDS_CREATION_TIME:
01202         return timeString(CreationTime);
01203     case KIO::UDSEntry::UDS_MODIFICATION_TIME:
01204     default:
01205         return timeString(ModificationTime);
01206     }
01207 }
01208 
01209 void KFileItem::setMetaInfo( const KFileMetaInfo & info ) const
01210 {
01211     d->m_metaInfo = info;
01212 }
01213 
01214 KFileMetaInfo KFileItem::metaInfo(bool autoget, int) const
01215 {
01216     if ((isRegularFile() || isDir()) && autoget && !d->m_metaInfo.isValid())
01217     {
01218         bool isLocalUrl;
01219         KUrl url(mostLocalUrl(isLocalUrl));
01220         d->m_metaInfo = KFileMetaInfo(url);//, mimetype() );
01221     }
01222     return d->m_metaInfo;
01223 }
01224 
01225 void KFileItem::assign( const KFileItem & item )
01226 {
01227     *this = item;
01228 }
01229 
01230 KUrl KFileItem::mostLocalUrl(bool &local) const
01231 {
01232     QString local_path = localPath();
01233 
01234     if ( !local_path.isEmpty() )
01235     {
01236         local = true;
01237         KUrl url;
01238         url.setPath(local_path);
01239         return url;
01240     }
01241     else
01242     {
01243         local = d->m_bIsLocalUrl;
01244         return d->m_url;
01245     }
01246 }
01247 
01248 QDataStream & operator<< ( QDataStream & s, const KFileItem & a )
01249 {
01250     // We don't need to save/restore anything that refresh() invalidates,
01251     // since that means we can re-determine those by ourselves.
01252     s << a.d->m_url;
01253     s << a.d->m_strName;
01254     s << a.d->m_strText;
01255     return s;
01256 }
01257 
01258 QDataStream & operator>> ( QDataStream & s, KFileItem & a )
01259 {
01260     s >> a.d->m_url;
01261     s >> a.d->m_strName;
01262     s >> a.d->m_strText;
01263     a.d->m_bIsLocalUrl = a.d->m_url.isLocalFile();
01264     a.d->m_bMimeTypeKnown = false;
01265     a.refresh();
01266     return s;
01267 }
01268 
01269 KUrl KFileItem::url() const
01270 {
01271     return d->m_url;
01272 }
01273 
01274 mode_t KFileItem::permissions() const
01275 {
01276     return d->m_permissions;
01277 }
01278 
01279 mode_t KFileItem::mode() const
01280 {
01281     return d->m_fileMode;
01282 }
01283 
01284 bool KFileItem::isLink() const
01285 {
01286     return d->m_bLink;
01287 }
01288 
01289 bool KFileItem::isLocalFile() const
01290 {
01291     return d->m_bIsLocalUrl;
01292 }
01293 
01294 QString KFileItem::text() const
01295 {
01296     return d->m_strText;
01297 }
01298 
01299 QString KFileItem::name( bool lowerCase ) const
01300 {
01301     if ( !lowerCase )
01302         return d->m_strName;
01303     else
01304         if ( d->m_strLowerCaseName.isNull() )
01305             d->m_strLowerCaseName = d->m_strName.toLower();
01306     return d->m_strLowerCaseName;
01307 }
01308 
01309 KUrl KFileItem::targetUrl() const
01310 {
01311     const QString targetUrlStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_TARGET_URL );
01312     if (!targetUrlStr.isEmpty())
01313       return KUrl(targetUrlStr);
01314     else
01315       return url();
01316 }
01317 
01318 /*
01319  * Mimetype handling.
01320  *
01321  * Initial state: m_pMimeType = 0.
01322  * When mimeTypePtr() is called first: fast mimetype determination,
01323  *   might either find an accurate mimetype (-> Final state), otherwise we
01324  *   set m_pMimeType but not m_bMimeTypeKnown (-> Intermediate state)
01325  * Intermediate state: determineMimeType() does the real determination -> Final state.
01326  *
01327  * If delayedMimeTypes isn't set, then we always go to the Final state directly.
01328  */
01329 
01330 KMimeType::Ptr KFileItem::mimeTypePtr() const
01331 {
01332     if (!d->m_pMimeType) {
01333         // On-demand fast (but not always accurate) mimetype determination
01334         Q_ASSERT(!d->m_url.isEmpty());
01335         bool isLocalUrl;
01336         KUrl url = mostLocalUrl(isLocalUrl);
01337         int accuracy;
01338         d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl,
01339                                                // use fast mode if delayed mimetype determination can refine it later
01340                                                d->m_delayedMimeTypes, &accuracy );
01341         // If we used the "fast mode" (no sniffing), and we didn't get a perfect (extension-based) match,
01342         // then determineMimeType will be able to do better.
01343         const bool canDoBetter = d->m_delayedMimeTypes && accuracy < 100;
01344         //kDebug() << "finding mimetype for" << url << ":" << d->m_pMimeType->name() << "canDoBetter=" << canDoBetter;
01345         d->m_bMimeTypeKnown = !canDoBetter;
01346     }
01347     return d->m_pMimeType;
01348 }
01349 
01350 KIO::UDSEntry KFileItem::entry() const
01351 {
01352     return d->m_entry;
01353 }
01354 
01355 bool KFileItem::isMarked() const
01356 {
01357     return d->m_bMarked;
01358 }
01359 
01360 void KFileItem::mark()
01361 {
01362     d->m_bMarked = true;
01363 }
01364 
01365 void KFileItem::unmark()
01366 {
01367     d->m_bMarked = false;
01368 }
01369 
01370 KFileItem& KFileItem::operator=(const KFileItem& other)
01371 {
01372     d = other.d;
01373     return *this;
01374 }
01375 
01376 bool KFileItem::isNull() const
01377 {
01378     return d == 0;
01379 }
01380 
01381 KFileItemList::KFileItemList()
01382 {
01383 }
01384 
01385 KFileItemList::KFileItemList( const QList<KFileItem> &items )
01386   : QList<KFileItem>( items )
01387 {
01388 }
01389 
01390 KFileItem KFileItemList::findByName( const QString& fileName ) const
01391 {
01392     const_iterator it = begin();
01393     const const_iterator itend = end();
01394     for ( ; it != itend ; ++it ) {
01395         if ( (*it).name() == fileName ) {
01396             return *it;
01397         }
01398     }
01399     return KFileItem();
01400 }
01401 
01402 KFileItem KFileItemList::findByUrl( const KUrl& url ) const {
01403     const_iterator it = begin();
01404     const const_iterator itend = end();
01405     for ( ; it != itend ; ++it ) {
01406         if ( (*it).url() == url ) {
01407             return *it;
01408         }
01409     }
01410     return KFileItem();
01411 }
01412 
01413 KUrl::List KFileItemList::urlList() const {
01414     KUrl::List lst;
01415     const_iterator it = begin();
01416     const const_iterator itend = end();
01417     for ( ; it != itend ; ++it ) {
01418         lst.append( (*it).url() );
01419     }
01420     return lst;
01421 }
01422 
01423 KUrl::List KFileItemList::targetUrlList() const {
01424     KUrl::List lst;
01425     const_iterator it = begin();
01426     const const_iterator itend = end();
01427     for ( ; it != itend ; ++it ) {
01428         lst.append( (*it).targetUrl() );
01429     }
01430     return lst;
01431 }
01432 
01433 bool KFileItem::isDesktopFile() const
01434 {
01435     // only local files
01436     bool isLocal;
01437     const KUrl url = mostLocalUrl(isLocal);
01438     if (!isLocal)
01439         return false;
01440 
01441     // only regular files
01442     if (!S_ISREG(d->m_fileMode))
01443         return false;
01444 
01445     // only if readable
01446     if (!isReadable())
01447         return false;
01448 
01449     // return true if desktop file
01450     return determineMimeType()->is("application/x-desktop");
01451 }
01452 
01453 bool KFileItem::isRegularFile() const
01454 {
01455     return S_ISREG(d->m_fileMode);
01456 }

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal