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

KDE's Doxygen guidelines are available online.

KIO

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

kdelibs-4.8.3 API Reference

Skip menu "kdelibs-4.8.3 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • 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
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal