• Skip to content
  • Skip to link menu
KDE 4.4 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     const QString displayType = d->m_entry.stringValue( KIO::UDSEntry::UDS_DISPLAY_TYPE );
00716     if (!displayType.isEmpty())
00717         return displayType;
00718 
00719     KMimeType::Ptr mType = determineMimeType();
00720 
00721     bool isLocalUrl;
00722     KUrl url = mostLocalUrl(isLocalUrl);
00723 
00724     KMimeType::Ptr mime = mimeTypePtr();
00725     // This cannot move to kio_file (with UDS_DISPLAY_TYPE) because it needs
00726     // the mimetype to be determined, which is done here, and possibly delayed...
00727     if (isLocalUrl && mime->is("application/x-desktop")) {
00728         KDesktopFile cfg( url.toLocalFile() );
00729         QString comment = cfg.desktopGroup().readEntry( "Comment" );
00730         if (!comment.isEmpty())
00731             return comment;
00732     }
00733 
00734     QString comment = mType->comment( url );
00735     //kDebug() << "finding comment for " << url.url() << " : " << d->m_pMimeType->name();
00736     if (!comment.isEmpty())
00737         return comment;
00738     else
00739         return mType->name();
00740 }
00741 
00742 static QString iconFromDesktopFile(const QString& path)
00743 {
00744     KDesktopFile cfg( path );
00745     const KConfigGroup group = cfg.desktopGroup();
00746     const QString icon = cfg.readIcon();
00747     const QString type = cfg.readPath();
00748 
00749     if ( cfg.hasDeviceType() )
00750     {
00751         const QString unmount_icon = group.readEntry( "UnmountIcon" );
00752         const QString dev = cfg.readDevice();
00753         if ( !icon.isEmpty() && !unmount_icon.isEmpty() && !dev.isEmpty() )
00754         {
00755             KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByDevice(dev);
00756             if (!mountPoint) // not mounted?
00757                 return unmount_icon;
00758         }
00759     } else if ( cfg.hasLinkType() ) {
00760         const QString emptyIcon = group.readEntry( "EmptyIcon" );
00761         if ( !emptyIcon.isEmpty() ) {
00762             const QString u = cfg.readUrl();
00763             const KUrl url( u );
00764             if ( url.protocol() == "trash" ) {
00765                 // We need to find if the trash is empty, preferrably without using a KIO job.
00766                 // So instead kio_trash leaves an entry in its config file for us.
00767                 KConfig trashConfig( "trashrc", KConfig::SimpleConfig );
00768                 if ( trashConfig.group("Status").readEntry( "Empty", true ) ) {
00769                     return emptyIcon;
00770                 }
00771             }
00772         }
00773     }
00774     return icon;
00775 }
00776 
00777 QString KFileItem::iconName() const
00778 {
00779     if (d->m_useIconNameCache && !d->m_iconName.isEmpty()) {
00780         return d->m_iconName;
00781     }
00782 
00783     d->m_iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME );
00784     if (!d->m_iconName.isEmpty()) {
00785         d->m_useIconNameCache = d->m_bMimeTypeKnown;
00786         return d->m_iconName;
00787     }
00788 
00789     bool isLocalUrl;
00790     KUrl url = mostLocalUrl(isLocalUrl);
00791 
00792     KMimeType::Ptr mime = mimeTypePtr();
00793     if (isLocalUrl && mime->is("application/x-desktop")) {
00794         d->m_iconName = iconFromDesktopFile(url.toLocalFile());
00795         if (!d->m_iconName.isEmpty()) {
00796             d->m_useIconNameCache = d->m_bMimeTypeKnown;
00797             return d->m_iconName;
00798         }
00799     }
00800 
00801     // KDE5: handle .directory files here too, and get rid of
00802     // KFolderMimeType and the url argument in KMimeType::iconName().
00803 
00804     d->m_iconName = mime->iconName(url);
00805     d->m_useIconNameCache = d->m_bMimeTypeKnown;
00806     //kDebug() << "finding icon for" << url << ":" << d->m_iconName;
00807     return d->m_iconName;
00808 }
00809 
00810 QStringList KFileItem::overlays() const
00811 {
00812     QStringList names;
00813     if ( d->m_bLink ) {
00814         names.append("emblem-symbolic-link");
00815     }
00816 
00817     if ( !S_ISDIR( d->m_fileMode ) // Locked dirs have a special icon, use the overlay for files only
00818          && !isReadable()) {
00819         names.append("object-locked");
00820     }
00821 
00822     if ( isDesktopFile() ) {
00823         KDesktopFile cfg( localPath() );
00824         const KConfigGroup group = cfg.desktopGroup();
00825 
00826         // Add a warning emblem if this is an executable desktop file
00827         // which is untrusted.
00828         if ( group.hasKey( "Exec" ) && !KDesktopFile::isAuthorizedDesktopFile( localPath() ) ) {
00829             names.append( "emblem-important" );
00830         }
00831     }
00832 
00833     if ( isHidden() ) {
00834         names.append("hidden");
00835     }
00836 
00837 #ifndef Q_OS_WIN
00838     if( S_ISDIR( d->m_fileMode ) && d->m_bIsLocalUrl)
00839     {
00840         if (KSambaShare::instance()->isDirectoryShared( d->m_url.toLocalFile() ) ||
00841             KNFSShare::instance()->isDirectoryShared( d->m_url.toLocalFile() ))
00842         {
00843             //kDebug() << d->m_url.path();
00844             names.append("network-workgroup");
00845         }
00846     }
00847 #endif  // Q_OS_WIN
00848 
00849     if ( d->m_pMimeType && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) &&
00850          d->m_pMimeType->is("application/x-gzip") ) {
00851         names.append("application-zip");
00852     }
00853 
00854     return names;
00855 }
00856 
00857 // ## where is this used?
00858 QPixmap KFileItem::pixmap( int _size, int _state ) const
00859 {
00860     const QString iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME );
00861     if ( !iconName.isEmpty() )
00862         return DesktopIcon(iconName, _size, _state);
00863 
00864     if (!d->m_pMimeType) {
00865         // No mimetype determined yet, go for a fast default icon
00866         if (S_ISDIR(d->m_fileMode)) {
00867             static const QString * defaultFolderIcon = 0;
00868             if ( !defaultFolderIcon ) {
00869                 const KMimeType::Ptr mimeType = KMimeType::mimeType( "inode/directory" );
00870                 if ( mimeType )
00871                     defaultFolderIcon = &KGlobal::staticQString( mimeType->iconName() );
00872                else
00873                     kWarning(7000) << "No mimetype for inode/directory could be found. Check your installation.";
00874             }
00875             if ( defaultFolderIcon )
00876                 return DesktopIcon( *defaultFolderIcon, _size, _state );
00877 
00878         }
00879         return DesktopIcon( "unknown", _size, _state );
00880     }
00881 
00882     KMimeType::Ptr mime;
00883     // Use guessed mimetype if the main one hasn't been determined for sure
00884     if ( !d->m_bMimeTypeKnown && !d->m_guessedMimeType.isEmpty() )
00885         mime = KMimeType::mimeType( d->m_guessedMimeType );
00886     else
00887         mime = d->m_pMimeType;
00888 
00889     // Support for gzipped files: extract mimetype of contained file
00890     // See also the relevant code in overlays, which adds the zip overlay.
00891     if ( mime->name() == "application/x-gzip" && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) )
00892     {
00893         KUrl sf;
00894         sf.setPath( d->m_url.path().left( d->m_url.path().length() - 3 ) );
00895         //kDebug() << "subFileName=" << subFileName;
00896         mime = KMimeType::findByUrl( sf, 0, d->m_bIsLocalUrl );
00897     }
00898 
00899     bool isLocalUrl;
00900     KUrl url = mostLocalUrl(isLocalUrl);
00901 
00902     QPixmap p = KIconLoader::global()->loadMimeTypeIcon( mime->iconName( url ), KIconLoader::Desktop, _size, _state );
00903     //kDebug() << "finding pixmap for " << url.url() << " : " << mime->name();
00904     if (p.isNull())
00905         kWarning() << "Pixmap not found for mimetype " << d->m_pMimeType->name();
00906 
00907     return p;
00908 }
00909 
00910 bool KFileItem::isReadable() const
00911 {
00912     /*
00913       struct passwd * user = getpwuid( geteuid() );
00914       bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user);
00915       // This gets ugly for the group....
00916       // Maybe we want a static QString for the user and a static QStringList
00917       // for the groups... then we need to handle the deletion properly...
00918       */
00919 
00920     if (d->m_permissions != KFileItem::Unknown) {
00921         // No read permission at all
00922         if ( !(S_IRUSR & d->m_permissions) && !(S_IRGRP & d->m_permissions) && !(S_IROTH & d->m_permissions) )
00923             return false;
00924 
00925         // Read permissions for all: save a stat call
00926         if ( (S_IRUSR|S_IRGRP|S_IROTH) & d->m_permissions )
00927             return true;
00928     }
00929 
00930     // Or if we can't read it [using ::access()] - not network transparent
00931     if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), R_OK ) == -1 )
00932         return false;
00933 
00934     return true;
00935 }
00936 
00937 bool KFileItem::isWritable() const
00938 {
00939     /*
00940       struct passwd * user = getpwuid( geteuid() );
00941       bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user);
00942       // This gets ugly for the group....
00943       // Maybe we want a static QString for the user and a static QStringList
00944       // for the groups... then we need to handle the deletion properly...
00945       */
00946 
00947     if (d->m_permissions != KFileItem::Unknown) {
00948         // No write permission at all
00949         if ( !(S_IWUSR & d->m_permissions) && !(S_IWGRP & d->m_permissions) && !(S_IWOTH & d->m_permissions) )
00950             return false;
00951     }
00952 
00953     // Or if we can't read it [using ::access()] - not network transparent
00954     if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), W_OK ) == -1 )
00955         return false;
00956 
00957     return true;
00958 }
00959 
00960 bool KFileItem::isHidden() const
00961 {
00962     // The kioslave can specify explicitly that a file is hidden or shown
00963     if ( d->m_hidden != KFileItemPrivate::Auto )
00964         return d->m_hidden == KFileItemPrivate::Hidden;
00965 
00966     // Prefer the filename that is part of the URL, in case the display name is different.
00967     QString fileName = d->m_url.fileName();
00968     if (fileName.isEmpty()) // e.g. "trash:/"
00969         fileName = d->m_strName;
00970     return fileName.length() > 1 && fileName[0] == '.';  // Just "." is current directory, not hidden.
00971 }
00972 
00973 bool KFileItem::isDir() const
00974 {
00975     if (d->m_fileMode == KFileItem::Unknown) {
00976         // Probably the file was deleted already, and KDirLister hasn't told the world yet.
00977         //kDebug() << d << url() << "can't say -> false";
00978         return false; // can't say for sure, so no
00979     }
00980     return (S_ISDIR(d->m_fileMode));
00981 }
00982 
00983 bool KFileItem::isFile() const
00984 {
00985     return !isDir();
00986 }
00987 
00988 bool KFileItem::acceptsDrops() const
00989 {
00990     // A directory ?
00991     if ( S_ISDIR( mode() ) ) {
00992         return isWritable();
00993     }
00994 
00995     // But only local .desktop files and executables
00996     if ( !d->m_bIsLocalUrl )
00997         return false;
00998 
00999     if ( mimetype() == "application/x-desktop")
01000         return true;
01001 
01002     // Executable, shell script ... ?
01003     if ( QFileInfo(d->m_url.toLocalFile()).isExecutable() )
01004         return true;
01005 
01006     return false;
01007 }
01008 
01009 QString KFileItem::getStatusBarInfo() const
01010 {
01011     QString text = d->m_strText;
01012     const QString comment = mimeComment();
01013 
01014     if ( d->m_bLink )
01015     {
01016         text += ' ';
01017         if ( comment.isEmpty() )
01018             text += i18n ( "(Symbolic Link to %1)", linkDest() );
01019         else
01020             text += i18n("(%1, Link to %2)", comment, linkDest());
01021     }
01022     else if ( targetUrl() != url() )
01023     {
01024         text += i18n ( " (Points to %1)", targetUrl().pathOrUrl());
01025     }
01026     else if ( S_ISREG( d->m_fileMode ) )
01027     {
01028         text += QString(" (%1, %2)").arg( comment, KIO::convertSize( size() ) );
01029     }
01030     else
01031     {
01032         text += QString(" (%1)").arg( comment );
01033     }
01034     return text;
01035 }
01036 
01037 QString KFileItem::getToolTipText(int maxcount) const
01038 {
01039     // we can return QString() if no tool tip should be shown
01040     QString tip;
01041     KFileMetaInfo info = metaInfo();
01042 
01043     // the font tags are a workaround for the fact that the tool tip gets
01044     // screwed if the color scheme uses white as default text color
01045     const QString colorName = QApplication::palette().color(QPalette::ToolTipText).name();
01046     const QString start = "<tr><td align=\"right\"><nobr><font color=\"" + colorName + "\"><b>";
01047     const QString mid = "&nbsp;</b></font></nobr></td><td><nobr><font color=\"" + colorName + "\">";
01048     const char* end = "</font></nobr></td></tr>";
01049 
01050     tip = "<table cellspacing=0 cellpadding=0>";
01051 
01052     tip += start + i18n("Name:") + mid + text() + end;
01053     tip += start + i18n("Type:") + mid;
01054 
01055     QString type = Qt::escape(mimeComment());
01056     if ( d->m_bLink ) {
01057         tip += i18n("Link to %1 (%2)", linkDest(), type) + end;
01058     } else
01059         tip += type + end;
01060 
01061     if ( !S_ISDIR ( d->m_fileMode ) )
01062         tip += start + i18n("Size:") + mid +
01063                QString("%1").arg(KIO::convertSize(size())) +
01064                end;
01065 
01066     tip += start + i18n("Modified:") + mid +
01067            timeString( KFileItem::ModificationTime ) + end
01068 #ifndef Q_WS_WIN //TODO: show win32-specific permissions
01069            +start + i18n("Owner:") + mid + user() + " - " + group() + end +
01070            start + i18n("Permissions:") + mid +
01071            permissionsString() + end
01072 #endif
01073            ;
01074 
01075     if (info.isValid())
01076     {
01077         const QStringList keys = info.preferredKeys();
01078 
01079         // now the rest
01080         QStringList::ConstIterator it = keys.begin();
01081         for (int count = 0; count<maxcount && it!=keys.end() ; ++it)
01082         {
01083             if ( count == 0 )
01084             {
01085                 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>";
01086             }
01087 
01088             KFileMetaInfoItem item = info.item( *it );
01089             if ( item.isValid() )
01090             {
01091                 QString s = item.value().toString();
01092                 if ( ( item.properties().attributes() & PredicateProperties::SqueezeText )
01093                      && s.length() > 50) {
01094                     s.truncate(47);
01095                     s.append("...");
01096                 }
01097                 if ( !s.isEmpty() )
01098                 {
01099                     count++;
01100                     tip += start +
01101                            Qt::escape( item.name() ) + ':' +
01102                            mid +
01103                            Qt::escape( s ) +
01104                            end;
01105                 }
01106 
01107             }
01108         }
01109     }
01110     tip += "</table>";
01111 
01112     //kDebug() << "making this the tool tip rich text:\n";
01113     //kDebug() << tip;
01114 
01115     return tip;
01116 }
01117 
01118 void KFileItem::run( QWidget* parentWidget ) const
01119 {
01120     (void) new KRun( targetUrl(), parentWidget, d->m_fileMode, d->m_bIsLocalUrl );
01121 }
01122 
01123 bool KFileItem::cmp( const KFileItem & item ) const
01124 {
01125     return d->cmp(*item.d);
01126 }
01127 
01128 bool KFileItem::operator==(const KFileItem& other) const
01129 {
01130     // is this enough?
01131     return d == other.d;
01132 }
01133 
01134 bool KFileItem::operator!=(const KFileItem& other) const
01135 {
01136     return d != other.d;
01137 }
01138 
01139 void KFileItem::setUDSEntry( const KIO::UDSEntry& _entry, const KUrl& _url,
01140                              bool _delayedMimeTypes, bool _urlIsDirectory )
01141 {
01142     d->m_entry = _entry;
01143     d->m_url = _url;
01144     d->m_strName.clear();
01145     d->m_strText.clear();
01146     d->m_iconName.clear();
01147     d->m_strLowerCaseName.clear();
01148     d->m_pMimeType = 0;
01149     d->m_fileMode = KFileItem::Unknown;
01150     d->m_permissions = KFileItem::Unknown;
01151     d->m_bMarked = false;
01152     d->m_bLink = false;
01153     d->m_bIsLocalUrl = _url.isLocalFile();
01154     d->m_bMimeTypeKnown = false;
01155     d->m_hidden = KFileItemPrivate::Auto;
01156     d->m_guessedMimeType.clear();
01157     d->m_metaInfo = KFileMetaInfo();
01158     d->m_delayedMimeTypes = _delayedMimeTypes;
01159     d->m_useIconNameCache = false;
01160 
01161     d->readUDSEntry( _urlIsDirectory );
01162     d->init();
01163 }
01164 
01165 KFileItem::operator QVariant() const
01166 {
01167     return qVariantFromValue(*this);
01168 }
01169 
01170 void KFileItem::setExtraData( const void *key, void *value )
01171 {
01172     if ( !key )
01173         return;
01174 
01175     d->m_extra.insert( key, value ); // replaces the value of key if already there
01176 }
01177 
01178 const void * KFileItem::extraData( const void *key ) const
01179 {
01180     return d->m_extra.value( key, 0 );
01181 }
01182 
01183 void KFileItem::removeExtraData( const void *key )
01184 {
01185     d->m_extra.remove( key );
01186 }
01187 
01188 QString KFileItem::permissionsString() const
01189 {
01190     if (d->m_access.isNull() && d->m_permissions != KFileItem::Unknown)
01191         d->m_access = d->parsePermissions( d->m_permissions );
01192 
01193     return d->m_access;
01194 }
01195 
01196 // check if we need to cache this
01197 QString KFileItem::timeString( FileTimes which ) const
01198 {
01199     return KGlobal::locale()->formatDateTime( d->time(which) );
01200 }
01201 
01202 QString KFileItem::timeString( unsigned int which ) const
01203 {
01204     switch (which) {
01205     case KIO::UDSEntry::UDS_ACCESS_TIME:
01206         return timeString(AccessTime);
01207     case KIO::UDSEntry::UDS_CREATION_TIME:
01208         return timeString(CreationTime);
01209     case KIO::UDSEntry::UDS_MODIFICATION_TIME:
01210     default:
01211         return timeString(ModificationTime);
01212     }
01213 }
01214 
01215 void KFileItem::setMetaInfo( const KFileMetaInfo & info ) const
01216 {
01217     d->m_metaInfo = info;
01218 }
01219 
01220 KFileMetaInfo KFileItem::metaInfo(bool autoget, int) const
01221 {
01222     if ((isRegularFile() || isDir()) && autoget && !d->m_metaInfo.isValid())
01223     {
01224         bool isLocalUrl;
01225         KUrl url(mostLocalUrl(isLocalUrl));
01226         d->m_metaInfo = KFileMetaInfo(url);//, mimetype() );
01227     }
01228     return d->m_metaInfo;
01229 }
01230 
01231 void KFileItem::assign( const KFileItem & item )
01232 {
01233     *this = item;
01234 }
01235 
01236 KUrl KFileItem::mostLocalUrl(bool &local) const
01237 {
01238     QString local_path = localPath();
01239 
01240     if ( !local_path.isEmpty() )
01241     {
01242         local = true;
01243         KUrl url;
01244         url.setPath(local_path);
01245         return url;
01246     }
01247     else
01248     {
01249         local = d->m_bIsLocalUrl;
01250         return d->m_url;
01251     }
01252 }
01253 
01254 QDataStream & operator<< ( QDataStream & s, const KFileItem & a )
01255 {
01256     // We don't need to save/restore anything that refresh() invalidates,
01257     // since that means we can re-determine those by ourselves.
01258     s << a.d->m_url;
01259     s << a.d->m_strName;
01260     s << a.d->m_strText;
01261     return s;
01262 }
01263 
01264 QDataStream & operator>> ( QDataStream & s, KFileItem & a )
01265 {
01266     s >> a.d->m_url;
01267     s >> a.d->m_strName;
01268     s >> a.d->m_strText;
01269     a.d->m_bIsLocalUrl = a.d->m_url.isLocalFile();
01270     a.d->m_bMimeTypeKnown = false;
01271     a.refresh();
01272     return s;
01273 }
01274 
01275 KUrl KFileItem::url() const
01276 {
01277     return d->m_url;
01278 }
01279 
01280 mode_t KFileItem::permissions() const
01281 {
01282     return d->m_permissions;
01283 }
01284 
01285 mode_t KFileItem::mode() const
01286 {
01287     return d->m_fileMode;
01288 }
01289 
01290 bool KFileItem::isLink() const
01291 {
01292     return d->m_bLink;
01293 }
01294 
01295 bool KFileItem::isLocalFile() const
01296 {
01297     return d->m_bIsLocalUrl;
01298 }
01299 
01300 QString KFileItem::text() const
01301 {
01302     return d->m_strText;
01303 }
01304 
01305 QString KFileItem::name( bool lowerCase ) const
01306 {
01307     if ( !lowerCase )
01308         return d->m_strName;
01309     else
01310         if ( d->m_strLowerCaseName.isNull() )
01311             d->m_strLowerCaseName = d->m_strName.toLower();
01312     return d->m_strLowerCaseName;
01313 }
01314 
01315 KUrl KFileItem::targetUrl() const
01316 {
01317     const QString targetUrlStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_TARGET_URL );
01318     if (!targetUrlStr.isEmpty())
01319       return KUrl(targetUrlStr);
01320     else
01321       return url();
01322 }
01323 
01324 KUrl KFileItem::nepomukUri() const
01325 {
01326     if(isLocalFile()) {
01327         return url();
01328     }
01329     else {
01330         const QString nepomukUriStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_NEPOMUK_URI );
01331         return KUrl(nepomukUriStr);
01332     }
01333 }
01334 
01335 /*
01336  * Mimetype handling.
01337  *
01338  * Initial state: m_pMimeType = 0.
01339  * When mimeTypePtr() is called first: fast mimetype determination,
01340  *   might either find an accurate mimetype (-> Final state), otherwise we
01341  *   set m_pMimeType but not m_bMimeTypeKnown (-> Intermediate state)
01342  * Intermediate state: determineMimeType() does the real determination -> Final state.
01343  *
01344  * If delayedMimeTypes isn't set, then we always go to the Final state directly.
01345  */
01346 
01347 KMimeType::Ptr KFileItem::mimeTypePtr() const
01348 {
01349     if (!d->m_pMimeType) {
01350         // On-demand fast (but not always accurate) mimetype determination
01351         Q_ASSERT(!d->m_url.isEmpty());
01352         bool isLocalUrl;
01353         KUrl url = mostLocalUrl(isLocalUrl);
01354         int accuracy;
01355         d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl,
01356                                                // use fast mode if delayed mimetype determination can refine it later
01357                                                d->m_delayedMimeTypes, &accuracy );
01358         // If we used the "fast mode" (no sniffing), and we didn't get a perfect (extension-based) match,
01359         // then determineMimeType will be able to do better.
01360         const bool canDoBetter = d->m_delayedMimeTypes && accuracy < 100;
01361         //kDebug() << "finding mimetype for" << url << ":" << d->m_pMimeType->name() << "canDoBetter=" << canDoBetter;
01362         d->m_bMimeTypeKnown = !canDoBetter;
01363     }
01364     return d->m_pMimeType;
01365 }
01366 
01367 KIO::UDSEntry KFileItem::entry() const
01368 {
01369     return d->m_entry;
01370 }
01371 
01372 bool KFileItem::isMarked() const
01373 {
01374     return d->m_bMarked;
01375 }
01376 
01377 void KFileItem::mark()
01378 {
01379     d->m_bMarked = true;
01380 }
01381 
01382 void KFileItem::unmark()
01383 {
01384     d->m_bMarked = false;
01385 }
01386 
01387 KFileItem& KFileItem::operator=(const KFileItem& other)
01388 {
01389     d = other.d;
01390     return *this;
01391 }
01392 
01393 bool KFileItem::isNull() const
01394 {
01395     return d == 0;
01396 }
01397 
01398 KFileItemList::KFileItemList()
01399 {
01400 }
01401 
01402 KFileItemList::KFileItemList( const QList<KFileItem> &items )
01403   : QList<KFileItem>( items )
01404 {
01405 }
01406 
01407 KFileItem KFileItemList::findByName( const QString& fileName ) const
01408 {
01409     const_iterator it = begin();
01410     const const_iterator itend = end();
01411     for ( ; it != itend ; ++it ) {
01412         if ( (*it).name() == fileName ) {
01413             return *it;
01414         }
01415     }
01416     return KFileItem();
01417 }
01418 
01419 KFileItem KFileItemList::findByUrl( const KUrl& url ) const {
01420     const_iterator it = begin();
01421     const const_iterator itend = end();
01422     for ( ; it != itend ; ++it ) {
01423         if ( (*it).url() == url ) {
01424             return *it;
01425         }
01426     }
01427     return KFileItem();
01428 }
01429 
01430 KUrl::List KFileItemList::urlList() const {
01431     KUrl::List lst;
01432     const_iterator it = begin();
01433     const const_iterator itend = end();
01434     for ( ; it != itend ; ++it ) {
01435         lst.append( (*it).url() );
01436     }
01437     return lst;
01438 }
01439 
01440 KUrl::List KFileItemList::targetUrlList() const {
01441     KUrl::List lst;
01442     const_iterator it = begin();
01443     const const_iterator itend = end();
01444     for ( ; it != itend ; ++it ) {
01445         lst.append( (*it).targetUrl() );
01446     }
01447     return lst;
01448 }
01449 
01450 bool KFileItem::isDesktopFile() const
01451 {
01452     // only local files
01453     bool isLocal;
01454     const KUrl url = mostLocalUrl(isLocal);
01455     if (!isLocal)
01456         return false;
01457 
01458     // only regular files
01459     if (!S_ISREG(d->m_fileMode))
01460         return false;
01461 
01462     // only if readable
01463     if (!isReadable())
01464         return false;
01465 
01466     // return true if desktop file
01467     return determineMimeType()->is("application/x-desktop");
01468 }
01469 
01470 bool KFileItem::isRegularFile() const
01471 {
01472     return S_ISREG(d->m_fileMode);
01473 }
01474 
01475 QDebug operator<<(QDebug stream, const KFileItem& item)
01476 {
01477     if (item.isNull()) {
01478         stream << "[null KFileItem]";
01479     } else {
01480         stream << "[KFileItem for" << item.url() << "]";
01481     }
01482     return stream;
01483 }

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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  •     Sodep
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.9-20090814
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