• Skip to content
  • Skip to link menu
KDE 4.6 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 <QTextDocument>
00041 
00042 #include <kdebug.h>
00043 #include <kfilemetainfo.h>
00044 #include <kglobal.h>
00045 #include <kglobalsettings.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 QString KFileItem::getToolTipText(int maxcount) const
01073 {
01074     // we can return QString() if no tool tip should be shown
01075     QString tip;
01076     KFileMetaInfo info = metaInfo();
01077 
01078     // the font tags are a workaround for the fact that the tool tip gets
01079     // screwed if the color scheme uses white as default text color
01080     const QString colorName = QApplication::palette().color(QPalette::ToolTipText).name();
01081     const QString start = "<tr><td align=\"right\"><nobr><font color=\"" + colorName + "\"><b>";
01082     const QString mid = "&nbsp;</b></font></nobr></td><td><nobr><font color=\"" + colorName + "\">";
01083     const char* end = "</font></nobr></td></tr>";
01084 
01085     tip = "<table cellspacing=0 cellpadding=0>";
01086 
01087     tip += start + i18n("Name:") + mid + text() + end;
01088     tip += start + i18n("Type:") + mid;
01089 
01090     QString type = Qt::escape(mimeComment());
01091     if ( d->m_bLink ) {
01092         tip += i18n("Link to %1 (%2)", linkDest(), type) + end;
01093     } else
01094         tip += type + end;
01095 
01096     if ( !S_ISDIR ( d->m_fileMode ) )
01097         tip += start + i18n("Size:") + mid +
01098                QString("%1").arg(KIO::convertSize(size())) +
01099                end;
01100 
01101     tip += start + i18n("Modified:") + mid +
01102            timeString( KFileItem::ModificationTime ) + end
01103 #ifndef Q_WS_WIN //TODO: show win32-specific permissions
01104            +start + i18n("Owner:") + mid + user() + " - " + group() + end +
01105            start + i18n("Permissions:") + mid +
01106            permissionsString() + end
01107 #endif
01108            ;
01109 
01110     if (info.isValid())
01111     {
01112         const QStringList keys = info.preferredKeys();
01113 
01114         // now the rest
01115         QStringList::ConstIterator it = keys.begin();
01116         for (int count = 0; count<maxcount && it!=keys.end() ; ++it)
01117         {
01118             if ( count == 0 )
01119             {
01120                 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>";
01121             }
01122 
01123             KFileMetaInfoItem item = info.item( *it );
01124             if ( item.isValid() )
01125             {
01126                 QString s = item.value().toString();
01127                 if ( !s.isEmpty() )
01128                 {
01129                     count++;
01130                     tip += start +
01131                            Qt::escape( item.name() ) + ':' +
01132                            mid +
01133                            Qt::escape( s ) +
01134                            end;
01135                 }
01136 
01137             }
01138         }
01139     }
01140     tip += "</table>";
01141 
01142     //kDebug() << "making this the tool tip rich text:\n";
01143     //kDebug() << tip;
01144 
01145     return tip;
01146 }
01147 
01148 void KFileItem::run( QWidget* parentWidget ) const
01149 {
01150     (void) new KRun( targetUrl(), parentWidget, d->m_fileMode, d->m_bIsLocalUrl );
01151 }
01152 
01153 bool KFileItem::cmp( const KFileItem & item ) const
01154 {
01155     return d->cmp(*item.d);
01156 }
01157 
01158 bool KFileItem::operator==(const KFileItem& other) const
01159 {
01160     // is this enough?
01161     return d == other.d;
01162 }
01163 
01164 bool KFileItem::operator!=(const KFileItem& other) const
01165 {
01166     return d != other.d;
01167 }
01168 
01169 #ifndef KDE_NO_DEPRECATED
01170 void KFileItem::setUDSEntry( const KIO::UDSEntry& _entry, const KUrl& _url,
01171                              bool _delayedMimeTypes, bool _urlIsDirectory )
01172 {
01173     d->m_entry = _entry;
01174     d->m_url = _url;
01175     d->m_strName.clear();
01176     d->m_strText.clear();
01177     d->m_iconName.clear();
01178     d->m_strLowerCaseName.clear();
01179     d->m_pMimeType = 0;
01180     d->m_fileMode = KFileItem::Unknown;
01181     d->m_permissions = KFileItem::Unknown;
01182     d->m_bMarked = false;
01183     d->m_bLink = false;
01184     d->m_bIsLocalUrl = _url.isLocalFile();
01185     d->m_bMimeTypeKnown = false;
01186     d->m_hidden = KFileItemPrivate::Auto;
01187     d->m_guessedMimeType.clear();
01188     d->m_metaInfo = KFileMetaInfo();
01189     d->m_delayedMimeTypes = _delayedMimeTypes;
01190     d->m_useIconNameCache = false;
01191 
01192     d->readUDSEntry( _urlIsDirectory );
01193     d->init();
01194 }
01195 #endif
01196 
01197 KFileItem::operator QVariant() const
01198 {
01199     return qVariantFromValue(*this);
01200 }
01201 
01202 #ifndef KDE_NO_DEPRECATED
01203 void KFileItem::setExtraData( const void *key, void *value )
01204 {
01205     if ( !key )
01206         return;
01207 
01208     d->m_extra.insert( key, value ); // replaces the value of key if already there
01209 }
01210 #endif
01211 
01212 #ifndef KDE_NO_DEPRECATED
01213 const void * KFileItem::extraData( const void *key ) const
01214 {
01215     return d->m_extra.value( key, 0 );
01216 }
01217 #endif
01218 
01219 #ifndef KDE_NO_DEPRECATED
01220 void KFileItem::removeExtraData( const void *key )
01221 {
01222     d->m_extra.remove( key );
01223 }
01224 #endif
01225 
01226 QString KFileItem::permissionsString() const
01227 {
01228     if (d->m_access.isNull() && d->m_permissions != KFileItem::Unknown)
01229         d->m_access = d->parsePermissions( d->m_permissions );
01230 
01231     return d->m_access;
01232 }
01233 
01234 // check if we need to cache this
01235 QString KFileItem::timeString( FileTimes which ) const
01236 {
01237     return KGlobal::locale()->formatDateTime( d->time(which) );
01238 }
01239 
01240 #ifndef KDE_NO_DEPRECATED
01241 QString KFileItem::timeString( unsigned int which ) const
01242 {
01243     switch (which) {
01244     case KIO::UDSEntry::UDS_ACCESS_TIME:
01245         return timeString(AccessTime);
01246     case KIO::UDSEntry::UDS_CREATION_TIME:
01247         return timeString(CreationTime);
01248     case KIO::UDSEntry::UDS_MODIFICATION_TIME:
01249     default:
01250         return timeString(ModificationTime);
01251     }
01252 }
01253 #endif
01254 
01255 void KFileItem::setMetaInfo( const KFileMetaInfo & info ) const
01256 {
01257     d->m_metaInfo = info;
01258 }
01259 
01260 KFileMetaInfo KFileItem::metaInfo(bool autoget, int what) const
01261 {
01262     if ((isRegularFile() || isDir()) && autoget && !d->m_metaInfo.isValid())
01263     {
01264         bool isLocalUrl;
01265         KUrl url(mostLocalUrl(isLocalUrl));
01266         d->m_metaInfo = KFileMetaInfo(url.toLocalFile(), mimetype(), (KFileMetaInfo::What)what);
01267     }
01268     return d->m_metaInfo;
01269 }
01270 
01271 #ifndef KDE_NO_DEPRECATED
01272 void KFileItem::assign( const KFileItem & item )
01273 {
01274     *this = item;
01275 }
01276 #endif
01277 
01278 KUrl KFileItem::mostLocalUrl(bool &local) const
01279 {
01280     QString local_path = localPath();
01281 
01282     if ( !local_path.isEmpty() )
01283     {
01284         local = true;
01285         KUrl url;
01286         url.setPath(local_path);
01287         return url;
01288     }
01289     else
01290     {
01291         local = d->m_bIsLocalUrl;
01292         return d->m_url;
01293     }
01294 }
01295 
01296 KUrl KFileItem::mostLocalUrl() const
01297 {
01298     bool local = false;
01299     return mostLocalUrl(local);
01300 }
01301 
01302 QDataStream & operator<< ( QDataStream & s, const KFileItem & a )
01303 {
01304     // We don't need to save/restore anything that refresh() invalidates,
01305     // since that means we can re-determine those by ourselves.
01306     s << a.d->m_url;
01307     s << a.d->m_strName;
01308     s << a.d->m_strText;
01309     return s;
01310 }
01311 
01312 QDataStream & operator>> ( QDataStream & s, KFileItem & a )
01313 {
01314     s >> a.d->m_url;
01315     s >> a.d->m_strName;
01316     s >> a.d->m_strText;
01317     a.d->m_bIsLocalUrl = a.d->m_url.isLocalFile();
01318     a.d->m_bMimeTypeKnown = false;
01319     a.refresh();
01320     return s;
01321 }
01322 
01323 KUrl KFileItem::url() const
01324 {
01325     return d->m_url;
01326 }
01327 
01328 mode_t KFileItem::permissions() const
01329 {
01330     return d->m_permissions;
01331 }
01332 
01333 mode_t KFileItem::mode() const
01334 {
01335     return d->m_fileMode;
01336 }
01337 
01338 bool KFileItem::isLink() const
01339 {
01340     return d->m_bLink;
01341 }
01342 
01343 bool KFileItem::isLocalFile() const
01344 {
01345     return d->m_bIsLocalUrl;
01346 }
01347 
01348 QString KFileItem::text() const
01349 {
01350     return d->m_strText;
01351 }
01352 
01353 QString KFileItem::name( bool lowerCase ) const
01354 {
01355     if ( !lowerCase )
01356         return d->m_strName;
01357     else
01358         if ( d->m_strLowerCaseName.isNull() )
01359             d->m_strLowerCaseName = d->m_strName.toLower();
01360     return d->m_strLowerCaseName;
01361 }
01362 
01363 KUrl KFileItem::targetUrl() const
01364 {
01365     const QString targetUrlStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_TARGET_URL );
01366     if (!targetUrlStr.isEmpty())
01367       return KUrl(targetUrlStr);
01368     else
01369       return url();
01370 }
01371 
01372 KUrl KFileItem::nepomukUri() const
01373 {
01374 #ifndef KIO_NO_NEPOMUK
01375     const QString nepomukUriStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_NEPOMUK_URI );
01376     if(!nepomukUriStr.isEmpty()) {
01377         return KUrl(nepomukUriStr);
01378     }
01379     else if(targetUrl().isLocalFile()) {
01380         return targetUrl();
01381     }
01382     else {
01383         return KUrl();
01384     }
01385 #else
01386     return KUrl();
01387 #endif
01388 }
01389 
01390 /*
01391  * Mimetype handling.
01392  *
01393  * Initial state: m_pMimeType = 0.
01394  * When mimeTypePtr() is called first: fast mimetype determination,
01395  *   might either find an accurate mimetype (-> Final state), otherwise we
01396  *   set m_pMimeType but not m_bMimeTypeKnown (-> Intermediate state)
01397  * Intermediate state: determineMimeType() does the real determination -> Final state.
01398  *
01399  * If delayedMimeTypes isn't set, then we always go to the Final state directly.
01400  */
01401 
01402 KMimeType::Ptr KFileItem::mimeTypePtr() const
01403 {
01404     if (!d->m_pMimeType) {
01405         // On-demand fast (but not always accurate) mimetype determination
01406         Q_ASSERT(!d->m_url.isEmpty());
01407         bool isLocalUrl;
01408         KUrl url = mostLocalUrl(isLocalUrl);
01409         int accuracy;
01410         d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl,
01411                                                // use fast mode if delayed mimetype determination can refine it later
01412                                                d->m_delayedMimeTypes, &accuracy );
01413         // If we used the "fast mode" (no sniffing), and we didn't get a perfect (extension-based) match,
01414         // then determineMimeType will be able to do better.
01415         const bool canDoBetter = d->m_delayedMimeTypes && accuracy < 100;
01416         //kDebug() << "finding mimetype for" << url << ":" << d->m_pMimeType->name() << "canDoBetter=" << canDoBetter;
01417         d->m_bMimeTypeKnown = !canDoBetter;
01418     }
01419     return d->m_pMimeType;
01420 }
01421 
01422 KIO::UDSEntry KFileItem::entry() const
01423 {
01424     return d->m_entry;
01425 }
01426 
01427 bool KFileItem::isMarked() const
01428 {
01429     return d->m_bMarked;
01430 }
01431 
01432 void KFileItem::mark()
01433 {
01434     d->m_bMarked = true;
01435 }
01436 
01437 void KFileItem::unmark()
01438 {
01439     d->m_bMarked = false;
01440 }
01441 
01442 KFileItem& KFileItem::operator=(const KFileItem& other)
01443 {
01444     d = other.d;
01445     return *this;
01446 }
01447 
01448 bool KFileItem::isNull() const
01449 {
01450     return d == 0;
01451 }
01452 
01453 KFileItemList::KFileItemList()
01454 {
01455 }
01456 
01457 KFileItemList::KFileItemList( const QList<KFileItem> &items )
01458   : QList<KFileItem>( items )
01459 {
01460 }
01461 
01462 KFileItem KFileItemList::findByName( const QString& fileName ) const
01463 {
01464     const_iterator it = begin();
01465     const const_iterator itend = end();
01466     for ( ; it != itend ; ++it ) {
01467         if ( (*it).name() == fileName ) {
01468             return *it;
01469         }
01470     }
01471     return KFileItem();
01472 }
01473 
01474 KFileItem KFileItemList::findByUrl( const KUrl& url ) const {
01475     const_iterator it = begin();
01476     const const_iterator itend = end();
01477     for ( ; it != itend ; ++it ) {
01478         if ( (*it).url() == url ) {
01479             return *it;
01480         }
01481     }
01482     return KFileItem();
01483 }
01484 
01485 KUrl::List KFileItemList::urlList() const {
01486     KUrl::List lst;
01487     const_iterator it = begin();
01488     const const_iterator itend = end();
01489     for ( ; it != itend ; ++it ) {
01490         lst.append( (*it).url() );
01491     }
01492     return lst;
01493 }
01494 
01495 KUrl::List KFileItemList::targetUrlList() const {
01496     KUrl::List lst;
01497     const_iterator it = begin();
01498     const const_iterator itend = end();
01499     for ( ; it != itend ; ++it ) {
01500         lst.append( (*it).targetUrl() );
01501     }
01502     return lst;
01503 }
01504 
01505 
01506 bool KFileItem::isDesktopFile() const
01507 {
01508     return checkDesktopFile(*this, true);
01509 }
01510 
01511 bool KFileItem::isRegularFile() const
01512 {
01513     return S_ISREG(d->m_fileMode);
01514 }
01515 
01516 QDebug operator<<(QDebug stream, const KFileItem& item)
01517 {
01518     if (item.isNull()) {
01519         stream << "[null KFileItem]";
01520     } else {
01521         stream << "[KFileItem for" << item.url() << "]";
01522     }
01523     return stream;
01524 }

KIO

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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