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

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

Skip menu "kdelibs"
  • 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
Generated for kdelibs by doxygen 1.7.5
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