• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.9.5 API Reference
  • KDE Home
  • Contact Us
 

KIO

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

KDE's Doxygen guidelines are available online.

KIO

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

kdelibs-4.9.5 API Reference

Skip menu "kdelibs-4.9.5 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

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